3.LwIP相关初始化
[cpp] view plaincopy
- void LwIP_Config (void)
- {
- struct ip_addr ipaddr;
- struct ip_addr netmask;
- struct ip_addr gw;
-
- // 调用LWIP初始化函数
- lwip_init();
-
- IP4_ADDR(&ipaddr, 192, 168, 1, 16); // 设置网络接口的ip地址
- IP4_ADDR(&netmask, 255, 255, 255, 0); // 子网掩码
- IP4_ADDR(&gw, 192, 168, 1, 1); // 网关
-
- // 初始化enc28j60与LWIP的接口,参数为网络接口结构体、ip地址、
- // 子网掩码、网关、网卡信息指针、初始化函数、输入函数
- netif_add(&enc28j60, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);
-
- // 把enc28j60设置为默认网卡
- netif_set_default(&enc28j60);
-
- netif_set_up(&enc28j60);
- }
【说明】
【1】通过netif_add初始化网卡IP地址,子网掩码和网关地址。此处使用静态IP地址。
【2】netif_add需要传入两个函数指针,分别是网卡初始化函数和接收内容处理函数。ethernetif_init位于ethernetif.c而ethernet_input并不位于ethernetif.c,此处也不能使用ethernetif_input,其实ethernet_input在函数ethernetif_input被调用,但是ethernet_input变了一个样子:
netif->input(p, netif)!=ERR_OK
【3】在带操作系统的移植中,最后一个参数使用tcpip_input。
4.while(1)部分
[cpp] view plaincopy
- timer_typedef tcp_timer, arp_timer;
-
- /* 设定查询定时器 ARP定时器 */
- timer_set(&tcp_timer, CLOCK_SECOND / 10); // tcp处理定时器 100ms
- timer_set(&arp_timer, CLOCK_SECOND * 5); // arp处理定时器 5s
- while (1) {
-
- if (enc28j60_packet_getcount() != 0) {
- ethernetif_input(&enc28j60);
- }
-
- // TCP 定时处理
- if (timer_expired(&tcp_timer)) {
- timer_set(&tcp_timer, CLOCK_SECOND / 4);
- tcp_tmr();
- }
-
- // ARP 定时处理
- if (timer_expired(&arp_timer)) {
- timer_set(&arp_timer, CLOCK_SECOND * 5);
- etharp_tmr();
- }
- }
【说明】
while(1)循环包括3个主要功能
【1】一旦接受到数据包,立刻调用 ethernetif_input。此处使用查询法而不是中断法(中断法效果相似)
【2】定期处理TCP链接,定时时间为100ms,可根据情况适当缩小时间间隔。
【3】定期更新ARP缓冲,可根据情况适当扩大时间间隔。
【4】此处的timer通过systick实现,具体实现请参考代码仓库。
4.基本测试
【1】ping实验
此时网卡的静态IP地址为192.168.1.16,通过ping指令发送16个数据包
ping 192.168.1.16 -n 16
file:///C:/Users/dell/AppData/Local/YNote/Data/xukai19871105@126.com/79584133fb6b486eaaadbf2272e96ceb/clipboard.png
图1 ping实验
【2】TCP Echo例子
LwIP提供很多示例,TCP Echo示例位于contrib-1.4.1的apps文件夹中,文件夹名为tcpecho_raw)。修改TCP侦听端口为10086。
err = tcp_bind(echo_pcb, IP_ADDR_ANY, 10086);
file:///C:/Users/dell/AppData/Local/YNote/Data/xukai19871105@126.com/18259b4ebe074ebaad5bbadb661b0de0/clipboard.png
图2 TCP Echo例子
5.总结
【1】移植和应用LwIP一定要耐心细致。
【2】一旦网卡接收到数据,应调用ethernetif_input函数,调用该函数让数据进入LwIP协议栈。
【3】 netif_add(&enc28j60, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);最后一个参数为ethernet_input,千万必要写成ethernetif_input。
6.参考资料
更多细节内容请参考图书资料
【1】《嵌入式网络系统设计——基于Atmel ARM7系列》
【2】《STM32嵌入式系统开发实战指南——FreeRTOS与LwIP联合移植》
|