所以我有这个测试代码通过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, TCSANOW, &tty);
printf("Write: %i\n", write(fd, "HELLO", 5));
sleep(5);
if(close(fd) != 0){
warn("Could not close write fd");
}
程序执行正常并发送“HELLO”但有一个问题。调用write()函数时似乎没有发送“HELLO”,而是在文件描述符关闭时发送。我添加了上面的sleep(5)行来测试这个理论,果然,“HELLO”在程序执行后约5秒发送。如何在write()命令之后立即发送“HELLO”而不是close()?
答案 0 :(得分:8)
该设备是一个tty设备,所以fsync不会有帮助,也许不会fflush。
默认情况下,设备在规范模式下工作,这意味着数据被打包成行单位。您可能会发现在数据中添加cr / lf对将导致它被发送。
您需要确保规范模式已关闭。此外,R的答案将是有用的。
答案 1 :(得分:5)
来自write()
的手册页:
从write()成功返回并不能保证数据已提交到磁盘。事实上,在一些错误的实现上,它甚至不能保证已成功为数据保留空间。唯一可以确定的方法是在写完所有数据后调用fsync(2)。
您需要在文件描述符上调用fsync()
以确保实际提交数据。
答案 2 :(得分:3)
首先,不知道为什么你首先将所有termios字段设置为0,然后在没有对其前面的0进行任何修改的情况下,决定在cflag上设置通常的rs232标志。 (而不是在没有OR的情况下直接执行此操作,现在将其设置为0,以上)。
您可能想要的 - 而不是设置所有这些标志只是cfmakeraw()的termios字段。
另外,sync();没有任何参数(NOT fsync!;)似乎将所有挂起的输出发送到所有文件描述符,而不仅仅是块设备。还有tcp套接字和rs232 ..
并且open()有一个选项O_SYNC(O_SYNC和O_ASYNC具有令人困惑的名称,但与被驱动的串行线路协议无关,一个立即提交write(),另一个生成一个信号当输入变得可用时捕获(有点像dos上基于irq的rs232;)
在open()中设置O_SYNC可能已经解决了您的问题。
也'通过读取另一端的数据'......有些东西叫做'leds'和'resistor',你可以连接到TXD并查看数据;)还有一些叫做'rs232 breakout'的东西box'或可以使其直接可见的范围 - ;)比“猜测”哪一方行为不正确更容易。
警告:没有测试代码。它汇编。但是我把所有的ttyUSB0电缆放在另一栋楼里。但我认为你的主要问题是O_SYNC。将所有termios crap设置为0与cfmakeraw()几乎相同...也为什么设置CREAD如果你要打开它只写? (为什么打开它只写而不是写入? - 而且只有写入你不必害怕它成为一个控制tty(O_NOCTTY;)所以在只写的情况下,这也不是完全需要..
刚注意到%i(同样适用于%d btw)格式化程序也触发了类型不匹配警告,写入()的ssize_t返回值,以便将其转换为(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);
cfsetispeed(&tty,B19200);
tcsetattr(fd,TCSANOW,&tty);
printf("Write: %i\n",(int)write(fd,"HELLO",5));
sync();//if all else fails, also try without, O_SYNC should already fix that.
close(fd);
};
答案 3 :(得分:2)
输出端口通常是缓冲的,因此在写入输出流与实际发送到磁盘,线路或其他内容之间存在更大或更小的差距。这通常是为了提高效率。
请参阅fflush(3)以强制将缓冲区提交到输出。
你也可以以一种非缓冲的方式打开输出描述符,但使用fflush
来表示“就是这样,我已经完成了”,可能更好。
答案 4 :(得分:0)
更改此行:
tty.c_cc[VMIN] = 0;
到此:
tty.c_cc[VMIN] = 1;
答案 5 :(得分:-1)
缓冲区未刷新。 fflush。
答案 6 :(得分:-1)
请参阅this question。因此,您需要刷新文件,以便在需要时进行IO。
答案 7 :(得分:-1)
尝试做
fflush( NULL );
在write()
之后。也许有一些内部缓冲区没有刷新。