请问如何判断往串口的写操作(write)已经完成???高分请教!!!

zhangsheng2003 2004-03-09 06:34:33
我想循环地往串口1和串口2写数据:
while(1)
{
if(往串口1的写操作write已经完成) 则往串口2写;
if(往串口2的写操作write已经完成) 结束本次循环;
}
请问如何判断往串口的写操作(write)已经完成???
用ioctl(fd,FIONREAD,&bytes);可以判断输入缓冲的字节数,
能否用类似的方法解决上面的问题?
...全文
1035 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangsheng2003 2004-06-11
  • 打赏
  • 举报
回复
up
carol1980 2004-04-29
  • 打赏
  • 举报
回复
前两天写了个相关的程序 —— 不知道每次收到的数据报到底有多大,但是每个包的结尾都有一个特殊字符 '\r'

所以我就根据这个循环读完这个包
zhangsheng2003 2004-04-28
  • 打赏
  • 举报
回复
to uestc_yrq(我是猫) :
如果帧长可变,那么读的时候又如何处理,因为很多情况下长度是可变的。不知你看法如何?

uestc_yrq 2004-04-22
  • 打赏
  • 举报
回复
我没有考虑那么多,如果写我是通过这么一个循环来做的
nwrite(int ttyfd,char *buf,int len){
int count;
int now=len;
do{
count =write(ttyfd,buf,now);
if (count==now) break;
now -=count;
buf +=count;
}while (ount==0);
}
再度的时候,先判断是否缓存中有一帧的内容。
int nread(int ttyfd,char *buf,int len){
int count,
if(ioctl(ttyfs,FIOREAD,&count)<0) return -1;
if(count<len) return 0;
count= read(ttyfd,buf,len);
return count;
}
zhangsheng2003 2004-04-16
  • 打赏
  • 举报
回复
to carol1980(幻想懒王++) :
你问的"你的想法是不是,让接受端在接受完数据之前,就知道发送端一次要发送多少数据?"

我的现法和你理解的差不多,想让接受端在把串口的接收缓冲读到自己的缓冲之前,要知道发送端一次发送了多少数据,并且确认已经接收完(即接收缓冲的字节数就等于发送端发送的字节数),这样就可以一次把串口的接收缓冲读到自己的缓冲,否则不读而去处理其他的事,下次轮到此串口时再重复上面的检查。

当然,你说的办法我认为也是可以的,但是如果不考虑发送端,而是在接收端利用适当的延时,不知能否解决这样的问题,我就不知道要怎样考虑这样的延时。

这是我的想法,欢迎大家继续讨论,也感谢大家!!!
carol1980 2004-04-15
  • 打赏
  • 举报
回复
(3)另外,用ioctl(fd ,FIONRESD ,&bytes); 可以检查接收缓冲的字节数,我的问题是:
利用怎样的延时(尽可能小,比如用9600的波特率)和检查接收缓冲的字节数才能判串口的接收已经完成?在判断接收完成后才用read(fd ,mybuff,bytes)把串口接收缓冲中字节串读到自己的字节缓冲mybuff中。

这个问题嘛?

你的想法是不是,让接受端在接受完数据之前,就知道发送端一次要发送多少数据?

如果是这样的话,我的做法是,发送的数据里面包括一次要发送的数据大小。接受端首先读取数据长度,然后循环读完所有数据。
zhangsheng2003 2004-04-15
  • 打赏
  • 举报
回复
to carol1980(幻想懒王++) :
//发送端:
int bytes;
ioctl(fd ,TIOCOUTS ,&bytes); //用于检查发送缓冲中的字节数

另外,怎么没人帮我看看上面的问题呀?
firstyi 2004-04-13
  • 打赏
  • 举报
回复
up
carol1980 2004-04-12
  • 打赏
  • 举报
回复
嗯,FIONREAD 我也看到了,是用来获得input buffer里的字节数的

我也想知道,有没有简单的方法获得 output buffer 里的字节数。
zhangsheng2003 2004-04-11
  • 打赏
  • 举报
