东京热亚洲精品,伊人网在线85,激情综合视频米奇,久久精品水嫩水嫩懂色,五月婷色欧美,美女激情四射扣阴逼,女同性恋日本,美女亚洲综合二区,久久久久久中出久久V

ZLIP使用簡介

李章林1

1 南開大學(xué)電子應(yīng)用實驗室,http://www.wusss.cn,版本:2005-11-28)

1 目錄結(jié)構(gòu)

TCP/IP協(xié)議棧程序所在目錄。

Icmp協(xié)議。

IP層。

:網(wǎng)絡(luò)接口層。

TCP協(xié)議層。

TCPIP內(nèi)存管理程序。

 

 

 

 

 

 

 

 

:網(wǎng)絡(luò)接口協(xié)議所在目錄。

ARP協(xié)議。

:以太網(wǎng)接口協(xié)議。

RTL8019AS以太網(wǎng)接口芯片驅(qū)動程序。

 

 

 

 

 

 

:全局函數(shù)和宏定義所在目錄

 

 

 

 

:應(yīng)用層協(xié)議所在目錄

:主程序,這里包含一個如何使用的例子程序。

KeilC目錄下是KeilC51的工程文件所在目錄。用KeilC51打開Ex1.Uv2。

MCU目錄下是各種類型的51單片機的頭文件。

2 概述

單片機上網(wǎng)技術(shù),是當(dāng)前的一個熱門技術(shù)。單片機上網(wǎng)技術(shù)中的一個重要部分是在單片上實現(xiàn)TCP/IP協(xié)議棧,F(xiàn)在可獲得的TCP/IP源代碼一般并不為51單片機設(shè)計,而51單片機和KeilC51編譯器有其自身的特點:存儲類型、函數(shù)指針、重入函數(shù)等,ZLIP就是針對這些特點設(shè)計的TCP/IP協(xié)議棧。

ZLIP設(shè)計的目標(biāo)是:

1)              精簡TCP/IP協(xié)議棧,以減小代碼量。ZLIP目前沒有支持UDP協(xié)議,ICMP協(xié)議也只支持其中的echo協(xié)議(響應(yīng)ping數(shù)據(jù)包)lwIP是一個功能全面的TCP/IP協(xié)議棧,但是相對51來說代碼量較大。

2)             應(yīng)用層接口簡單,以兼容通用的socket接口。uIP有很小的代碼量和減小代碼量(選擇AVR為目標(biāo)器件時,代碼為5K左右)和RAM使用量(100字節(jié)左右)。uIP采用了不保存需要應(yīng)答的數(shù)據(jù)包的RAM使用方案,沒有和BSD的套接字接口兼容,應(yīng)用層接口較復(fù)雜。

3)             針對KeilC51編譯器設(shè)計。所有的外部變量都使用了xdata類型,全部指針都為明確存儲類型的指針,需要重入的函數(shù)已經(jīng)聲明為reentant,使用KeilC的小模式下編譯。

使用12M晶振、KeilC編譯器、89C55單片下測試的技術(shù)參數(shù)如下:

1:技術(shù)參數(shù)

代碼量(字節(jié))

外部RAM使用量(字節(jié))

發(fā)送速度(字節(jié)/秒)

14841

11068

5.892K

ZLIP的特點如下:

1)有適中代碼量和RAM使用量。

2)使用類似MFC的CScoket的套接字接口,使用方便。

3)支持多TCP連接、多網(wǎng)絡(luò)設(shè)備。能方便地移植到多任務(wù)操作系統(tǒng)和其它CPU下。能方便地替換網(wǎng)絡(luò)接口協(xié)議和網(wǎng)卡驅(qū)動設(shè)備。

4)支持ping命令的響應(yīng)。

5)為單片機設(shè)計:所有的外部變量都使用了xdata類型,全部指針都為明確存儲類型的指針,需要重入的函數(shù)已經(jīng)聲明為reentant,使用KeilC的小模式編譯。

