異步串口(UART)通訊是嵌入式設備中最常見的通訊方式之一。本文主要針對預裝Windows CE操作系統的英創主板,分析用戶層程序在使用UART進行發送時的幾個有關問題,供客戶在設計應用程序時參考。
問題1:數據是否發送出去了?
WriteFile函數是發送串口數據的基本API,具體函數形式及參數定義如下:
BOOLWriteFile(
HANDLE hFile,//CreateFile返回函數Handle
LPCVOID lpBuffer,//裝載發送數據的Buffer指針
DWORD nNumberOfBytesToWrite,//待發送數據的字節長度
LPDWORD lpNumberOfBytesWritten,//返回的實際發送的字節數
LPOVERLAPPED lpOverlapped// = NULL,CE未使用該參數
);
WriteFile的返回值為TRUE并不代表發送Buffer中的數據已全部發送出去了,需要檢查返回的實際字節長度lpNumberOfBytesWritten。所以推薦的調用方法為
// 發送緩沖區pTxBuff, 發送長度dwLen
DWORD dwNumberOfBytesWritten = 0;
BOOL bRet = WrietFile(hFile, pTxBuf, dwLen, &dwNumberOfBytesWritten, NULL);
if(bRet && (dwLen == dwNumberOfBytesWritten))
{
//發送緩沖區中的數據已成功送入UART硬件的發送端口,大多數情況數據已從
//物理端口發送出去,但此時可能還有若干字節還在UART的硬件TX FIFO中,等
//待硬件控制器順序發送。
//… 發送成功 …
}
else
{
//發送出錯處理。。。。
}
問題2:WriteFile函數的阻塞問題
CE串口驅動的執行數據發送時,為了保持代碼的高效率,沒有在驅動程序中層另外分配Buffer,把應用層需發送的數據先Copy到內部再發送,而是直接利用用戶層的pTxBuf。因此原則上說,當數據沒有發送完前,WriteFile函數是不會返回,處于阻塞掛起狀態的。進一步,可能存在某種原因,數據始終沒有發送完畢,則WriteFile將永遠阻塞而不會返回。不少應用程序并不希望這樣的永遠阻塞,而是希望WriteFile能在一定時間內返回,即使出錯,也讓應用程序有機會進行出錯處理。CE驅動為此專門設置了超時機制,其數據結構如下:
typedefstruct_COMMTIMEOUTS {
DWORD ReadIntervalTimeout; //與接收有關,本文不討論
DWORD ReadTotalTimeoutMultiplier; //與接收有關,本文不討論
DWORD ReadTotalTimeoutConstant; //與接收有關,本文不討論
DWORD WriteTotalTimeoutMultiplier; //發送超時倍數因子
DWORD WriteTotalTimeoutConstant; //發送超時固定常數值
} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
實際在驅動中,發送超時的計算及使用方法如下:
DWORD dwTimeout =
CommTimeouts.WriteTotalTimeoutMultiplier*dwLen +
CommTimeouts.WriteTotalTimeoutConstant;
if( !dwTimeout )
dwTimeout = INFINITE;
//等待來自發送中斷線程的發送結束事件
ULONG WaitReturn = WaitForSingleObject(hTransmitEvent, dwTimeout);
上面的代碼中dwTimeout的單位為ms,在第一次打開串口驅動”COM#”時,超時數據結構中的WriteTotalTimeoutMultiplier和WriteTotalTimeoutConstant均為0,所以就有發送超時無窮的問題。為了讓dwTimeout為有限值,需要設置超時參數如下:
COMMTIMEOUTS CommTimeouts; //定義局部變量
GetCommTimeouts(hFile, &CommTimeouts); //讀取串口的超時參數
//假設應用程序設置的串口波特率為baud
CommTimeouts. WriteTotalTimeoutConstant = baud / BR9600 + 1;
CommTimeouts. WriteTotalTimeoutMultiplier =
CommTimeouts.WriteTotalTimeoutConstant * 2;
SetCommTimeouts(hFile, &CommTimeouts); //重新設置串口超時參數
上述代碼大致設置了一個2倍發送時間長度的超時時間,其中選取BR9600為單位時間,是因為9600bps波特率基本對應一個字節的發送時間為1ms。
-
WINDOWS
+關注
關注
4文章
3702瀏覽量
94057 -
嵌入式主板
+關注
關注
7文章
6107瀏覽量
37078
發布評論請先 登錄
單片機中的串口通訊串行同步通信與串行異步通信
卡塔爾通訊與信息技術部與Ooredoo電信公司一行來訪達實智能開展培訓
龍芯中科成功舉辦2025信息技術應用創新產教融合交流會
龍芯中科助力2025教育信息技術應用創新大賽成功舉辦
使用nrf54L15的NORDIC藍牙芯片,通過串口發送一幀數據包時,會出現分包發送分析
寶馬南京信息技術有限公司開業
【道生物聯TKB-623評估板試用】TKB-623評估板雙機通訊測試_程序開發
易華錄入選國家級信息技術應用創新典型解決方案
佛瑞亞如何通過信息技術推動業務增長
飛騰主板為信創產業發展提高硬實力
DEKRA德凱成為沙特通信和信息技術設備技術法規認證機構
京能信息蒞臨中軟國際數字電力科創中心調研
科普|信創是什么?一文讀懂“信息技術應用創新”戰略
英創信息技術串口通訊中數據發送的有關問題分析
評論