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