No.104200 作者:tomchen 邮件:xiaoyongchen@tom.com ID:75014 登陆:3次 文章数:1篇 最后登陆IP:203.86.31.193 最后登陆:2008/2/18 16:37:54 注册:2007/4/24 13:58:44 财富:101 发帖时间:2007/4/24 14:16:32 发贴者IP:203.86.31.193 标题:tomchen:UcIP移植到ARM7上的体会 摘要:No.104200UcIP移植到ARM7上的体会
点击浏览该文件 uC/IP移植到ARM7+uCOS上的体会 深圳 陈小勇 uC/IP是由Guy Lancaster编写的一套基于uC/OS且开放源码的TCP/IP协议栈,是一套完全免费的、可供研究的TCP/IP协议栈。uC/IP具有如下一些特点:带身份验证和报头压缩支持的PPP协议,优化的单一请求/回复交互过程,支持 IP/TCP/UDP协议,可实现的网络功能较为强大,并可裁减。UCIP协议栈被设计为一个带最小化用户接口及可应用串行链路网络模块。根据采用CPU、编译器和系统所需实现协议的多少,协议栈需要的代码容量空间在30-60KB之间。本文介绍uC/IP移植到ARM7内核CPU上的一些体会。 本项目硬件使用ARM7 内核的CPU,通过串口连接GPRS通讯模块,使用PPP协议拨号上网,与主站软件之间使用TCP/IP通讯。硬件框架如图1。 UART接口 图1 软件框架如图2。 图2 上网过程为:CPU通过UART接口与GPRS通讯模块通讯,通过拨号(例如:*99***1#)与移动通信运营商接入服务器连接,连接使用PPP协议;连接成功后,采用SOCKET接口,与主站软件之间使用TCP/IP协议通讯。大部分GPRS通讯模块内置TCP/IP协议栈,但采用uC/IP协议栈,可以使用所有GPRS通讯模块,也可以应用MODEM拨号的情况。 uC/IP协议栈的移植,主要有两个方面,一是与硬件驱动的接口,二是与应用程序的接口。先说与硬件驱动的接口。uC/IP应用于串口模式时,使用nGet()函数接收数据,nPut()函数发送数据,所以移植时要把修改这两个函数。例如这两个函数做如下修改: void nGet(int fd, NBuf **returnHere, long delay) { // long time=mtime(); int l,c; // struct timeval timeout; NBuf *curNBuf,*head; nGET(curNBuf); if(!curNBuf) return ; curNBuf-> len = 0; curNBuf-> nextBuf = NULL; head=curNBuf; l = 0; while(1) { if(GetUartOneByte(&curNBuf-> data[l]) != 0) break; l++; if(l > = NBUFSZ) break; } if(l > 0) { curNBuf-> len=l; c=l; } head-> chainLen=c; *returnHere=head; return; } void nPut(int fd, NBuf *head) { NBuf *nb; for(nb=head; nb; nb=nFree(nb)) { SendUartBytes (nb-> data, nb-> len); } } 其中int GetUartOneByte(unsigned char *pByte) 函数从串口缓冲区读一个字节数据,成功时返回0,不成功返回1。Void SendUartBytes(unsigned char *pBuf, int len)函数向串口发送指定字节的数据。 uC/IP协议栈工作于多任务模式时,定时检查要使用void timerCheck(void);函数。在uCOS系统中,需要在TimeTick中断中调用timeCheck()。可以将timeCheck()添加于OSTimeTickHook()函数中,如下 void OSTimeTickHook (void) { timerCheck(); } 与应用程序的接口部份,首先是使用uC/IP之前的初始化。例如下面的代码就是做初试化的工作。 Interface myInterface; #define LOCAL_ADDRS "192.168.0.10" #define NETWORK_MASK "255.255.255.0" #define DEFAULT_ROUTE "210.22.12.56" void StartupNet(const char *user, const char *password) { myInterface.addrs.localAddr = ntohl(inet_addr(LOCAL_ADDRS)); myInterface.addrs.subnetMask = ntohl(inet_addr(NETWORK_MASK)); myInterface.addrs.gatewayAddr = ntohl(inet_addr(DEFAULT_ROUTE)); myInterface.addrs.networkAddr = myInterface.addrs.localAddr&myInterface.addrs.subnetMask; myInterface.BaseAddrs = 0x300; myInterface.IRQNum = 10; myInterface.arpExpire = 600; nBufInit(); netInit(&myInterface); socketInit(); netSetLogin(user, password); } nBufInit()函数对uC/IP协议栈缓冲区初试化,netInit()对网络接口初始化,socketInit()对Socket接口初始化,netSetLogin()设置PPP拨号时的用户名与密码。 拨号成功后,GPRS通讯模块或Modem返回CONNECT字符,这样就可以调用pppOpen()函数进行PPP连接。PPP连接成功后,就可以调用Socket接口函数进行TCP/IP连接与通信。 Socket接口函数需要做修改,修改如下: SOCKET socket(long af, short type, short protocol) { int i; int sd; for (i = 0; i < MAX_SOCKET; i++) { if (allSocks[i].s ......
>>返回讨论的主题
|