ENC28J60是Microchip公司生產(chǎn)的28引腳獨立以太網(wǎng)控制器,它內(nèi)置了10 Mbps以太網(wǎng)物理層器件和介質(zhì)訪問控制器,符合IEEE 802.3標準,特別適合于嵌入式設備的入網(wǎng)解決方案。ENC28J60通過SPI接口與控制器LPC2138交互,網(wǎng)卡芯片接口電路如圖3所示。SO、SI、SCK為SPI接口的3條總線,CS為ENC28J60的片選信號,中斷信號INT和WOL分別連接到主控制器的EINT3和EINT1上。芯片ENC28J60的2條差分接收引腳TPIN和2條差分發(fā)送引腳TPOUT外接在一個1:1脈沖變壓器上,脈沖變壓器輸出接至網(wǎng)口座上。

?
圖3 網(wǎng)卡芯片接口電路
2 軟件設計
網(wǎng)絡讀寫器軟件設計包括μC/OSII移植、LwIP協(xié)議棧移植、網(wǎng)卡驅(qū)動程序和上層應用程序的編寫4個部分。軟件設計整體框架如圖4所示。

?
圖4 軟件設計整體框架
2.1 μC/OSII移植
操作系統(tǒng)移植是LwIP協(xié)議棧移植和應用程序編寫的基礎[3],其在LPC2138上的移植內(nèi)容包括:
?、?完成操作系統(tǒng)所需的基本配置和數(shù)據(jù)類型定義、開關(guān)中斷函數(shù)文件OS_CPU.H的編寫。
?、?在文件OS_CPU.C完成堆棧初始化函數(shù)OSTaskStkInit()函數(shù),并根據(jù)自身需求編寫相關(guān)Hook函數(shù)。
?、?利用文件OS_CPU_A.S完成啟動最高優(yōu)先級任務的函數(shù)OSStartHighRdy、任務切換函數(shù)OSCtxSw、中斷級任務切換函數(shù)OSIntCtxSw、系統(tǒng)時鐘中斷服務函數(shù)OSTickISR的編寫。
?、?初始化定時器0,為系統(tǒng)提供時鐘。
2.2 LwIP協(xié)議棧移植
① 完成LwIP協(xié)議內(nèi)部使用的數(shù)據(jù)類型的定義,如u8_t、s8_t、u16_t、u32_t等。這樣使得協(xié)議棧內(nèi)部使用的數(shù)據(jù)類型不再受移植平臺處理器和編譯器的影響,增強了協(xié)議棧的可移植性。移植時,根據(jù)編譯器和移植平臺事先定義好這些數(shù)據(jù)類型,定義如下:
typedef unsignedcharu8_t;//定義8位無符號整數(shù)
typedef signedchars8_t;//定義8位帶符號整數(shù)
typedef unsignedshortu16_t;//定義16位無符號整數(shù)
typedef signedshorts16_t;//定義16位帶符號整數(shù)
typedef unsignedintu32_t;//定義32位無符號整數(shù)
typedef signedints32_t;//定義32位帶符號整數(shù)
?、?定義臨界區(qū)保護函數(shù)用于開關(guān)中斷,定義結(jié)構(gòu)體封裝宏以避免編譯器地址自動對齊。LwIP的實現(xiàn)基于這樣一種機制,即上層協(xié)議已經(jīng)明確知道了下層所傳上來的數(shù)據(jù)的結(jié)構(gòu)特點,上層直接使用地址計算得到想要的數(shù)據(jù),而避免了數(shù)據(jù)遞交時的復制與緩沖。所以需定義結(jié)構(gòu)體封裝宏,禁止編譯器的地址自動對齊以防止數(shù)據(jù)結(jié)構(gòu)被打亂。
③ 實現(xiàn)與信號量和郵箱操作相關(guān)的函數(shù)[5],比如建立、刪除、等待、釋放等。LwIP使用郵箱和信號量來實現(xiàn)上層應用程序與協(xié)議棧間、下層硬件驅(qū)動與協(xié)議棧間的信息交互。這些函數(shù)可以通過調(diào)用μC/OSII提供的信號量、郵箱函數(shù)來實現(xiàn)。
④ 實現(xiàn)一個與等待超時相關(guān)的函數(shù)sys_arch_timeouts.該函數(shù)能夠返回當前協(xié)議棧超時事件鏈表的首地址。在初始化LwIP進程時,會同時初始化一些超時事件,如ARP超時、TCP超時等,當某些事件等待超時后,協(xié)議棧會自動調(diào)用一些超時處理函數(shù)作相關(guān)處理,以滿足TCP/IP協(xié)議棧的需求。
?、?實現(xiàn)創(chuàng)建一個進程的函數(shù),可以通過操作系統(tǒng)提供的OSTaskCreate函數(shù)完成。
2.3 網(wǎng)卡驅(qū)動程序編寫
網(wǎng)卡芯片生產(chǎn)廠商一般都提供了豐富的驅(qū)動函數(shù),對這些接口函數(shù)進行相應的封裝,將接收到的數(shù)據(jù)包封裝為LwIP協(xié)議棧熟悉的數(shù)據(jù)結(jié)構(gòu),將發(fā)送的數(shù)據(jù)包封裝為芯片熟悉的數(shù)據(jù)結(jié)構(gòu)。發(fā)送數(shù)據(jù)包和接收數(shù)據(jù)包的函數(shù)需要被實現(xiàn)。芯片與控制器LPC2138接口定義如下:
#defineSPI_SCK(0x01﹤﹤4) //P0.4
#defineSPI_MISO(0x01﹤﹤5) //P0.5
#defineSPI_MOSI(0x01﹤﹤6) //P0.6
#defineENC28J60_CS(0x01﹤﹤8) //P0.8
#defineENC28J60_INT(0x01﹤﹤9) //P0.9
評論