linux 串口调试方法

作者:syhdjf 发布于:2015-4-8 16:41

最近项目上用到linux下的串口,与下级模块的通信出了些问题,所以写了个小程序想要测试下串口,物理连接是PC端串口调试助手通过usb转串口线接到板子的uart,最终的效果是,板子的uart能发不能收,发出去的数据在PC端可以接收到,PC端串口调试助手发送到板子uart的信息,uart不能接收,read函数一直返回-1.

所以想请教下各位有没有什么好的方法测试一下linux的串口?

下边是我写的一个简单的测试程序:(不知道是不是有什么问题)

#include <stdio.h>
#include     <stdlib.h>     /*标准函数库定义*/
#include     <unistd.h>     /*Unix标准函数定义*/
#include     <sys/types.h>  /**/
#include     <sys/stat.h>   /**/
#include     <fcntl.h>      /*文件控制定义*/
#include     <termios.h>    /*PPSIX终端控制定义*/
#include     <errno.h>      /*错误号定义*/

int fd = -1;


int open_port(char port[])
{
 fd = open( port, O_RDWR  ); //djf  delete the value  |O_NONBLOCK

 if (fd<0) {
     printf("open serialport failed!\n");
     return -1;
 }

 struct termios tio;

 tcgetattr(fd, &tio);
 //bzero(&tio, sizeof(tio));
 // these must be set first, don't know why
 tio.c_cflag |= CLOCAL;
 tio.c_cflag |= CREAD;
 tio.c_cflag &= ~CSIZE;
 // baud rate 115200
 if (cfsetispeed(&tio, B115200) != 0)    {
     printf("cfsetispeed failed\n");
     return -1;
 }
 if (cfsetospeed(&tio, B115200) != 0)
 {
     printf("cfsetospeed failed\n");
     return -1;
 }
 // parity NONE
 tio.c_cflag &= ~PARENB;
 tio.c_iflag &= ~INPCK;
 tio.c_iflag |= IGNBRK;
 // data bit 8
 tio.c_cflag |= CS8;
 // stop bit 1
 tio.c_cflag &= ~CSTOPB;
 // others
 tio.c_cc[VTIME] = 0;
 tio.c_cc[VMIN]  = 0;
 // flush settings
 if(tcflush(fd, TCIOFLUSH) != 0) //djf chage TCIFLUSH  to TCIOFLUSH 20150408
 {
     printf("open serialport: Flushing %s ERROR!\n\n", port);
     return -1;
 }

 if(tcsetattr(fd, TCSANOW, &tio) != 0)
 {
     printf("open serialport: Setting %s ERROR!\n\n", port);
     return -1;
 }
 return 0;
}


int main(int argc, char* argv[])
{
 char port_num[10] = {0,0,0,0,0,0,0,0,0,0};
 char wr_num[2] = {1,2};
 int ret;

 if(argc != 2)
 {
  printf("%s SerialPortDevFile\n", argv[0]);
  return -1;
 }
 if(open_port(argv[1]) != 0)
 {
  printf("Fail to open %s!\n", argv[1]);
  return -2;
 }
 else
 {
  while(1)
  {
   printf( "start read %s\n", argv[1] );
   ret = read( fd, (void *)port_num, 9 );
   if( ret == -1 )
   printf( "ret = -1\n" );
   else
   {
    printf("ret = %d\n", ret);
    printf( "%s received : %s\n", argv[1], port_num );
   }
   printf( "start write %s\n", argv[1] );
   ret = write( fd, (void *)wr_num, 2 );
   sleep(5);
  }

  close_com();

  return 0;
 }
}

 

做驱动有个感觉,好多东西都是功能实现了,但是自己却还是一知半解,要学的很多。以后争取多搞点核心的东西,向各位看齐!

标签: Linux uart

评论:

ddd
2015-07-23 12:08
如果保证硬件没有问题的情况下,一般都是配置串口的问题,特别设置注意回车的问题,终端和串口助手是有区别的
linuxer
2015-04-10 05:08
我觉得基本的方法是把接收路径细分:
1、硬件信号
2、串口驱动
3、uart core layer
4、tty layer
5、application layer
由于3和4是内核机制,应该不会有问题,建议可以先用示波器量一下信号看看是否对端正确的发送了你想要的信号,然后检查你自己的驱动是否正确产生了中断,FIFO中是否正确的收到了数据,并向上递交该数据。最后再看用户空间的那个测试程序

PS:read返回-1,你的代码至少要打印出errnor的信息才好调试吧
syhdjf
2015-04-12 00:16
@linuxer:感谢linuxer的回复,逐层确定了下,最后还是把问题确定在应用程序,第一次接触串口应用程序,所以一些基本问题不是很明白,折腾了好几天。
最后的问题是由于没有关掉串口的回显功能,接着又出现数据接收不全的问题,确定问题所在地方就好解决了,通过接收数据分析,发现是有些字符被当成特殊的功能指令了。
问题已经暂时解决,数据能正常全部接收了。
最后还是要感谢linuxer帮忙分析问题,非常感谢。

发表评论:

Copyright @ 2013-2015 蜗窝科技 All rights reserved. Powered by emlog