當(dāng)前位置:首頁 > 單片機(jī) > 單片機(jī)
[導(dǎo)讀]Internet實(shí)現(xiàn)了全球范圍內(nèi)計(jì)算機(jī)網(wǎng)絡(luò)的互連,不同主機(jī)之間必須遵循相同的網(wǎng)絡(luò)協(xié)議才能彼此通信。TCP/IP協(xié)議作為一種網(wǎng)絡(luò)互聯(lián)協(xié)議,在Internet中得到了最廣泛的支持以及應(yīng)用。筆者此處就輕量級TCP/IP協(xié)議Lwip的移植作

Internet實(shí)現(xiàn)了全球范圍內(nèi)計(jì)算機(jī)網(wǎng)絡(luò)的互連,不同主機(jī)之間必須遵循相同的網(wǎng)絡(luò)協(xié)議才能彼此通信。TCP/IP協(xié)議作為一種網(wǎng)絡(luò)互聯(lián)協(xié)議,在Internet中得到了最廣泛的支持以及應(yīng)用。筆者此處就輕量級TCP/IP協(xié)議Lwip的移植作一個(gè)簡單的介紹。

1. TCP/IP協(xié)議概述

TCP/IP協(xié)議是Internet上使用最廣泛的通信協(xié)議,其實(shí)際上是一個(gè)協(xié)議簇,其中TCP協(xié)議和IP協(xié)議是其中兩個(gè)最重要的協(xié)議。

TCP/IP協(xié)議采用4層層級結(jié)構(gòu):應(yīng)用層、運(yùn)輸層、網(wǎng)絡(luò)層、鏈路層。相應(yīng)的層級除了能夠向上一層提供服務(wù),還需要使用下一層所提供的服務(wù)。

1.1. 鏈路層

數(shù)據(jù)鏈路層將網(wǎng)絡(luò)層交下來的IP數(shù)據(jù)報(bào)組裝成幀,在兩個(gè)相鄰結(jié)點(diǎn)間的鏈路上透明傳送以幀為單位的數(shù)據(jù),另一結(jié)點(diǎn)若收到無差錯(cuò)的幀,則從收到的幀中提取出IP數(shù)據(jù)報(bào)上交上一層,否則丟棄此包。這一層級幀格式通常采用Ethernet V2,有效的MAC幀長度為64~1518字節(jié),通常由網(wǎng)絡(luò)適配器實(shí)現(xiàn)這一層級。

1.2. 網(wǎng)絡(luò)層

網(wǎng)絡(luò)層把運(yùn)輸層產(chǎn)生的報(bào)文段或用戶數(shù)據(jù)報(bào)封裝成分組或包進(jìn)行傳送,由于網(wǎng)絡(luò)層使用無連接的網(wǎng)際協(xié)議IP,因此,分組也稱為IP數(shù)據(jù)報(bào),并且是不可靠的。除了IP協(xié)議,網(wǎng)絡(luò)層還需配套使用以下幾個(gè)協(xié)議:地址解析協(xié)議ARP、逆地址解析協(xié)議RARP、因特網(wǎng)控制報(bào)文協(xié)議ICMP、因特網(wǎng)組管理協(xié)議IGMP。

1.3. 運(yùn)輸層

運(yùn)輸層向上面的應(yīng)用層提供通信服務(wù),具有復(fù)用和分用的功能。復(fù)用就是多個(gè)應(yīng)用層進(jìn)程可同時(shí)使用運(yùn)輸層的服務(wù),分用則為運(yùn)輸層可以把收到的數(shù)據(jù)分別交付上面應(yīng)用層中相應(yīng)的進(jìn)程。這一層級有兩個(gè)不同的協(xié)議:傳輸控制協(xié)議TCP和用戶數(shù)據(jù)報(bào)協(xié)議UDP。TCP提供面向連接的服務(wù),數(shù)據(jù)傳輸單位為報(bào)文段,能夠保證提供可靠的交付。其傳輸數(shù)據(jù)前必須先建立連接,結(jié)束傳輸后要釋放連接,不提供廣播或多播服務(wù)。UDP傳輸數(shù)據(jù)前不需要建立連接,數(shù)據(jù)傳輸單位為用戶數(shù)據(jù)報(bào),不保證提供可靠的交付。運(yùn)輸層接收到UDP報(bào)文后,不需要給出任何確認(rèn),可以實(shí)現(xiàn)廣播或多播服務(wù)。

1.4. 應(yīng)用層

