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都可以了,不过每个结构上都要修改一下,这个是黑郁闷黑郁闷啊
“轻量级”保护
\
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 \ * 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 * \ * 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 \ * implemented by setting the interrupt level to \ * 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”的效果是一样的。