【问题标题】:Porting Win32 serial (RS232) comms to POSIX将 Win32 串行 (RS232) 通信移植到 POSIX
【发布时间】:2019-05-20 19:31:37
【问题描述】:

目前我正在将 Win32 应用程序移植到 POSIX。该软件本身已有几十年的历史,用于更新专有机器。

虽然大多数函数相对容易用简单的宏和一些调用 POSIX 函数的较小函数替换,但事实证明与 RS232 通信相关的函数很困难。

应用程序使用这些函数通过 RS232 进行通信:

BOOL GetCommState(HANDLE comPort, DCB* dataControlBlock);

BOOL SetCommState(HANDLE comPort, DCB* dataControlBlock);

BOOL GetCommTimeouts(HANDLE comPort, LPCOMMTIMEOUTS comTimeouts);

BOOL SetCommTimeouts(HANDLE comPort, LPCOMMTIMEOUTS comTimeouts);

BOOL SetCommMask(HANDLE comPort, DWORD eventMask);

BOOL GetCommMask(HANDLE comPort, LPDWORD eventMask);

BOOL WaitCommEvent(HANDLE comPort, LPDWORD eventMask, LPOVERLAPPED overlapped);

连同以下结构:

typedef struct _DCB { /*...*/ } DCB, *LPDCB;

typedef struct _COMMTIMEOUTS { /*...*/ } COMMTIMEOUTS, *LPCOMMTIMEOUTS;

在搜索时,我遇到了this 链接,其中提到了 termios.h 和 sys/select.h,但这些标头的结构与我的喜好相差太大。使用 Wine 提到的其他答案,由于应用程序被移植到的硬件,这根本不是一个选项。

如果可能,我想实现一个更简单的解决方案并保留应用程序当前正在使用的结构 - 试图保持一切交叉兼容。

有没有办法做到这一点?
还是我坚持重写应用程序的粗略部分?

【问题讨论】:

  • Linux中的RS232已经在文件系统中实现了。你要归档什么?
  • 我希望使用应用程序中已经提供的结构,所以我不必重新编写太多的应用程序。本质上,我需要使用 RS232 将(原始)数据发送到专有 ECU 以更新其固件。最初用于运行软件的硬件已不再生产,因此我们/我需要将其移植到不同的硬件上。
  • 考虑使用boost::asio。它适用于 Windows 和 Linux。但在开始之前,请检查您是否可以为您的目标机器构建boost。一般来说这是可能的——我们甚至在ARMv5处理器上运行boost
  • RS232 to send (raw) data to a proprierary ECU 有什么问题?
  • @P__J__ 问题是,该应用程序是为 Win32 编写的。手头的问题是,是否有办法在 POSIX 机器上保持 Win32 结构,以便应用程序可以保持不变。本质上,如果有一种简单的方法可以在 Win32 和 POSIX 系统调用之间创建接口。我已经检查了 GtkTerm,但这也没有多大帮助。

标签: c winapi serial-port posix porting


【解决方案1】:

根据您的应用程序的复杂程度,我看到了两种可能的解决方案:

  1. 用等效的 POSIX 调用替换 Win32 调用,如 cmets 中提到的 P__J__。如果您这样做,等效的调用可能类似于以下内容:

GetCommState : tcgetattr

SetCommState : tcsetattr

Get/SetCommTimeouts :您仍然可以使用tcsetattr 进行设置,修改struct termios 中的c_cc[VTIME] 条目

Set/GetCommMask :不幸的是,POSIX API 没有与此功能等效的功能。如果您需要关心控制信号(CTS、DSR、RING),则需要循环读取线路状态。如果您只关心读取返回的字节,则无需担心这一点。

WaitCommEvent :POSIX 上的等价物是select(旧式)或poll(更现代)。与上面的 CommMask 类似,select/poll 将在有数据要读取时返回,而不是在控制线更改时返回。

  1. 如果您不想自己尝试解决跨平台问题,有几个库(C 语言)可以跨平台。这是一个快速列表:

..这就是我所知道的一切。我知道的所有其他库都是用于 C++ 的。

【讨论】:

  • 谢谢,我会先检查这些库,看看是否可以相应地重新编写应用程序。遗憾的是,这是一个相当复杂的应用程序。