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);