1.前言 
本次主要想实现的就是一个uart在imx6ull和单片间通信的功能,linux是非实时的系统,假如有那么一个场景需要实时的去控制一些设备,或者本身的MPU芯片资源不够用需要去扩展外设,那么此时可以考虑外挂一个芯片进行扩展,在mpu层只需要上传一下必要的信息进行数据交互或者mpu下发一些控制信息就可以了。当前这种情况已经用的很成熟了,很多公司内部也有自己的通信协议。本次就实现mpu和单片机间进行串口通信。 2.uart通信 
串口通信这里不在说明了,都太熟悉了,这里记录说明Imx6ull怎么实现串口通信,以及和单片机间通信,通过开发板将数据发送到单片机,这里选择的是AC78406YGLA核心板,单片机接收到数据后通过串口打印出到上位机,MPU开发板一直发送elfboard。 本次选择串口2和单片机通信,MPU板子将串口发送接到单片的接收,首先先确定单片机能够将接收到的数据发送出来,将单片机开发板和串口连接,使用电脑上位机先测试一下。如下所示,代码已经提前调好了,PC8对应uart tx PC9对应uart rx: 
 
单片机开发串口测试效果如下: 
 
以下为linux 板的I/O引脚出图,硬连接只需要将Uart2TX连接到单片机的PC9,单片3的PC8连接到USB转串口的RX:  
 连接如下所示: 3.代码设计 
单片机串口配置 串口中断收发配置:  
Linux开发板串程序,使用的是开发板提供的程序,发送函数: 
 
主函数: - int main(int argc, char *argv[])
 
 - {
 
 -     int result = 0;
 
  
-     //检测是否有参数
 
 -     if (argc < 2 || strncmp(argv[1], "tty", 3))
 
 -     {
 
 -         print_usage(argv[0]);
 
 -         exit(1);
 
 -     }
 
  
-     //检测是否有--h或--help
 
 -     if ((!strcmp(argv[1], "--h")) || (!strcmp(argv[1], "--help")))
 
 -     {
 
 -         print_usage(argv[0]);
 
 -         exit(1);
 
 -     }
 
  
-     strcpy(dev, "/dev/");
 
 -     strcat(dev, argv[1]);
 
  
-     //从main函数带来的参数解析为串口参数
 
 -     get_param(argc, argv, &tty_param);
 
  
-     //当知道设备名称时可以直接赋值dev,例strcpy(dev, "/dev/ttymxc1");
 
 -     //打开串口 设置可读写,不被输入影响,不等待外设响应
 
 -     fd = open(dev, O_RDWR | O_NOCTTY | O_NDELAY);
 
 -     if (fd < 0)
 
 -     {
 
 -         perror(dev);
 
 -         printf("Can't Open Serial Port %s \n", dev);
 
 -         exit(0);
 
 -     }
 
 -     else
 
 -     {
 
 -         printf("baudrate=%ld,data_bit=%d,stop_bit=%d,check='%c'\n", tty_param.baudrate, tty_param.data_bit, tty_param.stop_bit, tty_param.check);
 
 -         //设置串口参数
 
 -         if ((result = func_set_opt(fd, tty_param.baudrate, tty_param.data_bit, tty_param.stop_bit, tty_param.check, tty_param.hardware)) < 0)
 
 -         {
 
 -             perror("set_opt error");
 
 -             exit(0);
 
 -         }
 
 -         //设置串口为阻塞方式
 
 -         /*if(fcntl(fd, F_SETFL, 0)<0)
 
 -         {
 
 -             printf("fcntl failed!\n");
 
 -         }
 
 -         else
 
 -         {
 
 -             printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));
 
 -         }*/
 
 -         //设置串口为非阻塞方式
 
 -         /*if(fcntl(fd, F_SETFL, FNDELAY)<0)
 
 -         {
 
 -             printf("fcntl failed!\n");
 
 -         }
 
 -         else
 
 -         {
 
 -             printf("fcntl=%d\n",fcntl(fd, F_SETFL,FNDELAY));
 
 -         }*/
 
 -     }
 
  
-     while (1)
 
 -     {
 
 -         receive_num = func_receive_frame(fd, receive_buff, sizeof(receive_buff)); /*读取串口收到的数据*/
 
 -         if (receive_num > 0)
 
 -         {
 
 -             printf("[nread=%d] ", receive_num);
 
 -             func_my_print(receive_buff, receive_num, 'c'); /*打印接收到的数据*/
 
 -         }
 
 -         //组织发送数据
 
 -         if ((1 == loopback_send_mode) && (receive_num > 0)) //数据回环处理
 
 -         {
 
 -             send_num = receive_num;
 
 -             memcpy(send_buff, receive_buff, receive_num);
 
 -         }
 
 -         else if (1 == active_send_mode)
 
 -         {
 
 -             if (active_send_time_count >= active_send_time)
 
 -             {
 
 -                 active_send_time_count = 0;
 
 -                 send_num = active_send_num;
 
 -                 memcpy(send_buff, active_send_buff, active_send_num);
 
 -             }
 
 -             else
 
 -             {
 
 -                 active_send_time_count++;
 
 -             }
 
 -         }
 
 -         //数据发送
 
 -         if (send_num > 0)
 
 -         {
 
 -             real_send_num = func_send_frame(fd, send_buff, send_num);
 
 -             if (real_send_num > 0)
 
 -             {
 
 -                 printf("[nwrite=%d] ", real_send_num); /*打印发送的数据*/
 
 -                 func_my_print(send_buff, real_send_num, 'c');
 
 -             }
 
 -             memset(send_buff, 0, send_num);
 
 -             send_num = 0;
 
 -         }
 
 -         usleep(1000);
 
 -     }
 
 -     exit(0);
 
 - }
 
 
  复制代码编译生产可执行文件:  
拖入开发板,添加可执行权限,设置串口相关参数:  
通过逻辑分析仪观察串口发送的数据: 结果:  
 
 
 |