應(yīng)用層根據(jù)運(yùn)輸層提供的服務(wù),實(shí)現(xiàn)不同主機(jī)中多個(gè)應(yīng)用進(jìn)程之間的通信和協(xié)同工作,由實(shí)際的應(yīng)用規(guī)劃應(yīng)用進(jìn)程在通信時(shí)所遵循的協(xié)議。在Internet中有很多標(biāo)準(zhǔn)的應(yīng)用層協(xié)議如:域名系統(tǒng)DNS、文件傳輸協(xié)議FTP、超文本傳輸協(xié)議HTTP、遠(yuǎn)程終端協(xié)議TELNET、動(dòng)態(tài)主機(jī)配置協(xié)議DHCP、簡單網(wǎng)絡(luò)管理協(xié)議SNMP等等。

2. Lwip概述

Lwip是瑞典計(jì)算機(jī)科學(xué)院(SICS)的Adam Dunkels開發(fā)的一個(gè)小型開源TCP/IP協(xié)議棧。作為輕量級TCP/IP協(xié)議,Lwip支持有操作系統(tǒng)以及無操作系統(tǒng)運(yùn)行,其在保持TCP/IP協(xié)議主要功能的基礎(chǔ)上,減少對RAM、ROM的占用,非常適合于嵌入式系統(tǒng)使用。

3. Lwip移植

對于一個(gè)可移植的開源協(xié)議棧,移植部分往往分成體系結(jié)構(gòu)相關(guān)、操作系統(tǒng)相關(guān)、驅(qū)動(dòng)接口相關(guān)這幾個(gè)部分。此處以Lwip-1.4.1版本為例說明移植的相關(guān)代碼文件。

3.1. 體系結(jié)構(gòu)相關(guān)3.1.1. cc.h

在cc.h中需實(shí)現(xiàn)cpu以及編譯器相關(guān)的定義,Lwip為了可移植,使用了自身的數(shù)據(jù)類型,需根據(jù)使用的cpu以及編譯器進(jìn)行定義。網(wǎng)絡(luò)字節(jié)序使用大端格式,并且其數(shù)據(jù)結(jié)構(gòu)需嚴(yán)格按照字節(jié)對齊,此處定義cpu的字節(jié)序以及編譯器字節(jié)對齊宏等。

#ifndef __ARCH_CC_H__

#define __ARCH_CC_H__

#include /* printf, fflush, FILE */

#include /* abort */

#define LWIP_PROVIDE_ERRNO

/* Define platform endianness (might already bedefined) */

#define BYTE_ORDER LITTLE_ENDIAN

/* Define generic types used in lwIP */

typedef unsignedchar u8_t;

typedef signedchar s8_t;

typedef unsignedshort u16_t;

typedef signedshort s16_t;

typedef unsignedlong u32_t;

typedef signedlong s32_t;

typedef u32_t mem_ptr_t;

typedef u32_t sys_prot_t;

/* Define (sn)printf formatters for these lwIP types*/

#define U16_F "hu"

#define S16_F "hd"

#define X16_F "hx"

#define U32_F "lu"

#define S32_F "ld"

#define X32_F "lx"

/* Compiler hints for packing structures */

#define PACK_STRUCT_BEGIN

#define PACK_STRUCT_STRUCT __attribute__((__packed__))

#define PACK_STRUCT_END

#define PACK_STRUCT_FIELD(x) x

/* Plaform specific diagnostic output */

#define LWIP_PLATFORM_DIAG(x) do { printf x; } while(0)

#define LWIP_PLATFORM_ASSERT(x) do {

printf("Assertion "%s" failed at line%d in %sn",

x, __LINE__, __FILE__); fflush(NULL); abort(); }while(0)

#endif /* __ARCH_CC_H__ */

3.1.2. perf.h

perf.h用于實(shí)現(xiàn)系統(tǒng)統(tǒng)計(jì)和測量相關(guān)頭文件,在平時(shí)可以不用。

#ifndef __PERF_H__

#define __PERF_H__

#define PERF_START/* null definition */

#define PERF_STOP(x)/* null definition */

#endif /* __PERF_H__ */

3.2. 操作系統(tǒng)相關(guān)3.2.1. sys_arch.h/sys_arch.c

在sys_arch.h/sys_arch.c中需實(shí)現(xiàn)操作系統(tǒng)相關(guān)的接口,主要是提供信號量、郵箱、臨界區(qū)保護(hù)的接口實(shí)現(xiàn),為了支持Lwip的完整功能,還需實(shí)現(xiàn)多線程接口,除此之外,Lwip還需使用系統(tǒng)時(shí)鐘來確定一些模塊(如ARP、TCP等)的超時(shí)處理。所有需在sys_arch.h/sys_arch.c中實(shí)現(xiàn)的接口函數(shù)均在sys.h中給出了原型,此處不使用操作系統(tǒng),只需實(shí)現(xiàn)Lwip的系統(tǒng)時(shí)鐘即可。

