我的使用串口的C程序如果第二次运行就会挂在读取上

问题描述 投票:0回答:1

我正在使用 Cygwin 环境来构建我的程序。我还使用 termius 库。本质上,程序打开串口:

fuart = open(device, O_RDWR | O_NOCTTY | O_SYNC);

然后它的工作流程涉及以这种方式写入串行端口:

write(fuart, str, xlen);

以及从中阅读:

ln = read(fuart, buff, n);

最后:

tcflush(fuart,TCIOFLUSH);
close(fuart);
sleep(2); //just in case

当我第一次运行该程序时,它运行得很好,但是当随后使用相同的输入数据启动时,它将挂在读取上。如果我在 Windows 设备管理器中禁用 COM 端口并重新启用它,那么下次运行时一切都会正常。 我想也许我的程序由于兼容性问题而无法正确关闭端口,并且它仍然处于锁定状态,但是其他终端软件(例如

teraterm
)可以打开它,更有趣的是,如果我尝试第二次运行我的程序并且它挂起,通过任务管理器强行关闭并打开第3方终端软件后,我可以看到它写入串口的数据。所以看起来我的 C 程序无法正确处理 COM 端口的关闭(或者可能刷新/释放读取缓冲区,因为它挂在读取操作上),这不是操作系统或平台问题。请注意,在其工作过程中,我的程序成功地多次读取和写入端口(但仅在第一次运行期间再次运行,之后我必须禁用-启用设备或打开另一个终端软件)。

作为参考,我通信的设备是 USB 调制解调器。

我尝试寻找答案,但运气不佳,除了找到关闭端口的建议,我已经这样做了。我看到有人在同一条船上,他们使用了启用-禁用技巧,但就像我说的我的研究据透露,其他终端程序没有这个错误,它们甚至有助于释放COM端口。我什至找到了一个使用 Cygwin 运行时的软件,即 mobastorm,并且它不会遇到这个问题。

c io serial-port com-port
1个回答
0
投票

您遇到的问题可能是由于使用

termios
结构初始化和配置串行端口设置不当造成的。当您在类 Unix 环境(例如 Cygwin)中打开串行端口时,每次正确设置端口以确保一致的行为至关重要。如果不这样做,可能会使端口处于不一致的状态,导致程序的后续运行在
read()
操作上挂起。

在执行任何读取或写入操作之前,应使用

termios
结构设置串行端口。这涉及:

  • 使用
    tcgetattr()
    检索当前端口设置。
  • 修改设置以满足您的通信要求(波特率、奇偶校验、停止位等)。
  • 使用
    tcsetattr()
    应用新设置。

根据您的需求配置控制模式、本地模式、输入模式和输出模式。例如,如果您想要带超时的非阻塞读取,则可以在

VMIN
结构的
VTIME
数组中设置
c_cc
termios
值。

使用

tcflush()
清除输入和输出缓冲区中的所有数据。这可确保过时数据不会干扰新的读取或写入操作。

完成后,确保使用

close()
关闭串行端口。这会释放文件描述符并允许其他程序毫无问题地访问该端口。

始终检查系统调用的返回值,例如

open()
read()
write()
tcgetattr()
tcsetattr()
。正确的错误处理可以防止您的程序进入不一致的状态。

为什么其他程序在强制关闭你的程序后还能工作:

Tera Term 等其他终端程序可能会在打开端口时重新初始化串行端口设置。它们重置以前程序留下的所有配置,这就是它们可以毫无问题地与串行设备通信的原因。通过在程序中正确设置串行端口,您可以模仿此行为并防止程序退出后端口保持不良状态。

© www.soinside.com 2019 - 2024. All rights reserved.