原创 uCOS-II+LwIP的应用

2008-8-28 17:09 8810 6 7 分类: MCU/ 嵌入式
LwIP终于能跑了,总结下:
平台是LPC2136+ENC28J60,32K的RAM,软件是uCOS-II 2.51+LwIP 1.1.1。
感觉主要解决两个问题:
操作系统仿真层的移植。这个基于uCOS-II的代码太多了。COPY下就行!
1,设备驱动的移植.
驱动的移植主要就是完成ethernetif.c的工作。作者已经给好了驱动的接口。
struct netif {
  struct netif *next;
  struct ip_addr ip_addr;
  struct ip_addr netmask;
  struct ip_addr gw;
  err_t (* input)(struct pbuf *p, struct netif *inp);
  err_t (* output)(struct netif *netif, struct pbuf *p,
       struct ip_addr *ipaddr);
  err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
  void *state;
#if LWIP_DHCP
  struct dhcp *dhcp;
#endif
  unsigned char hwaddr_len;
  unsigned char hwaddr[NETIF_MAX_HWADDR_LEN];
  u16_t mtu;
  char name[2];
  u8_t num;
  u8_t flags;
};
主要就是:
    err_t (* input)(struct pbuf *p, struct netif *inp);
        这个是被驱动调用的,传递一个数据包给TCP/IP栈。
    err_t (* output)(struct netif *netif, struct pbuf *p,struct ip_addr *ipaddr);
        这个是被IP模块调用的,向以太网上发送一个数据包,函数要先通过IP地址获得解决硬件地址,然后发包。
    err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
        这个是直接发送数据包的接口。

相应的作者在ethernetif.c里面给了几个函数框架,这个文件相当于一个硬件抽象层。
static void low_level_init(struct netif *netif)
    网卡初始化函数
static err_t low_level_output(struct netif *netif, struct pbuf *p)
    链路层发送函数,实现err_t (* linkoutput)接口。
static struct pbuf *low_level_input(struct netif *netif)
    得到一整帧数据
static err_t ethernetif_output(struct netif *netif, struct pbuf *p,struct ip_addr *ipaddr)
    实现发送线程,实现err_t (* output)接口。
static void ethernetif_input(struct netif *netif)
    实现接收线程,识别数据包是ARP包还是IP包
err_t ethernetif_init(struct netif *netif)
    初始化底层接口,给作者给好了驱动的接口赋值啊啥的。

其实,写驱动的时候只要自己再建个ethernet.c,实际的网络硬件控制的文件
然后提供几个函数
比如:
void EMACInit( void )
    硬件的初始化
void EMACPacketSend ( u8_t *buffer, u16_t length )
    用来将buffer里面的包复制到网络设备的发送缓冲里面,发送。
u16_t EMACPacketReceive ( u8_t *buffer, u16_t max_length  )
    用来将网络设备的接收缓冲里面的包数据复制到buffer里面。
u16_t EMACPacketLength ( u16_t max_length )
    获得包长度
    还有其他控制类函数。

最后,用ethernet.c里的函数完成ethernetif.c里的框架。这样脉络可能会清楚一点。

2,应用层的那边的问题。
有几个概念。
1.lwip提供三种API:1)RAW API 2)lwip API 3)BSD API。
    对于多任务系统而言,因为lwip采用的是将TCP/IP协议放在一个单独的线程里面,所以那个线程是tcpip_thread。采用RAW API回调技术,就得把应用层程序写在tcpip_thread这个线程里面,作为同一个任务运行。
    而采用lwip API,就可以将TCP/IP协议和应用层程序放在不同的任务里面,通过调api_lib.c提供的函数,编写相应的应用层代码。好象一般都会采用这种方式。
    BSD API就是那sockets.c里面的,没用过。

2.任务间是如何调度的。
如图这样,
点击看大图
    从底层到应用层,一般将底层数据接收做为一个线程,可以建个任务也可以直接在中断里解决。
然后tcpip_thread是一个线程,最后是应用层一个线程。
    底层的邮箱投递活动是通过调用tcpip.c里的tcpip_input。这个函数向tcpip_thread投递消息。高层的投递应该是通过tcpip_apimsg。

遇到的问题:
1,一开始移植的时候,驱动写好的,能PING通,但TCP的任务没反应,这个我那问题是lwip协议栈的问题,换个版本的协议栈就搞定了,网上吧,下的协议栈,有的是有问题的。

现在开始应用层的开发了......
参考了一个例子
点击下载






PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户461316 2008-8-31 16:20

楼主的经验值得分享!!收藏起来
相关推荐阅读
用户1003858 2014-03-04 11:18
电子花样机控制系统-常州数控技术研究所
CZSK-GE01花样机控制系统 CZSK-GE01是常州数控技术研究所自主研发的一款花样机控制系统,适用于电脑花样机G款,E款,210D款用途,系统采用模块化设计,可以应用于多种不同机型,可...
用户1003858 2014-03-03 16:31
三轴运动控制器-常州数控技术研究所
三轴控制器介绍 控制器由手持盒(CZSK02T)和控制器(CZSK02M)组成,两者通过串口连接,手持盒完成人机交互功能,图形化的示教方式生成用户轨迹文件,支持G代码导入,DXF图形导入,PL...
用户1003858 2010-06-28 09:08
ARM资料网站推荐
http://www.stmfans.com/bbs/?fromuid=4215 http://www.stmfans.com/bbs/?fromuser=cyzgod关于STM32的资料,值得一看哦...
用户1003858 2010-06-09 10:53
STM32 AD
关于STM32的12位AD,前些日子经过实际使用,使用外部电源参考,精度能达到11位,最起码能保证10位精度。可放心使用。...
用户1003858 2009-12-26 14:22
STM32 I2C使用
    用了STM32F103的I2C读写CAT1025的EEPROM,采用的是STM32给的固件例子,网上反映的问题也挺多的。说不好使,用了下,确实是它奶奶的郁闷。不过,也不是不能用。    首先,...
用户1003858 2009-10-16 17:58
常州数控培训
投身制造业的“黄埔军校”<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />常州数控培训...
我要评论
1
6
关闭 站长推荐上一条 /3 下一条