原创 一个串口操作的问题---串口缓冲区★★★★

2011-6-14 21:28 6814 10 7 分类: MCU/ 嵌入式

<?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个字节吗?

Re: 请教一个串口操作的问题

 

 

串口缓冲就只能存放8个字

 

Re: 请教一个串口操作的问题

 

 

是这样。楼上的,谢了。

 

Re: 请教一个串口操作的问题

 

 

starless:

但是,我又试了一下write函数,是没有字数控制的,我写多少个字节都可以一次发

送。而且好多资料上的read函数都没有提及8个字节的限制问题,难道那些资料都没

有经过实践的?是不是有地方可以设置缓冲区大小,总不能让我调用numread(fd,&c,1)吧,

我想缓冲区只有8个字节好像不太可能,应该在512-1024才合适嘛。

 

Re: 请教一个串口操作的问题

 

 

一般来说只有本地接受缓冲,发送的时候只是不停的法给对方,所以,如果你不停的

发送就可能造成数据丢失。
你可以做一个实验试试。

 

Re: 请教一个串口操作的问题

 

我没写过linux下串口的程序, 但我知道串口芯片是16550, 它有16字节的缓冲区,

每次**只能**返回8个字节是肯定不对的.

Re: 请教一个串口操作的问题

 

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.

Re: 请教一个串口操作的问题

 

的确如楼上所说,我说的是芯片物理的fifo大小,有一个问题你用得是否为标准

内核,芯片是否1655016550的物理fifo的确是16字。
我刚才查看了一下标准kernel中的串口驱动。它定义了一个最大传输字节为256
另外,写了一个程序试验了一下。待会儿贴上来。一起研究。

Re: 请教一个串口操作的问题

 

 

#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");
}

 

Re: 请教一个串口操作的问题

 

 

试验步骤如下:
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



 

Re: 请教一个串口操作的问题

 

 

推测:newperson,你可能发送的时候,在8个字节后面有分行符。

 

Re: 请教一个串口操作的问题

 

 

starless真是个热心人啊

 

Re: 请教一个串口操作的问题

 

 

呵呵,手头正好有条件,这个问题我正好也不是特别清楚。

 

Re: 请教一个串口操作的问题

 

 

starless:
我又根据你的提示,对程序重新测试了一遍,后来发现是我串口设置有不同,我将串口设成了原始输入模式 ***tio.c_lflag &= ~(ICANON | ISIG | ECHO);
终端有二种工作模式,规范模式(默认)和非规范模式(或称原始模式),在规范模式下是以一次一行的方式接收输入的。
我试了你的测试程序,增加了一些常用的串口设置,如波特率等,边增加边测试,然后在增加到那句设置时,串口接收就出现了问题,只能收8个字符了。去掉设置又好了。
但是设置成规范模式也有个问题,我在2台计算机对联的时候,如A发,B收,A发的数据B并未接收而是返回给了A,在A的串口调试助手的接收窗口可以发现A自己发出去的数据。
所以为保证程序的可靠性,最终我还是老老实实选用了原始模式,并每次只Read一个字节。

 

Re: 请教一个串口操作的问题

 

 

看来,我的测试是在规范模式下做的。
原始模式看来不错,要是我也选择原始模式。

 

Re: 请教一个串口操作的问题

 

 


我看了这之前的所有贴子,猜测原因如下:

1
、对于设备调用read与正规文件有所区别。对正规文件,read试图返回尽可能多的内容,除非已经到达文件的尾部,否则将填满read(fd, buf, buf_len)buf。对于设备,则虽设备不同read的行为也有所区别,原始模式下的串口设备,则不像正规文件那样等到填满了buf才返回,而是每个接收中断都会唤醒应用程序,read不会一直阻塞到填满buf才返回。

2
16550的确是有16个字节的接收FIFO,但接收可以设置一个水准线(四个值选一个:10个字节、4个字节、8个字节、14个字节),收到的字节数达到FIFO水准线”16550设备就会产生中断(或者是超时也会产生中断),不是要一定要等到填满了rx_FIFO才产生中断(这样如果中断发生了延迟,中断没能及时处理,FIFO就要溢出了),我猜想Linux的串口驱动程序可能是把这个水准线设置成了8个字节。

3
、所以才会每次只受到8个字符。另外,我没看Linux的串口驱动,也没做过试验,只是凭经验瞎猜,真正原因需要各位自己去证实。

 

 

 

文章评论0条评论)

登录后参与讨论
我要评论
0
10
关闭 站长推荐上一条 /2 下一条