lwip 源文件结构分析
inlcude: 各源文件对应的头文件。
api:提供上层应用api接口源文件,包括有socket接口,netifapi接口的实现机制。
core:包含ip层和传输层协议,如ip,tcp,udp,dns,dhcp等。
netif:网络接口层,包括与底层驱动的接口,防火墙,ppp等。
为实现lwip移植,按lwip文档说明,我这添加了一个
arch:文件目录,里面包括lwip所需资源的实现,如邮箱,信号量,任务,超时机制等。
另外我添加了一个
app_lwip: 里面为lwip的一些应用和测试程序。
///看一下lwip的配置选项文件:include/lwip/opt.h
首先需要来了解的是lwip中的几个重要数据结构:
1. netif // 描述一个网络设备,即通常所说的网卡
struct netif {
/** pointer to next in linked list */
struct netif *next;
/** IP address configuration in network byte order */
struct ip_addr ip_addr;
struct ip_addr netmask;
struct ip_addr gw;
/** This function is called by the network device driver to pass a packet up the TCP/IP stack. */
err_t (* input)(struct pbuf *p, struct netif *inp); //接收到一个ip包后传递给上层进行 tcp_ip 处理
/** This function is called by the IP module when it wants to send a packet on the interface. This function typically
* first resolves the hardware address, then sends the packet. */
err_t (* output)(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr);//发送数据时,ip层调用它发送一个ip包
/** This function is called by the ARP module when it wants to send a packet on the interface. This function outputs
* the pbuf as-is on the link medium. */
err_t (* linkoutput)(struct netif *netif, struct pbuf *p); //被用于arp发送一个数据包到网络,比方说ping命令
/** This field can be set by the device driver and could point to state information for the device. */
void *state; //设备信息,比方说 MAC地址等
#if LWIP_DHCP
/** the DHCP client state information for this netif */
struct dhcp *dhcp;
#endif
/** number of bytes used in hwaddr */
u8_t hwaddr_len;
/** link level hardware address of this interface */
u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
/** maximum transfer unit (in bytes) */
u16_t mtu; //???
/** flags (see NETIF_FLAG_ above) */
u8_t flags;
/** link type */
u8_t link_type; //???
/** descriptive abbreviation */
char name[2];
/** number of this interface */
u8_t num;
};
即说到这里,就来先看下 netif.c
里面实现有网卡的一些基本操作函数,添加,删除,查找,参数设置,状态转换等。
其通过一个 struct netif *netif_list ,全局变量指向最新加入的netif实现了一个单向链表,方便,并且资源利用小.
2. pbuf lwip中数据接受存储传递数据结构
struct pbuf {
/** next pbuf in singly linked pbuf chain */
struct pbuf *next;
/** pointer to the actual data in the buffer */
void *payload;
/**
* total length of this buffer and all next buffers in chain belonging to the same packet.
* For non-queue packet chains this is the invariant:
* p->tot_len == p->len + (p->next? p->next->tot_len: 0)
*/
u16_t tot_len;
/** length of this buffer */
u16_t len;
/** flags telling the type of pbuf, see PBUF_FLAG_ */
u16_t flags;
/**
* the reference count always equals the number of pointers
* that refer to this pbuf. This can be pointers from an application,
* the stack itself, or pbuf->next pointers from a chain.
*/
u16_t ref;
};
在pbuf.c 中 static u8_t pbuf_pool_memory[MEM_ALIGNMENT - 1 + PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf))];定义了pool类型的pbuf缓存区。
在mem.c中 static u8_t ram[MEM_SIZE + sizeof(struct mem) + MEM_ALIGNMENT];定义了ram类型的pbuf缓存区,搞死了,这个文件真难理解,看了一个下午。
在memp.c中,包括了各数据结构的的内存分配,如,pbuf. raw_pcb, udp_pcb, tcp_pcb, tcp_pcb_listen, tcp_seg, netbuf, netconn, api_msg, tcpip_msg, sys_timeout.