• lwIP 2.0.3 移植笔记(基于 STM32 + μC/OS-II)


    本次实验参考自原子已经移植好的 LWIP(版本:1.4.1)模板来进行的,感谢!

    由于要做的一个小项目要用到网络通信,而且想要加上 UC/OS-II 跑个系统,感觉 LWIP 这个轻量级的 IP 协议栈再合适不过了,故浏览了下官方的下载地址(http://ftp.twaren.net/Unix/NonGNU/lwip/),发现此时的最新版是 2.0.3,下载下来对比原子的 1.4.1 版本,觉得新版本有以下优点便于移植:

    1.4.1 版本中:
        mempsize=memp_get_memorysize();
    	memp_memory=mymalloc(SRAMIN,mempsize);	
    	ramheapsize=LWIP_MEM_ALIGN_SIZE(MEM_SIZE)+2*LWIP_MEM_ALIGN_SIZE(4*3)+MEM_ALIGNMENT;
    	ram_heap=mymalloc(SRAMIN,ramheapsize);	
        手动来分配 memp_memory 和 ram_heap 的内存,需要自己实现内存的动态分配(malloc free)等操作;
        
    2.0.3 版本中:
        const struct memp_desc* const memp_pools[MEMP_MAX] = {
        #define LWIP_MEMPOOL(name,num,size,desc) &memp_ ## name,
        #include "lwip/priv/memp_std.h"
        };
        
        #define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[LWIP_MEM_ALIGN_BUFFER(size)]
        
        LWIP_DECLARE_MEMORY_ALIGNED(ram_heap, MEM_SIZE_ALIGNED + (2U*SIZEOF_STRUCT_MEM));
        已经在 LWIP 的内核中完成了内存的分配,便于移植。
    

    由于只是刚接触 LWIP,目前只是发现这个肤浅的优点,但新版本肯定优化了很多内容,通过源码中的 doc 文档可以得知,以后学习到会再次记录。

    大体的移植步骤(细节已经不记得了....)

    1. 创建 LWIP_archarch 文件夹,加入以下文件(来自原子的 LWIP 例程):

    2. 将原子的 lwipopts.h 文件拷入 LWIP_includelwip 目录下

    3. 将源码加入到 uc/os-ii 工程,如下图所示:


    enc28j60.c 与 spi.c 文件导入原子的文件即可,其它皆为 LWIP 源文件。

    4. 将 arch.h 中的 LWIP_NO_STDINT_H 值置为 1 以启用 cc.h 文件。

    5. 导入 sys_arch.c 文件,屏蔽掉其中的 malloc 相关函数,自己分配静态内存即可,屏蔽其中的 sys_msleep 函数,使用新版本中自带的 sys_msleep 函数。

    6. 包含各目录下的头文件,其中有些文件需要注意: 例如 #include "lwip/opt.h" 只需要包含 lwip 文件夹所在目录即可。

    编写 lwip_app.c 函数

    #include "netif/etharp.h"
    #include "lwip/dhcp.h"
    #include "lwip/mem.h"
    #include "lwip/memp.h"
    #include "lwip/init.h"
    #include "lwip/tcpip.h" 
    #include "lwip/ip_addr.h" 
    #include "delay.h"
    #include "usart.h"  
    #include "enc28j60.h"
    #include "lwip_app.h"
    #include <stdio.h>
    
    __lwip_dev lwipdev;	
    struct netif lwip_netif;				
    
    extern err_t ethernetif_input(struct netif *netif);
    extern err_t ethernetif_init(struct netif *netif);
    
    void lwip_pkt_handle(void)
    {
    	ethernetif_input(&lwip_netif);
    }
    
    void lwip_default_ip_set(__lwip_dev *lwipx)
    {
        //初步使用静态方式分配 IP 地址,以后再启用 DHCP
    	lwipx->remoteip[0]=192;	
    	lwipx->remoteip[1]=168;
    	lwipx->remoteip[2]=0;
    	lwipx->remoteip[3]=124;
    	
    	lwipx->mac[0]=enc28j60_dev.macaddr[0];
    	lwipx->mac[1]=enc28j60_dev.macaddr[1];
    	lwipx->mac[2]=enc28j60_dev.macaddr[2];
    	lwipx->mac[3]=enc28j60_dev.macaddr[3];
    	lwipx->mac[4]=enc28j60_dev.macaddr[4];
    	lwipx->mac[5]=enc28j60_dev.macaddr[5]; 
    
    	lwipx->ip[0]=192;	
    	lwipx->ip[1]=168;
    	lwipx->ip[2]=0;
    	lwipx->ip[3]=123;
    
    	lwipx->netmask[0]=255;	
    	lwipx->netmask[1]=255;
    	lwipx->netmask[2]=255;
    	lwipx->netmask[3]=0;
    
    	lwipx->gateway[0]=192;	
    	lwipx->gateway[1]=168;
    	lwipx->gateway[2]=0;
    	lwipx->gateway[3]=1;	
    	lwipx->dhcpstatus=0;
    } 
    
    u8_t lwip_app_init(void)
    {
    	struct netif *Netif_Init_Flag;			
    	struct ip4_addr ipaddr;  					
    	struct ip4_addr netmask; 					
    	struct ip4_addr gw;      					
    
    	if(ENC28J60_Init())return 2;			
    	
    	tcpip_init(NULL,NULL);							
    	lwip_default_ip_set(&lwipdev);			
    
    	IP4_ADDR(&ipaddr,lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);
    	IP4_ADDR(&netmask,lwipdev.netmask[0],lwipdev.netmask[1] ,lwipdev.netmask[2],lwipdev.netmask[3]);
    	IP4_ADDR(&gw,lwipdev.gateway[0],lwipdev.gateway[1],lwipdev.gateway[2],lwipdev.gateway[3]);
    	printf("网卡的MAC地址为:................%d.%d.%d.%d.%d.%d
    ",lwipdev.mac[0],lwipdev.mac[1],lwipdev.mac[2],lwipdev.mac[3],lwipdev.mac[4],lwipdev.mac[5]);
    	printf("网卡的IP地址为:........................%d.%d.%d.%d
    ",lwipdev.ip[0],lwipdev.ip[1],lwipdev.ip[2],lwipdev.ip[3]);
    	printf("子网掩码:..........................%d.%d.%d.%d
    ",lwipdev.netmask[0],lwipdev.netmask[1],lwipdev.netmask[2],lwipdev.netmask[3]);
    	printf("默认网关:..........................%d.%d.%d.%d
    ",lwipdev.gateway[0],lwipdev.gateway[1],lwipdev.gateway[2],lwipdev.gateway[3]);
    
    	Netif_Init_Flag = netif_add(&lwip_netif,&ipaddr,&netmask,&gw,NULL,&ethernetif_init,&tcpip_input);
    
    	if(Netif_Init_Flag != NULL) 				
    	{
    		netif_set_default(&lwip_netif); 	
    		netif_set_up(&lwip_netif);				
    		
    		printf("
    ********	Netif up ok! ********
    ");
    	}
    	
    	return 0;
    }
    

    运行效果

    将 lwip_app_init() 接口加入到 main 主函数,编译下载运行,效果如下所示:

    串口收到以下信息:

    ping 测试:

  • 相关阅读:
    【luogu P1073 最优贸易】 题解
    【luogu P2919 [USACO08NOV]守护农场Guarding the Farm】 题解
    【luogu P3946 ことりのおやつ】 题解
    【luogu P3393 逃离僵尸岛】 题解
    ubuntu问题: 同时只能有一个软件管理工具在运行
    Windows server 2008 r2 开启Aero
    windows8.1安装之后的感想
    20条Linux命令面试问答
    9个常用iptables配置实例
    Linux SSH安全技巧
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/9000154.html
Copyright © 2020-2023  润新知