3電路圖

1RTL8019AS電路左半部分

2RTL8019AS電路右半部分

該程序不能在KeilC下軟件仿真,因為程序的運行需要外部電路配合。該51系統(tǒng)的外部電路主要有:以太網(wǎng)接口芯片RTL8019AS電路、外部RAM電路。

       以太網(wǎng)接口芯片RTL8019AS電路圖,如圖1和圖2表示。A0A4接地址線,D0D7接數(shù)據(jù)線,CSRTL是片選線(低電平有效),RD-WR-接讀寫信號線。

4 應(yīng)用層接口

zlIP接口函數(shù)基本和BSD的套接字接口相同。

41提供的用戶接口函數(shù):

TCPSocket()

函數(shù)原型:socket xdata * TCPSocket(IP_ADDR ScrIP)。

功能:申請一個套接字。ScrIP是這個套接字的本地IP地址。返回socket類型指針,如果申請失敗返回NULL

 

TCPConnect()。

函數(shù)原型:BOOL TCPConnect(socket xdata * pTCB, IP_ADDR DestIP, WORD DestPort,void (code * recv)(void xdata * buf,WORD size),void (code * close)(socket xdata * pSocket))。

功能:向IP地址為DestIP的服務(wù)器的DestPort端口發(fā)起連接。參數(shù)recvclose用于設(shè)置當(dāng)接收到數(shù)據(jù)包和對方要求關(guān)閉TCP連接時應(yīng)該調(diào)用的回調(diào)函數(shù)指針。連接成功返回TRUE,否則返回FALSE。

 

TCPSend()

函數(shù)原型:BOOL TCPSend(socket xdata * pTCB,void xdata *buf,WORD DataSize)。

功能:發(fā)送數(shù)據(jù)。發(fā)送數(shù)據(jù)的TCP連接是套接字指針pTCB對應(yīng)的連接,發(fā)送的數(shù)據(jù)的起始地址為buf,大小為DataSize。發(fā)送成功返回TRUE,否則返回FALSE

 

TCPSendEx()

函數(shù)原型:BOOL TCPSendEx(socket xdata * pTCB,struct SMemHead xdata *MemHead) 。

功能:快速發(fā)送數(shù)據(jù)。在使用TCPSend函數(shù)時,你首先需要將數(shù)據(jù)放入buf指向的內(nèi)存中,然后調(diào)用TCPSend函數(shù),接著該函數(shù)會將buf指向的內(nèi)存區(qū)數(shù)據(jù)拷貝到TCP緩沖區(qū)中。使用TCPSendEx 時你首先用TCPAllocate(DATA_SIZE)獲得一個TCP緩沖區(qū),然后直接將數(shù)據(jù)放入TCP緩沖區(qū)中,從而比TCPSend函數(shù)少一次數(shù)據(jù)拷貝,提高發(fā)送速度。

參數(shù):發(fā)送數(shù)據(jù)的TCP連接是套接字指針pTCB對應(yīng)的連接,發(fā)送的數(shù)據(jù)放在TCP緩存MemHead中。發(fā)送成功返回TRUE,否則返回FALSE。

 

TCPListen()。

函數(shù)原型:BOOL TCPListen(socket xdata *pTCB,WORD ScrPort,void (code * accept)(socket xdata *pNewTCB))

功能:使用套接字pTCBScrPort端口監(jiān)聽。參數(shù)accept是當(dāng)有客戶端向這個監(jiān)聽端口連接成功時調(diào)用的回調(diào)函數(shù)指針。

 

TCPClose()。

函數(shù)原型:void TCPClose(socket xdata *pTCB)。

功能:我方主動關(guān)閉連接時調(diào)用TCPClose函數(shù),它將要求關(guān)閉套接字pTCB對應(yīng)的連接。TCPClose返回以后這個TCP連接可能保持,因為另一方還沒有發(fā)起關(guān)閉請求。

 

