徐良,陳向東
(西南交通大學信息科學與技術學院,成都610031)
隨著物聯網的蓬勃發展,越來越多的傳統本地設備或網絡有接入計算機網絡的需求,而這些傳統設備一般都是不具備網絡接口的非IP設備。最常用的通信接口是串口,不能直接接入計算機網絡,在不改變這些原有設備的基礎上,使用串口/以太網網關來接入計算機網絡的方式不失為一種比較好的解決方案。
基于此需求,設計和實現了串口/以太網網關,網絡結構如圖1所示。實現了非IP設備與IP設備間的數據通信,并特別考慮了串口通信的可靠性,從軟件和硬件兩方面詳細討論了保證串口通信可靠性的方法。IP端通信的可靠性由TCP/IP協議保證,這樣就保證了串口設備與IP設備間通信的可靠性。

圖1 網絡結構
網關實現串口設備和以太網之間的協議轉換,具體表現為幀格式的轉換,可表示為:
Socket幀?凈荷數據?串口幀
其中Socket(套接字)幀和串口幀都是為實現網關可靠通信而自定義格式的幀,凈荷數據為真正需要傳送的應用數據。
網關的數據通信可分為兩部分:網絡端和串口端,要保證整個網關通信的可靠性,那么就要分別保證網絡端和串口端通信的可靠性。
在網絡端,網關使用了流式套接字。流式套接字使用TCP協議,而TCP協議是面向連接的,保證了數據傳輸的正確性和順序性。所以,流式的套接字可以提供可靠的、面向連接的通信流。但是,流式數據對應用來說不易使用,所以Socket數據傳送都是基于幀格式的。
在串口端,串口數據傳送本質上也是字節流式的,在硬件層次是不可靠的,而且不能保證數據的完整性,需要在軟件上有一些其他機制來保證可靠性。所以,網關串口的數據傳送同樣基于幀格式,并且使用了接收確認、超時重發、差錯校驗等機制來保證可靠性。
圖2為網關工作時的數據流示意圖。圖中3個帶箭頭的橢圓表示3個線程,圖中未畫出建立Socket連接、串口初始化和線程啟動等過程。

圖2 網關數據流示意圖
串口數據傳送的幀格式如下:

字節數1 1 1 1可變1 1字段SFD Seq.Type LEN Data FCS EFD
其中各個字段的意義如下:
◆SFD:幀首定界符;
◆EFD:幀尾定界符,SFD和EFD為確定的特定值;
◆Seq.:幀序號;
◆Type:幀類型,其值見表1;
◆LEN:Data字段的字節數;
◆Data:實際要傳送的數據;
◆FCS:幀校驗,是一個簡單校驗,為Seq.至Data字段中所有字節按位異或運算的結果。

表1 串口幀類型
1.2.1 串口發送
串口發送隊列示意圖如圖3所示。網關使用FIFO(先入先出)隊列緩沖發送幀,包括待發送隊列和待確認隊列兩個隊列,每個隊列為一個雙向循環鏈表,節點從尾部插入,頭部讀出。

圖3 串口發送隊列示意圖
當有數據需要從串口發送時,首先將要發送的數據按幀格式加上一些附加的字段組成一個完整的幀,然后插入待發送隊列尾。插入待發送隊列的幀并不一定會被立即發送,但只要待發送隊列中緩沖有需要發送的幀,串口就會從隊列頭逐個的讀取待發送幀以中斷的方式發送,直到待發送隊列為空。
每一幀發送完畢后,如果是確認幀,便會被立即從待發送隊列中刪除并釋放掉內存,該幀的發送過程結束;如果是非確認幀,即數據幀或命令幀,那么該幀不會被立即釋放,而是從待發送隊列刪除而插入待確認隊列尾,等待串口另一端的設備發送對應的確認幀。
若在超時時間內收到對應的確認幀,則將該幀從待確認隊列刪除釋放,該幀的發送過程結束;若等待超時,則將該幀從待確認刪除并重新插入待發送隊列尾,以重發此幀。當然有重發次數限制,若達到了最大重發次數仍然未收到對應的確認幀,則丟棄該幀,該幀的發送過程結束。
1.2.2 串口接收
串口接收使用中斷方式,從串口接收到的字節數據并不直接處理,而是先存入一個環形緩沖,環形緩沖示意圖如圖4所示。從頭偏移處寫入,從尾偏移處讀出,每寫入或讀出一字節頭或尾都將模遞增,且頭偏移處為空,尾偏移處為滿。
只要串口接收到數據,就將其從頭偏移處寫入串口的環形緩沖。如果緩沖滿了,則用新數據覆蓋未處理的舊數據。
在將一個字節數據寫入緩沖的同時,判斷其是否等于幀結束定界符EFD,如果等于,則表示緩沖中可能存在一個完整的幀(只是可能,并不能完全確定,因為一個普通的字節數據完全有可能正好等于EFD),此時便可從環形緩沖中按幀格式解析數據。若解析到完整的幀,則做相應的處理:首先,根據幀中FCS字段做差錯校驗,如果校驗正確,則從串口回送一個同序號的確認幀;然后從幀中取出凈荷數據從Socket發送。

