<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />请教一个串口操作的问题 |
|
本人在LINUX下对串口读数据,调用read(fd,buf,num)函数,但每次只能返回8个字节,
无论指定num为多大,请教各位做过串口通信的高手,是read函数每次最多只能读8个字节吗?
|
|
|
串口缓冲就只能存放8个字 |
|
|
|
是这样。楼上的,谢了。 |
|
|
|
starless:
但是,我又试了一下write函数,是没有字数控制的,我写多少个字节都可以一次发
送。而且好多资料上的read函数都没有提及8个字节的限制问题,难道那些资料都没
有经过实践的?是不是有地方可以设置缓冲区大小,总不能让我调用num次read(fd,&c,1)吧,
我想缓冲区只有8个字节好像不太可能,应该在512-1024才合适嘛。 |
|
|
|
一般来说只有本地接受缓冲,发送的时候只是不停的法给对方,所以,如果你不停的
发送就可能造成数据丢失。 你可以做一个实验试试。 |
|
|
我没写过linux下串口的程序, 但我知道串口芯片是16550, 它有16字节的缓冲区, 你
每次**只能**返回8个字节是肯定不对的. |
|
The "buffer" those guys mentioned above is not a real buffer but a hardware
FIFO which should be several (8/16/32,etc.) bytes.
The real input buffer of ttySX which pass through "read" syscall should be 2
level , I dont remember the exact size of it, but it should be larger than or
equal as 1024 bytes, so the eight-byte-read must be wrong , I think.
Forgive my English inputing cuz I am in linux and I'm still not getting used
to the Chinese input in Linux. |
|
的确如楼上所说,我说的是芯片物理的fifo大小,有一个问题你用得是否为标准
内核,芯片是否16550。16550的物理fifo的确是16字。 我刚才查看了一下标准kernel中的串口驱动。它定义了一个最大传输字节为256。 另外,写了一个程序试验了一下。待会儿贴上来。一起研究。 |
|
|
#include <stdio.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>
#define BUFFSIZE 1024
int main() { int fd; int bytesread; char buff[BUFFSIZE];
fd = open("/dev/ttyS0",O_RDONLY); if (fd==-1) { printf("Open /dev/ttyS0 -- %s",strerror(errno)); return; } printf("read from /dev/ttyS0 : \n"); bzero(buff,sizeof(buff)); bytesread = read(fd,buff,sizeof(buff)); if (bytesread == -1) { printf("Read from /dev/ttyS0 -- %s",strerror(errno)); close(fd); return; } printf("%d:%s",bytesread,buff); close(fd); printf("\nFinished!\n"); }
|
|
|
|
试验步骤如下: 1.一个对接的串口线,分别连接本地串口1(/dev/ttyS0)和串口2(ttyS1)。 2.在一个控制台中,编译执行上述文件,假设编译好叫test。 #./test 此时,处于等待接受状态。 3.在另外一个工作台输入如下命令: #echo 1234567890 > /dev/ttyS1 结果:test 程序读出来了全部数据,读出字节数11。 4.我建立了一个文件(假设名字叫tmp)内容如下: 1234567890abcdefg 1234567890 然后,cat tmp > ttyS1。 结果: 在只读出来 1234567890abcdefg,读出字节个数18。也就是说只读出来第一行。如果要在第一行添加一些东西,比如说:1234567890abcdefghijklmnopq 结果还是把第一行读出来了,字节数28。
|
|
|
|
推测:newperson,你可能发送的时候,在8个字节后面有分行符。 |
|
|
|
starless真是个热心人啊 |
|
|
|
呵呵,手头正好有条件,这个问题我正好也不是特别清楚。 |
|
|
|
starless: 我又根据你的提示,对程序重新测试了一遍,后来发现是我串口设置有不同,我将串口设成了原始输入模式 ***tio.c_lflag &= ~(ICANON | ISIG | ECHO); 终端有二种工作模式,规范模式(默认)和非规范模式(或称原始模式),在规范模式下是以一次一行的方式接收输入的。 我试了你的测试程序,增加了一些常用的串口设置,如波特率等,边增加边测试,然后在增加到那句设置时,串口接收就出现了问题,只能收8个字符了。去掉设置又好了。 但是设置成规范模式也有个问题,我在2台计算机对联的时候,如A发,B收,A发的数据B并未接收而是返回给了A,在A的串口调试助手的接收窗口可以发现A自己发出去的数据。 所以为保证程序的可靠性,最终我还是老老实实选用了原始模式,并每次只Read一个字节。 |
|
|
|
看来,我的测试是在规范模式下做的。 原始模式看来不错,要是我也选择原始模式。 |
|
|
|
我看了这之前的所有贴子,猜测原因如下:
1、对于设备调用read与正规文件有所区别。对正规文件,read试图返回尽可能多的内容,除非已经到达文件的尾部,否则将填满read(fd, buf, buf_len)的buf。对于设备,则虽设备不同read的行为也有所区别,原始模式下的串口设备,则不像正规文件那样等到填满了buf才返回,而是每个接收中断都会唤醒应用程序,read不会一直阻塞到填满buf才返回。
2、16550的确是有16个字节的接收FIFO,但接收可以设置一个“水准线”(四个值选一个:1、0个字节、4个字节、8个字节、14个字节),收到的字节数达到FIFO的“水准线”16550设备就会产生中断(或者是超时也会产生中断),不是要一定要等到填满了rx_FIFO才产生中断(这样如果中断发生了延迟,中断没能及时处理,FIFO就要溢出了),我猜想Linux的串口驱动程序可能是把这个水准线设置成了8个字节。
3、所以才会每次只受到8个字符。另外,我没看Linux的串口驱动,也没做过试验,只是凭经验瞎猜,真正原因需要各位自己去证实。
|
|
|
|
|
|
|
|
文章评论(0条评论)
登录后参与讨论