extern volatile uint32_t SystemTick;

uint32_t sys_now(void)

{

returnSystemTick;

}

3.3. 驅(qū)動(dòng)接口相關(guān)3.3.1. ethernetif.c

Lwip最底層需要實(shí)現(xiàn)讀寫網(wǎng)卡,其中在源碼包中ethernetif.c,已經(jīng)給出了底層驅(qū)動(dòng)接口模板的實(shí)現(xiàn),因此只需要在模板中加入網(wǎng)卡驅(qū)動(dòng)接口函數(shù)即可,主要是網(wǎng)卡初始化、網(wǎng)卡接收、網(wǎng)卡發(fā)送這三個(gè)函數(shù)。筆者使用的是DM9000A,驅(qū)動(dòng)的實(shí)現(xiàn)在前面章節(jié)有詳細(xì)的介紹,此處不再細(xì)述。

/* Define those to better describe your networkinterface. */

#define IFNAME0 'e'

#define IFNAME1 'n'

struct ethernetif {

structeth_addr *ethaddr;

/* Addwhatever per-interface state that is needed here. */

};

struct netifDM9000_netif;

static void low_level_init(struct netif *netif)

{

/* set MAC hardware address length */

netif->hwaddr_len = ETHARP_HWADDR_LEN;

/* set MAC hardware address */

netif->hwaddr[0] = default_enetaddr[0];

netif->hwaddr[1] = default_enetaddr[1];

netif->hwaddr[2] = default_enetaddr[2];

netif->hwaddr[3] = default_enetaddr[3];

netif->hwaddr[4] = default_enetaddr[4];

netif->hwaddr[5] = default_enetaddr[5];

/* maximum transfer unit */

netif->mtu = 1500;

/* device capabilities */

/* don't set NETIF_FLAG_ETHARP if this device is notan ethernet one */

netif->flags = NETIF_FLAG_BROADCAST |NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;

/* Do whatever else is needed to initialize interface.*/

DM9000_Init();

}

static err_t low_level_output(struct netif *netif,struct pbuf *p)

{

struct pbuf*q;

uint16_tBuffer[1514/2];

uint8_t*pBuffer;

#if ETH_PAD_SIZE

pbuf_header(p,-ETH_PAD_SIZE); /* drop the padding word */

#endif

pBuffer =(uint8_t *)Buffer;

for(q = p; q!= NULL; q = q->next) {

memcpy(pBuffer, q->payload, q->len);

pBuffer +=q->len;

}

// signal thatpacket should be sent();

DM9000_SendPacket(Buffer, p->tot_len);

#if ETH_PAD_SIZE

pbuf_header(p,ETH_PAD_SIZE); /* reclaim the padding word */

#endif

LINK_STATS_INC(link.xmit);

return ERR_OK;

}

static struct pbuf * low_level_input(struct netif*netif)

{

struct pbuf*p, *q;

uint16_tBuffer[1514/2];

uint8_t*pBuffer;

int16_t len;

/* Obtain thesize of the packet and put it into the "len" variable. */

len =DM90000_ReceivePacket(Buffer);

if (len <=0) {

return NULL;

}

#if ETH_PAD_SIZE

len +=ETH_PAD_SIZE; /* allow room for Ethernet padding */

#endif

/* We allocatea pbuf chain of pbufs from the pool. */

p =pbuf_alloc(PBUF_RAW, len, PBUF_POOL);

if (p != NULL){

#if ETH_PAD_SIZE

pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */

#endif

pBuffer =(uint8_t *)Buffer;

for(q = p; q!= NULL; q = q->next) {

memcpy(q->payload, pBuffer, q->len);

pBuffer+= q->len;

}

#if ETH_PAD_SIZE

pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */

#endif

LINK_STATS_INC(link.recv);

} else {

LINK_STATS_INC(link.memerr);

LINK_STATS_INC(link.drop);

}

return p;

}

void ethernetif_input(struct netif *netif)

{

struct eth_hdr*ethhdr;

struct pbuf*p;

/* movereceived packet into a new pbuf */

p =low_level_input(netif);

/* no packetcould be read, silently ignore this */

if (p == NULL)return;

/* points topacket payload, which starts with an Ethernet header */

ethhdr =p->payload;

switch(htons(ethhdr->type)) {

/* IP or ARPpacket? */

caseETHTYPE_IP:

caseETHTYPE_ARP:

#if PPPOE_SUPPORT

/* PPPoEpacket? */

caseETHTYPE_PPPOEDISC:

caseETHTYPE_PPPOE:

#endif /* PPPOE_SUPPORT */

if(netif->input(p, netif)!=ERR_OK) {

LWIP_DEBUGF(NETIF_DEBUG, ("e

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動(dòng)現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