圖4 環形緩沖示意圖
從緩沖中解析數據的過程簡述如下:從環形緩沖的尾偏移處開始讀字節數據,查驗是否等于幀開始定界符SFD,若不等于則丟棄并繼續讀下一字節,若等于則向后偏移讀取長度域LEN,根據長度值,便能確定幀結束定界符EFD的位置。查驗此位置的字節數據,若不等于EFD,則認為之前等于SFD的字節只是個普通數據,并不是幀開始定界符,將其丟棄并繼續讀取查驗下一字節;若等于EFD,則認為SFD到EFD之間為一個完整的幀。
Socket數據傳送的幀格式如下:

字節數1 1可變1 SFD LEN Data EFD字段
相比串口幀格式,少了Seq.、Type和FCS字段。這三個字段在串口數據傳送中是用來保證可靠性的,而網關使用TCP Socket,下層的TCP協議會保證通信的可靠性,應用層只需要保證數據的完整性,所以不需要這些字段。其他字段相同,意義也分別相同。
1.3.1 Socket發送
Socket接收過程同串口接收類似,接收的數據并不直接處理,而是先存入環形緩沖。然后,按Socket幀格式,解析環形緩沖中的數據。解析到的數據幀插入串口發送隊列,從串口轉發。
1.3.2 Socket接收
Socket發送相比串口發送操作更簡單,因為下層的TCP協議會保證通信的可靠性,所以不需要再另外實現確認、重發等機制,發送隊列中只需要一個待發送隊列即可,不需要待確認隊列。而且在具體實現中,并沒有真的構造一個Socket發送隊列,而是利用了操作系統提供的線程間通信機制中的郵箱通信方式,需要從Socket發送數據時,只需將數據的首地址以郵件的方式發送到Socket發送線程指定的郵箱中。
網關軟硬件平臺包括操作系統RT-Thread和ARM9開發板Mini2440。
2.1.1 RT-Thread實時操作系統[1-3]
為實現網關,選用了實時操作系統RT-Thread。RTThread是一款國內的開源實時操作系統,并且商業許可證非常寬松,由國內一些專業開發人員開發、維護。RTThread不僅是一款高效、穩定的實時核心,也是一套面向嵌入式系統的軟件平臺,覆蓋了全搶占的實時操作系統內核小巧的文件系統、輕型的TCP/IP協議棧以及輕型的圖形用戶界面。
圖5是RT-Thread及外圍組件的基本框架圖。RTThread的使用范圍極為靈活,可以從資源極度緊張的小型系統到帶內存管理單元、網絡功能的基本計算單元。RT-Thread有著高度可配置、易裁減、可擴展性好和可靠性高等特點,適用于嵌入式實時系統。