TCPAbort()。

函數(shù)原型:void TCPAbort(socket xdata *pTCB)

功能:當(dāng)使用完這個套接字以后,調(diào)用TCPAbort,將這個套接字釋放,還給系統(tǒng)。

42使用步驟

使用ZLIP時,在你的主程序中(請看示例程序的main.c文件)需要做的步驟如下:

1)首先設(shè)置一個25ms的定時中斷函數(shù)(示例程序為Timer函數(shù))。請在中斷函數(shù)中調(diào)用NetIfTimer(); ARPTimer(); TCPTimer();三個函數(shù)。

 

       2)OnReceive函數(shù),它應(yīng)該有如下的參數(shù)和返回值,函數(shù)名可以任意:

void OnReceive1(void DT_XDATA * buf,WORD size)  REENTRANT_MUL

在使用TCPConnect函數(shù)時,OnReceive1將作為TCPConnect函數(shù)的一個參數(shù),也就是設(shè)置該socket的接收函數(shù)。當(dāng)TCP連接接收到對方數(shù)據(jù)時,將自動調(diào)用OnReceive1函數(shù)。buf指向接收的數(shù)據(jù),size是接收的數(shù)據(jù)量的大小。你可以在OnReceive1中處理接收的數(shù)據(jù)。當(dāng)程序中有多個TCP連接同時存在時,你需要給每個連接準(zhǔn)備一個OnReceive函數(shù)。

 

       3)OnClose函數(shù),它應(yīng)該有如下的參數(shù)和返回值,函數(shù)名可以任意:

void OnClose1(socket DT_XDATA * pSocket) REENTRANT_MUL

類似于OnReceive函數(shù),當(dāng)TCP連接的另一方首先向我方發(fā)起關(guān)閉連接的請求時,系統(tǒng)將自動調(diào)用OnClose函數(shù)。pSocket指向?qū)⒁P(guān)閉的socket。如果你想立即關(guān)閉這個連接則在OnClose函數(shù)中調(diào)用TCPClose函數(shù)。當(dāng)程序中有多個TCP連接同時存在時,你需要給每個連接準(zhǔn)備一個OnClose函數(shù)。

 

4)OnAccept函數(shù)。如果你的程序中用到TCPListen函數(shù)監(jiān)聽某端口,這時需要寫OnAccept函數(shù)。它應(yīng)該有如下的參數(shù)和返回值,函數(shù)名可以任意:

void OnAccept1(socket DT_XDATA *pNewSocket) REENTRANT_MUL

當(dāng)一個正在listensocket接受了對方的連接以后將會自動調(diào)用該函數(shù)。pNewSocket是將要獲得這個連接的控制權(quán)的socket指針。一般在OnAccept函數(shù)中做以下處理:

       ExAccept = pNewSocket;            //保存pNewSocket,以后可以用ExAccept發(fā)送數(shù)據(jù)

       pNewSocket->recv = OnAcceptRecv;  //設(shè)置pNewSocketOnReceive函數(shù)。

       pNewSocket->close = OnClose;          //設(shè)置pNewSocketOnClose函數(shù)。

當(dāng)程序中有多個處于listensocket時,你需要給每個socket準(zhǔn)備一個OnAccept函數(shù)

 

       5)在主程序中做初始化工作:

/* init. the order is not important */

       NetIfInit();     //初始化網(wǎng)絡(luò)接口

       ARPInit();      //初始化ARP

       TCPInit();      //初始化TCP

       MemInit();      //初始化內(nèi)存模塊

       RTLInit(EtherAddr);      //初始化RTL8019ASEtherAddr為以太網(wǎng)地址

 

       /* init Devcie struct and init this device */

