微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C write直到closuresfd被调用才会发送数据

所以我有这个testing代码通过USB串口发送“HELLO”:

int fd; struct termios tty; if((fd = open("/dev/ttyUSB0",O_WRONLY|O_NONBLOCK|O_NOCTTY)) == -1){ err(1,"Cannot open write on /dev/ttyUSB0"); } tcgetattr(fd,&tty); tty.c_iflag = 0; tty.c_oflag = 0; tty.c_lflag = 0; tty.c_cflag = 0; tty.c_cc[VMIN] = 0; tty.c_cc[VTIME] = 0; cfsetospeed(&tty,B19200); cfsetispeed(&tty,B19200); tty.c_cflag |= CREAD|CRTSCTS|HUPCL|CS8; tcsetattr(fd,TCSA@R_502_6363@,&tty); printf("Write: %in",write(fd,"HELLO",5)); sleep(5); if(close(fd) != 0){ warn("Could not close write fd"); }

程序执行正常,发送“HELLO”,但有一个问题。 当调用write()函数时,似乎并没有发送“HELLO”,而是closures了文件描述符。 我添加了上面的sleep(5)行来testing这个理论,果然,在程序执行后的5秒内发送“HELLO”。 如何在write()命令之后立即发送“HELLO”而不是close()?

UART初始化:防止UART拉高RTS

如何在Linux中通过USB-to-RS232线与设备进行通信?

串口通信terminal替代品的Windows

奇怪的未经处理的exception

PXA270上的RS232通信延迟很高

从write()的手册页:

write()的成功返回不能保证数据已被提交到磁盘。 事实上,在一些错误的实现中,它甚至不保证空间已经成功地被保留用于数据。 唯一可以确定的方法是在写完所有数据后调用fsync(2)。

您需要在文件描述符上调用fsync()以确保数据实际上已经提交。

该设备是一个tty设备,所以fsync不会帮助,也许不fflush。

认情况下,设备工作在规范模式,这意味着数据被打包成行单元。 你可能会发现添加一个cr / lf对到你的数据将导致它被发送。

您需要确保规范模式关闭。 另外,R的答案将是有用的。

http://en.wikibooks.org/wiki/Serial_Programming/termios

输出端口通常是缓冲的,所以在写入输出流和实际发送到磁盘,线路或其他内容之间存在更大或更小的差距。 这通常是为了效率。

见fflush(3)强制缓冲区被提交到输出

你也许可以打开输出描述符,使其不被缓冲,但使用fflush来说'就是这样,我完成了',可能会更好。

首先,不知道为什么你首先将所有的termios字段设置为0,然后在没有对其之前的0进行任何修改的情况下,决定在cflag上设置通常的rs232标志。 (而不是直接或没有这样做,你现在把它设置为0,在上面)。

你可能会喜欢的 – 而不是设置所有这些标志只是cfmakeraw()termios字段。

另外,sync(); 没有任何参数(不fsync!;)似乎发送所有待处理的输出到所有文件描述符,而不仅仅是块设备。 还有TCP套接字和rs232 ..

并且open()有一个选项O_SYNC(O_SYNC和O_ASYNC有混淆的名字,但是与串口线协议时钟没有关系,一个立即提交write(),另一个产生一个信号用于陷阱输入变得可用(有点像基于DOS的rs232 irq)

在open()中设置O_SYNC可能已经解决了你的问题。

还有'通过读取另一端的数据'…有这些东西叫'leds'和'电阻器',你可以连接到TXD和查看数据;也有一些东西叫'rs232中断箱'或一个可以使其直接可见的范围)比“猜测”哪一方的行为不正确容易得多。

警告:不要测试代码。 它编译。 但是我把所有的ttyUSB0电缆都放在了另外一栋楼里。 但我认为你的主要问题是O_SYNC无论如何。 将所有的termios废话设置为0是几乎相同的cfmakeraw()…也为什么设置CREAD,如果你打开它只写? (为什么打开它只写而不是写入? – 也只写你不会害怕它成为一个控制tty(O_NOCTTY;),所以在只写的情况下,这也不是完全需要.. 。

只是注意到%i(同样为%d btw)格式化程序也会触发一个类型不匹配警告ssize_t write()的返回值,以便将其转换为(int)

#include<termios.h> #include<stdio.h> #include<unistd.h> #include<fcntl.h> void main(){ int fd; struct termios tty; fd=-1; while(fd<0){fd=open("/dev/ttyUSB0",O_WRONLY|O_NONBLOCK|O_NOCTTY|O_SYNC);sleep(1);}; cfmakeraw(&tty); tty.c_cflag=CREAD|CRTSCTS|HUPCL|CS8; cfsetospeed(&tty,B19200); tcsetattr(fd,(int)write(fd,5)); sync();//if all else fails,also try without,O_SYNC should already fix that. close(fd); };

缓冲区不被刷新。 fflush。

请看这个问题 。 基本上,您需要刷新文件以便IO在您想要的时候发生。

尝试做一个

fflush( NULL );

在write() 。 也许有一些内部缓冲区没有被刷新。

改变这一行:

tty.c_cc[VMIN] = 0;

对此:

tty.c_cc[VMIN] = 1;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