将Win32串行(RS232)通讯移植到POSIX

时间:2018-12-20 09:39:58

标签: c winapi serial-port posix porting

当前,我正在将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提到了其他答案,由于要移植应用程序的硬件,这根本不是一个选择。

如果可能的话,我想实现一个更简单的解决方案并保留应用程序当前正在使用的结构-尝试使所有内容相互兼容。

有没有办法做到这一点?
还是我不得不重写应用程序的全部部分?

1 个答案:

答案 0 :(得分:1)

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

  1. 将Win32调用替换为等效的POSIX调用,如注释中提到的P__J__。如果这样做,等效调用将可能遵循以下内容:

GetCommStatetcgetattr

SetCommStatetcsetattr

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

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

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

  1. 如果您不想自己解决跨平台问题,则有几个库(用C语言编写)具有跨平台功能。快速清单:

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