劉平 賈林林
(中國(guó)空空導(dǎo)彈研究院,河南洛陽(yáng) 471009)
三種串口通訊方法的實(shí)現(xiàn)與比較
劉平 賈林林
(中國(guó)空空導(dǎo)彈研究院,河南洛陽(yáng) 471009)
一般測(cè)控設(shè)備在工作過(guò)程中,需要上位機(jī)與下位機(jī)之間不斷通訊,完成系統(tǒng)內(nèi)部指令的下發(fā)和數(shù)據(jù)信息上傳功能,通常的做法是通過(guò)串口進(jìn)行通訊。本文介紹3種常用的串口通訊方法,對(duì)每種方法的具體操作步驟進(jìn)行詳細(xì)的分析,并對(duì)各自的優(yōu)缺點(diǎn)進(jìn)行比較。實(shí)踐表明,使用多線程串口通訊技術(shù)在整個(gè)測(cè)試過(guò)程中既能夠滿足產(chǎn)品測(cè)試任務(wù)的需要,又能夠及時(shí)響應(yīng)串口事件,完美地解決了系統(tǒng)的邏輯并發(fā)和物理并發(fā)問(wèn)題,滿足系統(tǒng)研制的需求。
串口通訊;單線程;多線程
在一般的測(cè)控設(shè)備工作過(guò)程中,當(dāng)對(duì)產(chǎn)品進(jìn)行測(cè)試時(shí),需要設(shè)備的上位機(jī)和下位機(jī)之間保持通信,完成系統(tǒng)內(nèi)部的下發(fā)指令和上傳數(shù)據(jù)信息功能。為了滿足產(chǎn)品測(cè)試任務(wù)的并行性,并能夠及時(shí)響應(yīng)串口事件,通常的做法是采用多線程監(jiān)聽串口事件的設(shè)計(jì)方式。本文通過(guò)設(shè)計(jì)實(shí)例比較3種串口通訊方法的優(yōu)劣,為類似的設(shè)備研發(fā)提供一些有用的參考。
MSComm是屬于Microsoft公司Visual C++提供的Active X控件,用于在簡(jiǎn)化Windows下進(jìn)行串口通信編程。其提供了一系列的標(biāo)準(zhǔn)通信命令的接口,使得通過(guò)串口收發(fā)數(shù)據(jù)變得極為簡(jiǎn)便[1]。MSComm控件提供了2種處理通信問(wèn)題的方法。
1.1 串口活動(dòng)法
由事件驅(qū)動(dòng)通信,在處理串口活動(dòng)方面具有很強(qiáng)大的功能。當(dāng)有事件發(fā)生時(shí),利用OnComm事件捕獲和處理各種通信事件,以獲取該事件的發(fā)生時(shí)間,同樣該過(guò)程也可以通過(guò)捕獲和處理通信中錯(cuò)誤的完成。
1.2 程序檢測(cè)法
常用于小型的自含程序,每當(dāng)用戶的應(yīng)用程序執(zhí)行完某一對(duì)串行通信接口的操作后,通過(guò)查詢CommEvent的屬性以便對(duì)該程序執(zhí)行結(jié)果或者某事件是否發(fā)生進(jìn)行確認(rèn)。圖1給出了Visual C++的MSComm控件具體操作步驟。
首先,通過(guò)添加控件的方式加入MSComm控件,并定義該控件類的對(duì)象。其次,初始化該控件的屬性,通過(guò)設(shè)置相應(yīng)的屬性,可以省去打開串口與關(guān)閉串口等操作,并且可以設(shè)置相應(yīng)的串口號(hào)、波特率、奇偶校驗(yàn)位、數(shù)據(jù)停止位等參數(shù)。再者,捕捉串口事件既可以通過(guò)查詢的方法從端口獲取數(shù)據(jù),也可以采用通過(guò)事件驅(qū)動(dòng)的方法。當(dāng)有諸如接收數(shù)據(jù)之類的事件發(fā)生時(shí)通知程序,并由程序響應(yīng)捕獲的消息完成對(duì)前面發(fā)生的通信事件的處理,也就是通過(guò)串口事件消息處理函數(shù)OnComm()中完成操作,這種事件驅(qū)動(dòng)方法應(yīng)用最為廣泛。最后,串口的讀寫分別通過(guò)GetInput()函數(shù)讀取接收緩沖區(qū)的字符,SetOutput()函數(shù)向發(fā)送緩沖區(qū)寫入數(shù)據(jù)流的方式實(shí)現(xiàn),極為簡(jiǎn)單,這兩個(gè)函數(shù)的原型分別是使用VARIANT數(shù)據(jù)結(jié)構(gòu)的VARIANTGetput()及void SetOutput(const Variant& newValue)。
圖1 MSComm控件實(shí)現(xiàn)串口通訊流程圖
Visual Studio中將串口虛擬成文件,所有的操作都模擬成對(duì)文件的讀寫,這樣程序有一個(gè)統(tǒng)一的編程界面,簡(jiǎn)化了編程接口,同時(shí)文件的處理屏蔽掉了硬件的端口和地址等特征。使用虛擬的緩沖區(qū)代替了實(shí)際的硬件緩沖區(qū),使得程序開發(fā)只需要單一地關(guān)注邏輯上的輸入與輸出關(guān)系。圖2給出了采用單線程方式完成串口通訊的步驟[2]。
2.1 打開串口并獲取串口資源句柄
在使用單線程方式進(jìn)行串口通信的整個(gè)過(guò)程中,始終存在一種動(dòng)作,即程序在通過(guò)CreatFile()函數(shù)指定串口設(shè)備及相關(guān)的操作屬性后返回一個(gè)用于后續(xù)通信操作的句柄。同時(shí),可在進(jìn)行函數(shù)參數(shù)設(shè)置時(shí)設(shè)計(jì)異步I/O通訊方式,保證半雙工通訊。
2.2 串口設(shè)置
單線程打開某一串口后,該端口屬性將被設(shè)置成默認(rèn)值,才是可以調(diào)用GetCommState(&dcb)函數(shù)讀取當(dāng)前串口設(shè)備控制塊DCB(Device Control Block),然后根據(jù)具體的需求,修改完DCB后再使用SetCommState(&dcb)函數(shù)將其寫入。
圖2 單線程串口通訊方式流程圖
在進(jìn)行同步讀寫時(shí),應(yīng)注意操作超時(shí),并對(duì)其進(jìn)行特殊控制,以防在通信過(guò)程中由于未知原因?qū)е虏豢深A(yù)測(cè)事件發(fā)生。這類事件包括端口正在接收數(shù)據(jù)突然被中斷或者發(fā)送數(shù)據(jù)突然停止等,這類情況有可能會(huì)造成I/O線程掛起或者線程被無(wú)限阻塞。因此,必須在程序中通過(guò)超時(shí)設(shè)置來(lái)判斷通信是否異常并決定是否作相應(yīng)處理,可以采用COMMTIMEOUTS結(jié)構(gòu)完成設(shè)置后調(diào)用SetCommTimeouts(hComm,&timeouts)將結(jié)果寫入。此外,在設(shè)置緩沖時(shí),緩沖區(qū)容量應(yīng)與通信速率相匹配地進(jìn)行設(shè)置,較大的容量滿足更高的速率需求,但是應(yīng)在設(shè)備驅(qū)動(dòng)程序所能處理的容量范圍限制以下。
2.3 串口讀寫
單線程串口通信方式主要通過(guò)運(yùn)用包括ReadFile() 與WriteFile()等在內(nèi)的API函數(shù)完成串口讀寫。當(dāng)采用異步通信方式時(shí),這兩個(gè)函數(shù)的最后一個(gè)參數(shù)為一非空指針并指向OVERLAPPED結(jié)構(gòu),當(dāng)讀寫函數(shù)的返回值為FALSE時(shí),程序調(diào)用GetLastError()函數(shù);當(dāng)返回值為ERROR_IO_PENDONG時(shí),則表明I/O操作被掛起,表明該操作將轉(zhuǎn)入后臺(tái)并等待執(zhí)行。在操作中可以使用WaitForS-ingleObject()函數(shù)等待結(jié)束信號(hào),同時(shí)可以設(shè)置最長(zhǎng)的等待時(shí)間。
在某成像導(dǎo)引產(chǎn)品測(cè)控系統(tǒng)正常測(cè)試過(guò)程中,要求在圖像采集測(cè)試的同時(shí)保持串口通訊。比如隨時(shí)接收串口數(shù)據(jù),處理相應(yīng)數(shù)據(jù)并發(fā)出控制命令;或者設(shè)備不斷地采集產(chǎn)品數(shù)據(jù),并同時(shí)或者在設(shè)定的某一故障發(fā)生時(shí)向某個(gè)相關(guān)的監(jiān)控窗口及時(shí)發(fā)送通知消息,這些都需要在測(cè)控程序中創(chuàng)建用于監(jiān)控線程的端口。
Win32能夠區(qū)分2種不同類型的線程,分別稱之為用戶界面線程UI(User Interface Thread)和工作者線程(Worker Thread)[3]。2種線程的區(qū)別在于,用戶界面線程可在其他線程執(zhí)行之外響應(yīng)用戶或者系統(tǒng)所產(chǎn)生的事件和信息,其包含信息泵或者信息循環(huán);而工作者線程則沒(méi)有消息機(jī)制與用戶界面,是在后臺(tái)執(zhí)行包括監(jiān)視串口事件在內(nèi)的各種計(jì)算和維護(hù)任務(wù)的。
程序開始某一個(gè)線程是通過(guò)調(diào)用AfxBeginThread()函數(shù)自動(dòng)創(chuàng)建一個(gè)CWinThread對(duì)象的方式進(jìn)行的。圖3給出了多線程實(shí)現(xiàn)串口通訊流程圖[4]。
以下任意某一事件均可以終止線程:①線程函數(shù)返回;②線程函數(shù)的正常退出;③在異常情況下,使用線程的句柄調(diào)用TerminateThread()函數(shù)退出;④線程所屬的進(jìn)程被終止。
在本測(cè)控系統(tǒng)設(shè)計(jì)中,如果串口通訊線程出現(xiàn)錯(cuò)誤,將調(diào)用TerminateThread()來(lái)強(qiáng)行結(jié)束線程。如果通訊正常,函數(shù)將正常返回。
在以后系統(tǒng)擴(kuò)展中,可能會(huì)有多個(gè)串口同時(shí)工作,可以分別對(duì)各個(gè)端口建立監(jiān)控線程來(lái)實(shí)現(xiàn)對(duì)所有端口的同時(shí)監(jiān)控,也可以將此設(shè)計(jì)方式應(yīng)用于分布式網(wǎng)絡(luò)的構(gòu)建中,在此不再詳細(xì)介紹。
Visual C++提供的MSComm控件在完成基于對(duì)話框應(yīng)用程序的串口通信任務(wù)方面,由于具有更為簡(jiǎn)單的編程原理和方法,所以不需要了解具體的細(xì)節(jié)就可以容易實(shí)現(xiàn)。這樣帶來(lái)的負(fù)面作用是因?yàn)橹荒茉趯?duì)話框中使用,MSComm控件編程缺乏靈活性,限制了串口通信的傳輸速率。
單線程串口通信因?yàn)榭梢越⒆远x的通信類,所以具有最高的靈活性,但是其編程復(fù)雜,對(duì)程序員的專業(yè)化程度要求很高,同時(shí)還只適用于監(jiān)控系統(tǒng),而且由于不能同時(shí)發(fā)送和接收數(shù)據(jù),實(shí)時(shí)性不高,功能受到限制。
多線程串口通信方法具有較強(qiáng)的實(shí)時(shí)性,更為容易實(shí)現(xiàn)在多端口間獨(dú)立、準(zhǔn)確的通信,這樣使得該方法得到了更廣泛的應(yīng)用。同時(shí),多線程能夠使程序員方便地榨取到更多的CPU硬件資源,提高整個(gè)系統(tǒng)的通訊效率。
圖3 多線程串口通訊流程圖
另外,當(dāng)系統(tǒng)中存在各種邏輯并發(fā)和物理并發(fā)問(wèn)題時(shí),多線程技術(shù)在解決掉這一類問(wèn)題時(shí)更具有優(yōu)勢(shì),這樣使得軟件的諸如吞吐量、計(jì)算速度和響應(yīng)時(shí)間等各項(xiàng)技術(shù)指標(biāo)均可以得到改善。多線程串口通信技術(shù)可以提高軟件的執(zhí)行效率和運(yùn)行穩(wěn)定性,更合理地利用系統(tǒng)資源,并提高軟件代碼的可讀性。
某成像導(dǎo)引產(chǎn)品測(cè)控系統(tǒng)作為綜合性的復(fù)雜系統(tǒng),數(shù)據(jù)需要通過(guò)多個(gè)串口在不同的子系統(tǒng)端口之間進(jìn)行獨(dú)立傳輸,而且對(duì)測(cè)試實(shí)時(shí)性有很高的要求。經(jīng)過(guò)驗(yàn)證采用多線程編碼實(shí)現(xiàn)串口通訊功能能夠取得很好的效果。整個(gè)測(cè)控系統(tǒng)工作情況良好,在實(shí)際應(yīng)用中要注意每次讀完數(shù)據(jù)要及時(shí)清空緩沖區(qū),否則會(huì)導(dǎo)致緩沖區(qū)堵塞,造成新數(shù)據(jù)無(wú)法接收的情況。
[1]Mark E.Russinovisn.Windows2000內(nèi)部揭秘[M].北京:機(jī)械工業(yè)出版社,2001.
[2]冀榮華,祁力鈞,傅澤田.基于Visual C++的精確定時(shí)技術(shù)與應(yīng)用[J].農(nóng)機(jī)化研究,2007(5):191-193.
[3]張旭東,付強(qiáng),何松華,等.基于PCI接口的多通道高速數(shù)據(jù)采集系統(tǒng)[J].數(shù)據(jù)采集與處理,2000(2):240-244.
[4]王洪訊,趙天云,畢篤彥,等.高速偵察圖像數(shù)據(jù)的獲取和緩沖[J].微電子學(xué)和計(jì)算機(jī),2004(10):82-85.
Implementation and Comparison of Three Serial Communication Methods
Liu PingJia Linlin
(China Airborne Missile Academy,Luoyang Henan 471009)
In the process of general measurement and control equipment,the communication between the host computer and the lower computer is needed to complete internal command down function and the data upload function, the usual practice is to communicate through the serial port.This paper introduced three kinds of commonly used serial communication method,the specific operation steps of each method were analyzed in detail,and their advantages and disadvantages were compared.Practice shows that the use of multi thread serial communication technology in the entire test process can not only meet the needs of product testing tasks,but also in response to serial port events, which solve the problem of logical concurrency and physical concurrency,and meet the requirements of system development.
serial communication;single thread;multithread
TP311.1
A
1003-5168(2017)04-0037-03
2017-03-06
劉平(1981-),男,工程師,研究方向:紅外導(dǎo)引總體技術(shù)。