楊俊 呂建平 徐峰柳
(蘇州大學 電子信息學院,江蘇蘇州 215006)
隨著嵌入式系統和單片機技術的發展,嵌入式以太網的設計越來越受關注。美國貝爾實驗室總裁Arun Netravali等一批科學家曾經作出了預測:未來"將會產生比PC時代多出成百上千倍的瘦服務器和超級嵌入式瘦服務器,這些瘦服務器將與我們這個世界你能想象到的各種物理信息、生物信息相連接,通過Internet自動地、實時地、方便地、簡單地提供給需要這些信息的對象"[1]。因此,研究和設計嵌入式網絡通信將具有十分重要的價值。本文以LPC1768、DP83848CVVP芯片搭建硬件平臺,構建以μC/OS-Ⅱ、LwIP為基礎的軟件系統,在此基礎上實現web服務,從而達到通過瀏覽器對其進行訪問的目的。
μC/OS-Ⅱ是由美國人Jean J.Labrosse編寫的一個公開源代碼的微內核嵌入式實時操作系統,其實時性能和內核的健壯性早已經在大量的實際應用中得到了證實。具有如下特點:①公開源代碼,②移植性好,③可裁剪,④穩定性和可靠性高。
μC/OS-Ⅱ是多任務系統,內核負責管理各個任務,每個任務都有其優先級,μC/OS-Ⅱ最多可以管理64個任務,其每個任務都擁有自己獨立的堆棧。μC/OS-Ⅱ提供了非常豐富的系統服務功能,比如信號量、消息郵箱、消息隊列、事件標志、內存管理和時間管理等,這些功能可以幫助用戶實現非常復雜的應用。
μC/OS-Ⅱ作為操作系統,全部源代碼大約是6000~7000行,文件結構如圖1所示,移植主要是處理與處理器相關的源文件,即 os_cpu_c.c,os_cpu_a.s,os_cpu.h。其中 os_cpu.h 主要包含編譯器相關的數據類型的定義、堆棧類型的定義以及幾個宏定義和函數說明,為了便于移植,須重新定義數據類型,因為不同的編譯器所提供的同一數據類型的數據長度并不相同。os_cpu_c.c文件中主要實現任務堆棧的初始化函數OSTaskStkInit(),任務創建函數通過調用函數OSTaskStkInit()初始化任務堆棧結構。在os_cpu_a.s文件中需要根據具體的硬件處理器實現幾個匯編函數OSstartHighRdy()、OSCtxSw()、OSIntetxsw以及臨界處理函數OS_CPU_SR_Save,OS_CPU_SR_Restore。尤其需要注意的是,由于LPC1768是cortex-m3內核,故OSCtxSw()、OSIntetxsw函數都是通過觸發pendsv(可掛起中斷服務)來完成,它負責μC/OS-II的全部上下文切換。

圖1 μC/OS-Ⅱ系統文件結構
由于LPC1768的以太網控制器只集成了介質訪問控制器(MAC),缺少物理層(PHY),故本系統選用的 PHY芯片為DP83848CVV芯片,由 National Semiconductor公司生產,RJ45接口選用 HanRun公司生產的 HR911105A接口。DP83848CVV、HR911105A與LPC1768的硬件連接示意圖如圖2所示。1768的以太網模塊使用RMII(簡化的媒體獨立接口)協議和片上MIIM(媒體獨立接口管理)串行總線、MDIO(管理數據輸入/輸出)來實現與片外PHY之間的連接,MIMM接口可對PHY寄存器進行訪問。RMII對應的引腳為 ENET_TX_EN、ENET_TXD[1:0]、ENET_RXD_[1:0]、ENET_RX_ER、ENET_CRS、ENET_REF_CLK,接口MIMM對應的引腳為ENET_MDC、ENET_MDIO。需要注意的是使用DP83848CVV芯片的RMII模式必須外接50MHz的有源晶振。

圖2 LPC1768網絡連接示意圖
LwIP是瑞士計算機科學院(Swedish Institute of Computer Science)Adam Dunkels等開發的一套用于嵌入式系統的開放源代碼TCP/IP協議棧。
LwIP的體系結構如圖3所示,由圖可知:LwIP由一些相對獨立的模塊組成,除TCP/IP協議的實現模塊(IP、ICMP、UDP、TCP)外,還包括許多相關的支持模塊,這些支持模塊包括操作系統模擬層、緩沖與內存管理模塊、網絡接口函數以及一組Intemct校驗和計算函數、API接口函數。

圖3 LwIP協議棧體系結構
LwIP的操作系統模擬層(sys_arch)是底層操作系統和LwIP之間的一個接口,為LwIP提供信號量和郵箱2種進程間通信方式。當用戶移植LwIP時,只需修改這個接口即可。主要實現以下幾種類型的函數,分別是信號量操作函數、郵箱操作函數、臨界保護函數、sys_thread_new()函數、sys_arch_timeouts()函數。由于μC/OS-II提供了創建任務函數、臨界保護函數以及豐富的信號量和郵箱操作函數,所以只需對這些函數稍加修改,便可實現LwIP操作系統模擬層的函數。
TCP屬于傳輸層協議,它為應用層提供可靠的字節流服務,建立在TCP協議之上的應用層協議有 HTTP等。本文采用的是HTTP協議。基本的TCP處理過程被分割為6個功能函數來實現:tcp_input()、tcp_process()、tcp_receive()、tcp_write、tcp_enqueue、tcp_output。實現框圖如圖4所示。

