Linux下C语言串口编程(有了解MINICOM原理的吗?)

时间:2021-11-11 21:29:52
遇到了个很难解决的小问题,特来次求教,谢谢各位了,我遇到的情况如下:

我的电脑通过串口连接到一个嵌入式的目标机上了,目标机的标准输入输出是串口(类似通过串口配置交换机的界面),我想通过读串口数据将串口的输出数据都在主机显示出来,目前遇到一个小问题就是我总是输出不了最后一行数据(“MPC8610HPCD login:"),但是我需要读到这一行里的“login“来做判断跟串口进行交互,最后一行数据是个登录输入用户名的提示行,我所看到最后一行和其他行的区别就是它没有换行,需要直接在“MPC8610HPCD login:"后输入用户名回车再输入密码之类的,但是minicom可以完全正常显示,显示区别如下:

最后几行
minicom:
   EXT2-fs error (device sda3): ext2_free_blocks: bit already cleared for block 143
                                                                                
   Debian GNU/Linux 3.1 MPC8610HPCD ttyS0                                          
                                                                                
   MPC8610HPCD login: 
我的代码只能输出:
   EXT2-fs error (device sda3): ext2_free_blocks: bit already cleared for block 143
                                                                                
   Debian GNU/Linux 3.1 MPC8610HPCD ttyS0


看了一下午minicom源码,貌似在参数配置上跟minicom几乎找不到区别,但是还是没看懂输出的方式!还有什么VT100也不太明白

    char *dev  = "/dev/ttyS0";                         //串口配置部分
    int fd = OpenDev(dev);
    fcntl(fd, F_SETFL, FNDELAY);
    
    struct termios  options;
    
    tcgetattr(fd, &options); 
    cfsetispeed(&options,B115200);
    cfsetospeed(&options,B115200);
    
    options.c_cflag|=(CLOCAL|CREAD);
    options.c_cflag &= ~PARENB; 
    options.c_cflag &= ~CSTOPB; 
    options.c_cflag &= ~CSIZE; 
    options.c_cflag |= CS8;
    
    options.c_cflag &= ~CRTSCTS;
    options.c_iflag &=~(IXON | IXOFF | IXANY);
    
    options.c_iflag |= INPCK;
    
    options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  
    options.c_oflag  &= ~OPOST;   
    
    options.c_cc[VTIME] = 150; 
    options.c_cc[VMIN] = 0;
    
    tcsetattr(fd,TCSANOW,&options);
    tcflush(fd,TCIOFLUSH);



while (1)                      //main里是这么调getData的
    {
        getData(fd,result,&cur);
    }

int getData(int fd, char* result, int* cur)     //这个是读串口的函数
{

    int nread,i;
    char buff[1024];
    nread = read(fd, buff, 1024);
    //printf("\ncomecomecome : %d\n",nread);
    if (nread<=0)
    {
        return -1;
    }
    for (i=0;i<nread;++i)
    {
        result[*cur+i]=buff[i];
        printf("%c",buff[i]);
    }
    (*cur)=(*cur)+nread;
    return 0; 
}

13 个解决方案

#1


       帮顶  ~~  

#2


帮顶!专接非技术分!

#3


printf 需要在最后加 \n 才能输出数据。

#4


引用 3 楼 findcsdn 的回复:
printf 需要在最后加 \n 才能输出数据。


你说的这个现象 我遇到过,我加了\n就能输出最后一行了~  但是我需要不加也能输出~  我去试试putchar()看可行~

#5


putchar()也不行~~~   

#6


"MPC8610HPCD login:"确定也是串口输出的数据吗?

#7


恩是的~  minicom也可以收到呢~   我现在在用GDB 跟踪,在getData里插了断点,每次continue发现竟然屏幕上打印的输出 跟buff里的值有错位,我的最终结果 result数组里 的确是有了"MPC8610HPCD login:"
下面是我截的GDB调试的信息  我是很难理解了~~~

(gdb) c
Continuing.

Debian GNU/Linux 3.1 MPC8610HPCD ttyS0


Breakpoint 1, getData (fd=6, 
    result=0xbfe59c24 "\r\n\r\nU-Boot 1.3.0 (Feb 13 2009 - 11:31:21)\r\n\r\nFreescale PowerPC\r\nCPU:\r\n    Core: E600 Core 0, Version: 0.2, (0x80040202)\r\n    System: 8610, Version: 1.1, (0x80a00011)\r\n    Clocks: CPU:1066 MHz, MPX: 53"..., 
    cur=0xbfe59c10) at getData.c:139
139 (*cur)=(*cur)+nread;
(gdb) p buff
$11 = "\r\nDebian GNU/Linux 3.1 MPC8610HPCD ttyS0\r\n\r\nMPC8610HPCD login: ", '\0' <repeats 49 times>, "\002\000\000\000\000\000\000\000�_\002�P\214\004\b"

#8


上面这个截的还体现不出来错位,这个可以体现出来。明明输出的是"Unable to find swap-space signature" 但是buff数组里的开头却是"ignature",初步分析就是每遇到一个\r\n  printf才输出,这个原因我很难理解,因为普通的函数直接printf一个字符 也是完全没问题的啊~

(gdb) 
Continuing.
Unable to find swap-space signature

Breakpoint 1, getData (fd=6, 
    result=0xbfe59c24 "\r\n\r\nU-Boot 1.3.0 (Feb 13 2009 - 11:31:21)\r\n\r\nFreescale PowerPC\r\nCPU:\r\n    Core: E600 Core 0, Version: 0.2, (0x80040202)\r\n    System: 8610, Version: 1.1, (0x80a00011)\r\n    Clocks: CPU:1066 MHz, MPX: 53"..., 
    cur=0xbfe59c10) at getData.c:139
139 (*cur)=(*cur)+nread;
(gdb) p buff
$9 = "ignature\r\np-space signature\r\nEXT2-fs warning: mounting unchecked fs, running e2fsck is recommended\r\nUnable to find swap-space s\b"

#9


路过,帮顶。

#10


fflush(stdout)试试

#11


引用 10 楼 yuzl32 的回复:
fflush(stdout)试试


呵 刚搜到这个,正在试呢 谢谢你哦~

#12


好吧~  问题就在这了~  sigh, 就因为对底层的知识的缺乏,耽误了多少天的功夫~~~

请问 yuzl32  关于这方面的缓冲区 有什么推荐的书 来学习下吗?

#13


该回复于2012-09-24 08:36:49被版主删除

#1


       帮顶  ~~  

#2


帮顶!专接非技术分!

#3


printf 需要在最后加 \n 才能输出数据。

#4


引用 3 楼 findcsdn 的回复:
printf 需要在最后加 \n 才能输出数据。


你说的这个现象 我遇到过,我加了\n就能输出最后一行了~  但是我需要不加也能输出~  我去试试putchar()看可行~

#5


putchar()也不行~~~   

#6


"MPC8610HPCD login:"确定也是串口输出的数据吗?

#7


恩是的~  minicom也可以收到呢~   我现在在用GDB 跟踪,在getData里插了断点,每次continue发现竟然屏幕上打印的输出 跟buff里的值有错位,我的最终结果 result数组里 的确是有了"MPC8610HPCD login:"
下面是我截的GDB调试的信息  我是很难理解了~~~

(gdb) c
Continuing.

Debian GNU/Linux 3.1 MPC8610HPCD ttyS0


Breakpoint 1, getData (fd=6, 
    result=0xbfe59c24 "\r\n\r\nU-Boot 1.3.0 (Feb 13 2009 - 11:31:21)\r\n\r\nFreescale PowerPC\r\nCPU:\r\n    Core: E600 Core 0, Version: 0.2, (0x80040202)\r\n    System: 8610, Version: 1.1, (0x80a00011)\r\n    Clocks: CPU:1066 MHz, MPX: 53"..., 
    cur=0xbfe59c10) at getData.c:139
139 (*cur)=(*cur)+nread;
(gdb) p buff
$11 = "\r\nDebian GNU/Linux 3.1 MPC8610HPCD ttyS0\r\n\r\nMPC8610HPCD login: ", '\0' <repeats 49 times>, "\002\000\000\000\000\000\000\000�_\002�P\214\004\b"

#8


上面这个截的还体现不出来错位,这个可以体现出来。明明输出的是"Unable to find swap-space signature" 但是buff数组里的开头却是"ignature",初步分析就是每遇到一个\r\n  printf才输出,这个原因我很难理解,因为普通的函数直接printf一个字符 也是完全没问题的啊~

(gdb) 
Continuing.
Unable to find swap-space signature

Breakpoint 1, getData (fd=6, 
    result=0xbfe59c24 "\r\n\r\nU-Boot 1.3.0 (Feb 13 2009 - 11:31:21)\r\n\r\nFreescale PowerPC\r\nCPU:\r\n    Core: E600 Core 0, Version: 0.2, (0x80040202)\r\n    System: 8610, Version: 1.1, (0x80a00011)\r\n    Clocks: CPU:1066 MHz, MPX: 53"..., 
    cur=0xbfe59c10) at getData.c:139
139 (*cur)=(*cur)+nread;
(gdb) p buff
$9 = "ignature\r\np-space signature\r\nEXT2-fs warning: mounting unchecked fs, running e2fsck is recommended\r\nUnable to find swap-space s\b"

#9


路过,帮顶。

#10


fflush(stdout)试试

#11


引用 10 楼 yuzl32 的回复:
fflush(stdout)试试


呵 刚搜到这个,正在试呢 谢谢你哦~

#12


好吧~  问题就在这了~  sigh, 就因为对底层的知识的缺乏,耽误了多少天的功夫~~~

请问 yuzl32  关于这方面的缓冲区 有什么推荐的书 来学习下吗?

#13


该回复于2012-09-24 08:36:49被版主删除