TCP/IP协议栈lwip的移植 新建几个头文件 Include/lwipopts.h Include/arch/cc.h Include/arch/perf.h Include/arch/sys_arch.h
除头文件外还需要添加一个C文件:sys_arch.c。 说明在doc/sys_arch.txt中。
修改netif/Ethernetif.c。 结构对齐的几个宏 对于一个结构下载下来的LWIP的通用定义如下: PACK_STRUCT_BEGIN struct icmp_echo_hdr { PACK_STRUCT_FIELD(u8_t type); PACK_STRUCT_FIELD(u8_t code); PACK_STRUCT_FIELD(u16_t chksum); PACK_STRUCT_FIELD(u16_t id); PACK_STRUCT_FIELD(u16_t seqno); } PACK_STRUCT_STRUCT; PACK_STRUCT_EN
#define PACK_STRUCT_FIELD(x) 这个宏是为了字节序的转换,由于是用的小端,就不用转换了直接定义为#define PACK_STRUCT_FIELD(x) x #define PACK_STRUCT_STRUCT #define PACK_STRUCT_BEGIN #define PACK_STRUCT_END 以上三个宏都是为了做结构体对齐用: 对于gcc的编译器在结构体后跟个关键字就ok struct ip_hdr { } ;__attribute__ ((__packed__)) 因此可以定义为 #define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) #define PACK_STRUCT_BEGIN #define PACK_STRUCT_END 对于vc的编译器就郁闷了,vc做结构体对齐是这样做的 #pragma pack(1) //结构体按照1字节对齐 struct ip_hdr { } ; #pragma pack() //结构体按照编译器默认值对齐 但是VC的编译器不允许将预处理做为宏,也就是不允许这种宏替代#define PACK_STRUCT_BEGIN #pragma pack(1) 所以想靠宏替换来完成字节对齐是不行了,于是就动了大工夫做了如下处理 #ifdef WIN32 #define PACK_STRUCT_STRUCT #define PACK_STRUCT_BEGIN #define PACK_STRUCT_END #else #define PACK_STRUCT_STRUCT __attribute__ ((__packed__)) #define PACK_STRUCT_BEGIN #define PACK_STRUCT_END endif PACK_STRUCT_BEGIN #ifdef WIN32 #pragma pack(1) #endif struct icmp_echo_hdr { PACK_STRUCT_FIELD(u8_t type); PACK_STRUCT_FIELD(u8_t code); PACK_STRUCT_FIELD(u16_t chksum); PACK_STRUCT_FIELD(u16_t id); PACK_STRUCT_FIELD(u16_t seqno); } PACK_STRUCT_STRUCT; #ifdef WIN32 #pragma pack() #endif PACK_STRUCT_END 这样一改在VC下和GCC都可以了,不过每个结构上都要修改一下,这个是黑郁闷黑郁闷啊
“轻量级”保护 "lightweight" synchronization mechanisms - SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. SYS_ARCH_PROTECT(x) - enterprotection mode. SYS_ARCH_UNPROTECT(x) - leaveprotection mode. 这三个宏定义一个快速的“保护”和“解除保护”操作。例如进入保护可以是屏蔽中断或使用一个信号量或mutex。注意:进入保护后还允许再次进入保护,旧的保护标志通过lev返回,退出保护时再恢复。
如果没有定义这三个宏,Sys.h中有一段代码进行了判断。 #ifndef SYS_ARCH_PROTECT
如果没有定义SYS_ARCH_PROTECT,那么可以在lwipopts.h中定义宏SYS_LIGHTWEIGHT_PROT,并在sys_arch.c中定义函数sys_arch_protect()和sys_arch_unprotect(lev) #if SYS_LIGHTWEIGHT_PROT
#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev /** SYS_ARCH_PROTECT * Perform a "fast" protect. This could be implemented by * disabling interrupts for an embedded system or by using a semaphore or * mutex. The implementation should allow calling SYS_ARCH_PROTECT when * already protected. The old protection level is returned in the variable * "lev". This macro will default to calling the sys_arch_protect() function * which should be implemented in sys_arch.c. If a particular port needs a * different implementation, then this macro may be defined in sys_arch.h */ #define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() /** SYS_ARCH_UNPROTECT * Perform a "fast" set of the protection level to "lev". This could be * implemented by setting the interrupt level to "lev" within the MACRO or by * using a semaphore or mutex. This macro will default to calling the * sys_arch_unprotect() function which should be implemented in * sys_arch.c. If a particular port needs a different implementation, then * this macro may be defined in sys_arch.h */ #define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) sys_prot_t sys_arch_protect(void); void sys_arch_unprotect(sys_prot_t pval);
#else
#define SYS_ARCH_DECL_PROTECT(lev) #define SYS_ARCH_PROTECT(lev) #define SYS_ARCH_UNPROTECT(lev)
#endif /* SYS_LIGHTWEIGHT_PROT */
#endif /* SYS_ARCH_PROTECT */
LWIP_COMPAT_MUTEX
定义此宏表示用信号量来代替mutex。
Init.c 不定义NO_SYS和“#define NO_SYS 0”的效果是一样的。 下面这些宏对代码有影响: LWIP_SOCKET LWIP_ARP LWIP_RAW LWIP_UDP LWIP_TCP LWIP_SNMP LWIP_AUTOIP LWIP_IGMP LWIP_DNS LWIP_TIMERS void lwip_init(void) { /* Sanity check user-configurable values */ lwip_sanity_check();
/* Modules initialization */ stats_init(); #if !NO_SYS sys_init(); #endif /* !NO_SYS */ mem_init(); memp_init(); pbuf_init(); netif_init(); #if LWIP_SOCKET lwip_socket_init(); #endif /* LWIP_SOCKET */ ip_init(); #if LWIP_ARP etharp_init(); #endif /* LWIP_ARP */ #if LWIP_RAW raw_init(); #endif /* LWIP_RAW */ #if LWIP_UDP udp_init(); #endif /* LWIP_UDP */ #if LWIP_TCP tcp_init(); #endif /* LWIP_TCP */ #if LWIP_SNMP snmp_init(); #endif /* LWIP_SNMP */ #if LWIP_AUTOIP autoip_init(); #endif /* LWIP_AUTOIP */ #if LWIP_IGMP igmp_init(); #endif /* LWIP_IGMP */ #if LWIP_DNS