/* 初始化一個以太網(wǎng)接口設(shè)備,并設(shè)置這個設(shè)備的發(fā)送和接收驅(qū)動函數(shù)。如果你的系統(tǒng)中以太網(wǎng)接口芯片的驅(qū)動不一樣,只要替換這里的發(fā)送和接口驅(qū)動函數(shù)就可以了*/

       EtherDevInit(&DevRTL,EtherAddr,RTLSendPacket,RTLReceivePacket);

 

       /* add this device to NetIf */

/* 添加一個網(wǎng)絡(luò)接口設(shè)備。參數(shù)含義是:該設(shè)備的IP地址、子網(wǎng)掩碼、網(wǎng)關(guān)、輸入函數(shù)指針、輸出函數(shù)指針、該設(shè)備的指針。如果你的系統(tǒng)中有多個網(wǎng)絡(luò)設(shè)備,比如moden,可以編寫moden的輸入輸出函數(shù),使用NetIfAdd函數(shù)添加這個設(shè)備。*/

       NetIfAdd(IPAddr,NetMask,GateWay,EtherInput,EtherOutput,&DevRTL);

 

       6)啟動25ms的定時中斷

 

       7)使用類似

ExConn = TCPSocket(IPAddr);

       語句分配一個socket,并且綁定這個socket的源IP地址。

 

       8)

如果我方作為服務(wù)器方,監(jiān)聽某一端口則:

                            TCPListen(ExConn,Port1,OnAccept1);

當(dāng)另一方向我方Port1端口進(jìn)行連接時,系統(tǒng)自動調(diào)用OnAccpet1函數(shù)。

       如果我方作為客戶端,向另一方的某個端口進(jìn)行連接則:

TCPConnect(ExConn,IPAddr2,Port2,OnReceive2,OnClose2);

即向IP地址為IPAddr2的服務(wù)器的Port2端口進(jìn)行連接。在連接成功以后,如果接收到另一方的數(shù)據(jù)則自動調(diào)用OnReceive1函數(shù),如果接收到另一方的關(guān)閉請求則自動調(diào)用OnClose1函數(shù)。

 

       9)當(dāng)某個socket處于連接狀態(tài)時,可以使用TCPSend或者TCPSendEx函數(shù)發(fā)送數(shù)據(jù)。

 

       10)需要關(guān)閉連接的時候,使用TCPClose關(guān)閉連接。

 

       11)當(dāng)一個socket不再需要時,使用TCPAbort將這個socket還給系統(tǒng)。

5 移植相關(guān)修改

5.1 RTL8019AS的基地址

修改Netif\RTL8019.h中的

#define RTL_BASE_ADDRESS 0xb000

默認(rèn)的基地址為0xb000。當(dāng)單片機訪問0xb000開始的地址的時候,CSRTL信號線應(yīng)給低電平,以選通RTL8019AS。

5.2 TCP緩沖區(qū)大小設(shè)置

修改TCIPIP\TCPIPmem.h中的

#define TCPIP_BUF_SIZE    0x2000

默認(rèn)為8K,建議大于4K。緩沖區(qū)過小,將會影響發(fā)送和接收速度。

5.3 多網(wǎng)絡(luò)設(shè)備

如果你的系統(tǒng)中有多個網(wǎng)絡(luò)設(shè)備。修改TCPIP\NetIf.h中的

#define NET_IF_MAX_NUM       1

默認(rèn)情況下為最多一個設(shè)備。

在主程序中使用NetIfAdd函數(shù)添加網(wǎng)絡(luò)設(shè)備。

5.4 TCP連接數(shù)的設(shè)置

修改TCPIP\TCP.h中的

#define TCP_CONNECTION_MAX_NUM         10

默認(rèn)情況下最多支持10socket同時工作。

5.5 網(wǎng)絡(luò)接口層協(xié)議的最大幀頭長度

只有當(dāng)你的程序使用以太網(wǎng)以外的網(wǎng)絡(luò)接口協(xié)議時,才需要修改。修改TCPIP\NetIf.h中的