回复
to carol1980(幻想懒王++) :
对不起,上面的FIONRESD 写错了,应该是FIONREAD
我暂时也记不起在那儿找到的,你可以用用看
carol1980 2004-04-09
  • 打赏
  • 举报
回复
你说的 TIOCOUTS FIONRESD 在 ioctl_list 里面都没有啊

我觉得目前的话,要么就是使用 select 函数比较好
holymoon 2004-04-09
  • 打赏
  • 举报
回复
至于16字节的缓冲,那时uart的硬件缓冲,不是驱动(软件)管理的。
holymoon 2004-04-09
  • 打赏
  • 举报
回复
to zhangsheng2003(viwmwx):
关于串口驱动4K缓冲的说法,参考/linux-source/drviver/char/serial.c文件中tmp_buf的定义,tmp_buf是一个写缓冲,分配的是get_zeroded_page, one page的内存。在X86上正好是4K吧!
zhangsheng2003 2004-04-06
  • 打赏
  • 举报
回复
to whiteclouds(蓝蓝的天上白云飘) :
(1)我用300的波特率只是为了验证“发送端把字符串往串口write后是否其他的事就交给串口驱动程序去办了?”这个想法正确否
(2)我是用下面方法解决“判断数据发完”的问题,没有用到硬件握手,现在写出来大家看看是否有问题:
//发送端:
int bytes;
ioctl(fd ,TIOCOUTS ,&bytes); //用于检查发送缓冲中的字节数
if(bytes==0) //则可以判断已经发送完了
(3)另外,用ioctl(fd ,FIONRESD ,&bytes); 可以检查接收缓冲的字节数,我的问题是:
利用怎样的延时(尽可能小,比如用9600的波特率)和检查接收缓冲的字节数才能判串口的接收已经完成?在判断接收完成后才用read(fd ,mybuff,bytes)把串口接收缓冲中字节串读到自己的字节缓冲mybuff中。
anonimousboy 2004-04-03
  • 打赏
  • 举报
回复
学习!
whiteclouds 2004-04-03
  • 打赏
  • 举报
回复
linux的串口驱动只有16字节的缓冲,至少从我编过的程序来看是这样。用select处理读操作没问题,关键写操作如果过快,不管你怎么设置,都会出现阻塞。楼主为什么用300的波特率?太慢,现在一般都用9600了。设想你再马路开车,车道上已经都是车了,你的车无论如何都要等待才能开。
至于楼主问的"发送端为什么不等接收端接收完第一个字符串后再发第二个字符串呢?",除非你在硬件上使用了握手信号,否则计算机怎么知道数据发完了?
wmrwinhap 2004-04-02
  • 打赏
  • 举报
回复
int ret;
fd_set w;
struct timeval tv;

while(数据未写完) { // 数据写完退出
FD_ZERO(&w);
FD_SET(fd,&w);
tv.tv_sec=0;
tv.tv_usec=100000; // 超时时间设置为100 毫秒
ret=select(fd+1,NULL,&w,NULL,&tv);
if(ret<0) break; // 写错误
else if(ret>0) { // 已写完
if(FD_ISSET(fd,&w)) { // 恒为真
// 继续写剩余数据
}
}
// else if(ret==0); // 超时没写完,继续等待
}

这样就可以分批写数据(当然也可以一次写所有数据),反正当前数据写完则select将返回>0
zhangsheng2003 2004-04-02
  • 打赏
  • 举报
回复
to holymoon(风雪狂客):有什么办法可以验证你说的"linux串口驱动程序本身有4k的缓冲区"?
用select好像是个不错的办法,我想对于多个串口的读也可以用类似的方法,不过还是要试试
看.
非常感谢大家的帮忙,欢运更多的人来讨论!!!
holymoon 2004-03-26
  • 打赏
  • 举报
回复
linux串口驱动程序本身有4k的缓冲区
zhangsheng2003 2004-03-26
  • 打赏
  • 举报
回复
up

23,124

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