圖5 RT-Thread基本框架圖
2.1.2 Mini2440開發板
硬件平臺使用了Mini2440開發板,Mini2440是一款ARM9開發板,微處理器采用三星公司的S3C2440芯片,具有64MB SDRAM、128MB/256MB/1GB大小可選的NAND Flash和2MB NOR Flash,外設包括1個100M以太網RJ-45口(采用DM9000網卡)和3個串口等。
2.2.1 軟件相關
如圖2所示,系統使用了3個線程:串口接收線程、Socket發送線程和Socket接收線程,下面對這3個線程作具體介紹:
①串口接收線程。以阻塞的方式接收“UART_RX_IRQ_EVENT”事件,接收到此事件后,從串口環形接收緩沖中解析串口幀,當有數據幀需要向以太網發送時,便將該數據幀的首地址以郵件的方式給Socket發送線程。而在RT-Thread中,郵件的存儲方式本質是雙向循環隊列。
②Socket發送線程。以阻塞的方式接收來自串口接收線程的指針郵件,接收到此類郵件后,Socket發送線程將指針指向的數據封裝成Socket幀發送。
③Socket接收線程。用于從以太網接收數據,并緩存解析數據幀,調用串口發送接口函數,將收到的數據幀封裝成串口幀并插入串口發送隊列。
串口收/發工作于中斷方式,可以連續發送串口發送隊列中緩存的待發送幀和從串口接收字節數據并寫入串口的環形接收緩存。在接收到等于EFD的字節時,向串口接收線程發送一個“UART_RX_IRQ_EVENT”事件,通知串口接收線程環形緩存中可能存在一個完整的幀。
串口幀發送完畢后等待確認幀的時間計時使用了RT-Thread提供的定時器,并且在定時器的超時函數中處理幀重發問題。
在軟件實現過程中遇到了一個問題:在RT-Thread操作系統的中斷程序中不能申請和釋放動態內存,而串口中斷發送程序在發送完一個幀后,如果該幀是確認幀或非確認幀但達到了最大發送次數,那么需要從待發送隊列刪除該幀并釋放對應的動態內存。這就存在矛盾,系統不能提供中斷程序釋放內存的功能,但實際應用又需要此功能。
為此,程序中專門設置了一個刪除隊列,當中斷程序需要釋放發送幀時,將對應幀插入刪除隊列,并向串口接收線程發送一個刪除事件“UART_TX_DEL_EVENT”,在串口接收線程中接收到此事件后再來釋放隊列中的幀,這就避免了在串口發送中斷程序中直接釋放動態內存。
2.2.2 硬件相關
在硬件方面,為提高串口通信的可靠性,也做了相應處理。
S3C2440微處理器的串口具有兩種工作模式[4]:非FIFO模式和FIFO模式。在FIFO模式中,串口發送和接收分別具有64字節的硬件FIFO緩沖,使用硬件緩沖,能顯著地減少串口發送和接收中斷產生的次數,進而減小正常程序被中斷的頻率,提高系統性能。并且使用接收FIFO后,在處理器不能及時跳轉到串口接收中斷程序的情況下,由于硬件FIFO的存在,使得串口數據丟失的可能性減小。所以,網關中S3C2440微處理器的串口使用了FIFO模式。
另外,S3C2440微處理器的串口還具有硬件自動流控制功能[3],當與網關相連的串口設備也具有硬件自動流控制功能時,開啟此功能。在開啟此功能的情況下,當通信的某一端不能及時讀取接收緩沖中的數據時,硬件自動流控制能自動暫停另一端串口的數據發送,以防止數據的丟失。
在網關的軟件實現中,確認機制的開關、確認超時時間、重發次數、隊列容量、緩沖的大小、串口的FIFO設置和硬件流控制的開關等都是可配置的,針對不同的應用可以非常容易地做出合適的裁剪和設置。
目前該網關被用于一個無線體溫監測項目,以連接本地無線傳感網絡和遠程數據庫服務器,實現本地設備對遠程數據庫服務器的訪問,通過實際運行實驗,網關能很好地實現本文講述的功能。當然,網關仍然有不盡完善之處,比如對有些公共資源的訪問沒有提供競爭保護機制,可能會影響網關運行的穩定性和可靠性,有待今后進一步完善。
[1]RT-Thread工作室.RT-Thread實時操作系統編程指南,2010.
[2]邱祎.嵌入式實時操作系統RT-Thread的設計與實現[D].成都:電子科技大學,2007.
[3]Samsung Electronics.S3C2440A32-BIT CMOS MICROCONTROLLER USER'S MANUAL,2004.