[英]set low_latency flag on a serial port on windows in c++
我有一個程序,使用boost asio打開一個串口。
默認情況下,串行端口具有使線路空閑的延遲。 在Windows平台上,我看到延遲30毫秒,在Linux平台上,延遲是20毫秒。
對於Linux環境,我發現“linux.h”的類'ioctl'有一種方法可以設置帶有一些標志的串行設置(以及我需要的東西:low_latency)。
代碼如下:
boost::asio::basic_serial_port<boost::asio::serial_port_service>::native_type native = serial_port_.native(); // serial_port_ is the boost's serial port class.
struct serial_struct serial;
ioctl(native, TIOCGSERIAL, &serial);
serial.flags |= ASYNC_LOW_LATENCY; // (0x2000)
ioctl(native, TIOCSSERIAL, &serial);
我想減少我的Windows平台上的延遲。 對於使用C ++的窗口,是否有相同的方法?
順便說一句,我看到有一些解決方案建議在Windows設備管理器中更改串口的屬性,但我沒有這些解決方案所顯示的屬性,我需要一個代碼解決方案。
從Windows中的boost asio獲取本機句柄並將其傳遞給SetCommTimeouts: http : //msdn.microsoft.com/en-us/library/windows/desktop/aa363437( v = vs。85) .aspx
特別是,請查看COMMTIMEOUT結構的ReadIntervalTimeout: http : //msdn.microsoft.com/en-us/library/windows/desktop/aa363190( v = vs.85) .aspx
ReadIntervalTimeout通信線路上兩個字節到達之間允許的最長時間(以毫秒為單位)。 在ReadFile操作期間,時間段從收到第一個字節開始。 如果任意兩個字節到達之間的間隔超過此量,則完成ReadFile操作並返回任何緩沖的數據。 值為零表示不使用間隔超時。 MAXDWORD的值與ReadTotalTimeoutConstant和ReadTotalTimeoutMultiplier成員的零值組合在一起,指定讀取操作將立即返回已接收的字節,即使沒有收到任何字節。
您還可以使用GetCommTimeouts查詢當前值: http : //msdn.microsoft.com/en-us/library/windows/desktop/aa363261( v = vs.85) .aspx
我記得在NT4 / Win2k / WinXP時代遇到這個問題,我認為你遇到的問題是類似的。
使用COMMTIMEOUT結構總是在每次超時后添加一個時間片延遲,這意味着對於可變長度數據包,您總是會增加10ms或16ms的延遲,具體取決於機器是否是SMP機器。 例如,你不能真正獲得1毫秒的超時。 即使在具有完成端口的串行端口上使用COMMTIMEOUT進行異步操作時也是如此。
為了消除這個問題,我使用了IO完成端口,並且有一個單字符讀取操作管道。 讀取在字節到達端口時完成,並且可以在主IOCP事件循環中出列。 這以一些代碼復雜性為代價提供了非常高的性能。
使用boost :: asio時,這種方法不會很容易,因為只允許一個未完成的讀取。 您可以嘗試為Windows for asio實現基於Windows IOCP的串行端口后端,或者您可以為串行通信創建單獨的IOCP和線程。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.