圖4 TCP層通信流程
主線程tcpip_thread是一個主控循環,底層接口函數通過tcpip_thread和lwip的內部函數進行通信,比如在進行tcp傳輸時,底層接口函數通過傳遞郵箱mbox的方式進入到tcpip_thread,然后在該函數中,進入tcp層的tcpip_input函數中,實現tcp層的傳輸。
LwIP API專為LwIP設計,所以它可以充分利用LwIP的內部結構以實現其設計目標,不需要在應用程序和協議棧之間復制數據,因此應用程序可以巧妙地直接處理內部緩沖區。LwIP API使用2種數據類型,分別為:①、netbuf,描述網絡緩存的數據類型,對應的函數為netbuf_new()、netbuf_delete()、netbuf_alloc()等;②、netconn,描述網絡連接的數據類型,對應的函數為netconn_new,netconn_delete()、netconn_bind,netconn_connect()、netconn_accept()等。LwIP的上層應用程序是基于LwIP API編寫的。
超文本傳送協議(HTTP)是實現www的應用層協議,HTTP負責web服務器與web客戶(瀏覽器)之間的實際超文本文檔的傳送。
網頁就是一個HTML語法格式的純文本文檔,HTML是網絡所基于的標準的格式化語言。HTML文檔與網頁在瀏覽器的顯示并不相同,瀏覽器顯示的是對HTML文檔的解釋。
一個HTTP事物包含一個HTTP請求和一個HTTP應答報文,這兩種報文都遵循一個通用結構,被稱為HTTP報文格式,如圖5所示。由圖可知,請求行是HTTP請求報文的起始行,用于指示命令或客戶要求服務器執行的動作、方法、要引用的資源以及客戶使用的HTTP版本。該行格式如下:<IMETHOD> <I請求的URI> <IHTTP版本>,其中方法(method)告知服務器要執行的動作。方法的種類有"get"、"post"、"HEAD"等。本系統實現的是利用"get"請求向服務器提取網頁。

圖5 HTTP報文格式
本系統的實現是通過在μC/OS-Ⅱ下建立的4個任務完成,分別是:①起始任務task_start(),優先級為0,用于創建其他3個任務并進行LwIP、EMAC的初始化,執行之后被掛起,永不再執行;② 底層硬件接收任務ethernetif_input(),優先級為4;③ tcpip_thread()任務,優先級為1;④ http_server任務,優先級為10。任務②、③、④依靠μC/OS-Ⅱ下的信號量sem和郵箱mbox進入就緒態,否則被掛起。如圖6所示:

圖6 ethernetif_input、tcpip_thread、http_server通信流程
當本系統上電時,由于此時瀏覽器并沒有發送數據,網絡接口沒有數據,故沒用中斷發生,sem和mbox無法投遞,所以此時這3個任務完全由μC/OS-II內核的系統定時器中斷依據優先級而發生切換,程序流程如圖7。tcpip_thread的優先級最高,tcpip_thread首先被運行,但由于沒有郵箱被投遞,故該任務隨之被掛起,在內核調度的作用下,ethernetif_input()任務開始運行,同理,sem也沒有投遞,隨之掛起,然后進入到http_server任務,隨之也被掛起,此時系統進入空閑任務,等待中斷的發生,即等待瀏覽器的訪問。

圖7 未發生中斷時,系統程序流程圖
web服務器的實現:
http_server任務是基于lwip API編程的,程序流程如圖8所示,由圖可以看出,在進入到netconn_accept函數時,等待郵箱accept_mbox的到來,否則被掛起。accept_mbox郵箱是在瀏覽器和服務器三次握手之后由accept_function()投遞,此時程序進入netconn_recv()函數,等待recv_mbox的到來。recv_mbox的投遞發生在數據被傳至tcp層時,由 recv_tcp函數投遞的。一旦 recv_mbox被 post,則進入到netbuf_data()函數,用于獲得接收數據指針,這個指針指向netbuf的第一個數據片段且這個片段包含HTTP請求,若是"get"請求,則發送網頁,若不是則關閉連接,等待下一個連接到來。

圖8 http_server任務流程圖
本文詳細介紹了利用LPC1768以太網控制模塊,在μC/OS-II操作系統的基礎上,移植LwIP協議棧,搭建嵌入式web服務器的過程。由于搭建的web服務器具有網頁數據動態顯示功能,可以滿足一般的嵌入式設備進行遠程監控,所以本系統實現對嵌入式設備的遠程檢測和控制具有很好的借鑒意義。
[1] 李紀栓.嵌入式INTERNET接入模塊的設計[J].機械管理開發,2006,5.
[2] 焦海波,劉健康.嵌入式網絡系統設計-基于Atmel ARM7系列[M].北京:北京航空航天大學出版社,2008.4.
[3] (美)JEAN J.LABROSSE.嵌入式實時操作系統μC/OS-II(第2版)[M].邵貝貝譯.北京:北京航空航天大學出版社,2003.5.
[4] 鄭巨明,張和生,賈利民等.基于μC/OS-II和LwIP的嵌入式以太網接口設計[J].計算機測量與控制,2009,17(11).
[5] 熊海泉.μ C/OS II下LwIP協議的移植實現[J].科技廣場,2005.2.
[6] 蘇義鑫,毛曉磊.uIP在S3C44B0X上的移植研究及webserver實現[J].微型電腦應用,2008,24(2).