IPv6的嵌入式設(shè)計與實現(xiàn)
(3)接收函數(shù)
在接收數(shù)據(jù)時,網(wǎng)絡(luò)接口層接收函數(shù)Rec_Ethernet_Packed( )被下層以太網(wǎng)驅(qū)動程序的數(shù)據(jù)接收函數(shù)Rec_Packet()調(diào)用。Rec_Ethernet_Packed()的作用根據(jù)以太類型值,調(diào)用不同的函數(shù),同時去除以太幀的頭部,將正確的IPv6 數(shù)據(jù)從NIC 的數(shù)據(jù)緩沖區(qū)內(nèi)發(fā)送到ARM 的接收緩沖區(qū)內(nèi)。Rec_Packet()函數(shù)通過讀取RTL8019AS的當(dāng)前寄存器CURR(寫寄存器)和邊界寄存器BNRY(讀寄存器)的值來確定是否有新數(shù)據(jù)的到來,若有新數(shù)據(jù)到來,則設(shè)置數(shù)據(jù)地址和數(shù)據(jù)長度,然后啟動遠(yuǎn)程DMA 將接收緩沖環(huán)中的以太網(wǎng)幀送交給上層。
2 嵌入式TCP/IPv6 協(xié)議棧的實現(xiàn)
2.1 嵌入式TCP/IPv6 協(xié)議棧處理流程
如圖1 所示,嵌入式TCP/IPv6 協(xié)議接收數(shù)據(jù)包的過程就是解析數(shù)據(jù)包的過程。首先由底層處理函數(shù)解析數(shù)據(jù)包,根據(jù)類型,將去掉幀首部的數(shù)據(jù)包分配到緩沖區(qū)BUF 中,接著由IP 協(xié)議處理程序繼續(xù)解析。IP 協(xié)議處理程序?qū)?shù)據(jù)包解析后,將數(shù)據(jù)交給TCP 或ICMPv6 協(xié)議處理程序。嵌入式TCP/IPv6 協(xié)議棧發(fā)送數(shù)據(jù)包的過程是封裝數(shù)據(jù)包的過程,數(shù)據(jù)經(jīng)過某層協(xié)議的處理,就會在數(shù)據(jù)包首部增加某種格式的首部。本文引用地址:http://cafeforensic.com/article/152302.htm
2.2 軟件實現(xiàn)
首先做如下類型定義:
#define PROTO_ICMP 58 #define PROTO_TCP 6 #define ICMP_ECHO_REPLY 129 #define ICMP_ECHO 128 芯片接收到數(shù)據(jù)包后,放入緩沖區(qū)BUF 中交由上層協(xié)議處理。然后對數(shù)據(jù)包進(jìn)行判斷。過程下:for(c=0;c8;c++)
if(BUF->destipaddr[c] != hostaddr[c])
{ STAT(++stat.ip.drop);
goto drop; } 接收數(shù)據(jù)包后,檢查下一個報頭中的協(xié)議類型,如果是TCP 或ICMP 協(xié)議,則分別轉(zhuǎn)向其處理程序,否則丟棄。
if(BUF->proto == PROTO_TCP) /* Check for TCP packet.If so,jump to the tcp_input label.*/
goto tcp_input;
if(BUF->proto = PROTO_ICMP) /*Check for ICMP packet.If so,jump to the icmp_input label.*/ goto icmp_input; goto drop;
3 IPv6 在ARM 中的移植
IPv6協(xié)議棧在設(shè)計時就考慮到了移植問題,已把所有與硬件、OS、編譯器相關(guān)的部分獨立出來[4]。因此,IPv6 在本文研究的系統(tǒng)中的移植就是針對LPC2210 硬件平臺、uC/OS-II 操作系統(tǒng)和ADS1.2 的編譯器對其進(jìn)行相應(yīng)的修改。
1 數(shù)據(jù)類型定義
IPv6 的數(shù)據(jù)定義應(yīng)該與uC/OS-II 定義的數(shù)據(jù)長度類型是一致的。
typedef unsigned char uint8;/* 無符號8 位整型變量*/
typedef signed char int8;/* 有符號8 位整型變量*/
typedef unsigned short uintl6;/* 無符號16 位整型變量*/
typedef signed short int16;/* 有符號16 位整型變量*/
typedef unsigned int uint32;/* 無符號32 位整型變量*/
typedef signed int int32;/*有符號32位整型變量*/
typedef float fp32;/* 單精度浮點數(shù)(32 位長度)*/
typedef double fp64;/* 雙精度浮點數(shù)(64 位長度)*/
2 操作系統(tǒng)相關(guān)部分
(1)信號量
IPv6 中需要使用信號量進(jìn)行同步。信號量實際上是一種約定機制,在多任務(wù)內(nèi)核中普遍使用。信號像是一把鑰匙,任務(wù)要運行下去,得先拿到這把鑰匙。如果信號已被別的任務(wù)占用,該任務(wù)被掛起,直到信號被當(dāng)前使用者釋放。一般地說,對信號量只能實施三種操作:初始化(也可稱作建立)、等信號(也可稱作掛起)、給信號或發(fā)信號。信號量初始化時要給信號量賦初值,等待信號量的任務(wù)表應(yīng)清為空。想要得到信號量的任務(wù)執(zhí)行等待操作。如果該信號量有效(即信號量值大于0),則信號量值減1,任務(wù)得以繼續(xù)運行。如果信號量的值為0,等待信號量的任務(wù)就被列入等待信號量任務(wù)表。多數(shù)內(nèi)核允許用戶定義等待超時,如果等待時間超過了某一設(shè)定值時,該信號量還是無效,則等待信號量的任務(wù)進(jìn)入就緒態(tài)準(zhǔn)備運行,并返回出錯代碼(指出發(fā)生了等待超時錯誤)。任務(wù)以發(fā)信號操作釋放信號量。如果沒有任務(wù)在等待信號量,信號量的值僅僅是簡單地加1。如果有任務(wù)在等待該信號量,那么就會有一個任務(wù)進(jìn)入就緒態(tài),信號量的值也就不加1。于是,鑰匙給了等待信號量的諸任務(wù)中的等待信號量任務(wù)中優(yōu)先級最高的任務(wù)、信號量處理函數(shù):
OSSemCreate / * 創(chuàng)建一個信號量* /
OSSemDel()/* 刪除信號量*/
OSSemPend()/* 等待信號量*/
OSSemPost()/* 發(fā)送信號量*/
評論