#define NETIF_HEAD_MAX_LEN      14

默認(rèn)是以太網(wǎng)幀頭長度,即14個字節(jié)。

5.6 ARP表的大小設(shè)置

修改Netif\ARP.h中的

#define ARP_ENTRY_MAX_NUM              4

默認(rèn)情況下ARP表大小為4個記錄。當(dāng)ARP表已經(jīng)滿的時候,新的記錄將會覆蓋最老的那個記錄。

5.7響應(yīng)ping命令

如果不希望系統(tǒng)能夠響應(yīng)ping命令,則修改TCPIP\icmp.h中的

#define ICMP_EN  1

默認(rèn)情況下該開關(guān)是打開的。如果不需要此功能將其設(shè)置為0

5.8 到其它CPU的移植

zlIP雖然為51單片機設(shè)計,但是也可以被移植到其它的CPU上。系統(tǒng)中的GloblDef\GlobleDef.h記錄了CPU的信息,主要修改這個文件。

1)      設(shè)置BYTE,WORD,DWORD,BOOL等類型的定義

2)      注釋掉#define MCU_C51這一行。注釋掉這個選項開關(guān)以后將程序從C51變?yōu)?/span>ANSIC,程序中將沒有C51特有的關(guān)鍵字。

3)      字節(jié)順序設(shè)置。即設(shè)置多字節(jié)變量的高字節(jié)存在于低地址還是高地址。51單片機的字節(jié)順序和0x8086CPU不一樣。刪除#   define HOST_ORDER_AS_NET,如果字節(jié)順序和網(wǎng)絡(luò)字節(jié)順序不一樣。

4)      是否移植到具有多線程的51單片機程序中。比如單片上運行了RTOS51uc/OS-II、Tiny51等單片上的多線程操作系統(tǒng),則需要打開#   define MULTI_THREAD開關(guān),此時程序中幾乎所有的函數(shù)都聲明為reentrant類型的。

5)      如果需要運行在調(diào)試狀態(tài)打開#   define DEBUG開關(guān)。

6)      對于IORAM不是統(tǒng)一編址的系統(tǒng)需要修改RTL8019.c文件中的#define ReadReg(port) (*((BYTE DT_XDATA *)port))#define WriteReg(port,value) (*((BYTE DT_XDATA *)port) = value),使程序能夠訪問IO端口。

6 后記

       公布此源代碼,旨在將我的心得和成果和大家共享,共同學(xué)習(xí)和進(jìn)步。由于本人水平有限,錯誤和疏漏之處難免,還請各位同行指正。

參考文獻(xiàn)

[1] 李章林,張立民. TCP/IP在51單片上的實現(xiàn)特點和方法. “2003年全國單片機和嵌入式系統(tǒng)年會”論文集.2003年

[2] (電子文獻(xiàn))Adam Dunkels.uIP - A Free Small TCP/IP Stack[Z].  http://dunkels.com/adam/uip/index.html. 2002-1-15.1

[3] (電子文獻(xiàn))Adam Dunkels.lwIP - News Archive[Z].http://www.sics.se/~adam/lwip/news.html.2001-1-9.

[4] 李章林,張立民. ANSIC程序到KeilC51的移植心得. “2003年全國單片機和嵌入式系統(tǒng)年會”論文集.2003年

 

 

揭阳市| 镇沅| 龙川县| 柘城县| 微博| 石渠县| 河津市| 册亨县| 桐城市| 察雅县| 文山县| 东城区| 上饶市| 武功县| 新竹市| 朝阳区| 高邑县| 寿光市| 建宁县| 公主岭市| 彰武县| 神池县| 什邡市| 隆化县| 洪湖市| 平陆县| 黄骅市| 岳普湖县| 大冶市| 乐东| 天长市| 东光县| 焦作市| 峨山| 含山县| 乌鲁木齐县| 余姚市| 垦利县| 南安市| 勃利县| 金溪县|