LwIP协议栈学习
流程图
以梳理流程图的方式,认识LWIP协议栈的工作流程、和工作原理。
整体工作流程
模块分析
一个整体协议也可作为一个模块,既要向下兼容,也要向上兼容。这种兼容无疑要采用“接口”实现。向下要兼容各种硬件、平台的硬件驱动(想想这里的接口实现方式,可以linux驱动模型吧?)。向上也要给应用留出好用的接口。
IP[Internet Protocol]【网际协议】
TCP[Transmission Control Protocol]【传输控制协议】
ICMP[Internet control message protocol]【Internet控制报文协议】
它是tcp/ip协议簇的一个子协议。是一种面向无连接的“错误侦测与回报机制”的协议。
报文协议格式
ICMP报文包含在IP数据报中,属于IP的一个用户,IP头部就在ICMP报文的前面,所以一个ICMP报文包括IP头部、ICMP头部和ICMP报文。IP头部的Protocol值为1就说明这是一个ICMP报文,ICMP头部中的类型(Type)域用于说明ICMP报文的作用及格式,此外还有一个代码(Code)域用于详细说明某种ICMP报文的类型,所有数据都在ICMP头部后面。这里有一个简洁,扼要的ICMP协议格式ICMP协议格式
ICMP报文主要有两个功能:查询报文和差错报文
//定义ICMP首部
typedef struct _icmphdr{
unsigned char i_type; //8位类型
unsigned char i_code; //8位代码
unsigned short i_cksum; //16位校验和, 从TYPE开始,直到最后一位用户数据,如果为字节数为奇数则补充一位
unsigned short i_id ; //识别号(一般用进程号作为识别号), 用于匹配ECHO和ECHO REPLY包
unsigned short i_seq ; //报文序列号, 用于标记ECHO报文顺序
unsigned int timestamp; //时间戳
}ICMP_HEADER;
内存管理
内存管理策略
动态内存堆分配策略
动态内存池[POOL]分配策略
用到的语法技巧
- 宏定义
概念:在编译时,直接替换
#define MACRO_EXP macro_actual
表达 作用
分析:
数据包pbuf
LWIP有一个高效的数据包管理核心,能够兼容各种数据类型的数据,避免在各层之间复制数据的巨大开销。
struct pbuf {
struct pubf *next; /* 详见说明【1】 */
void *payload; /* 详见说明【2】 */
u16_t tot_len; /* 详见说明【3】 */
u16_t len; /* 详见说明【4】 */
u8_t type; /* 详见说明【5】 */
u8_t flags; /* 详见说明【6】 */
u16_t ref; /* 详见说明【7】 */
}
说明:
【1】:单向链表,指向下一个puf数据包
【2】:数据指针,指向pbuf数据的起始地址
【3】:包含当前的pbuf和其后的所有pbuf的有效数据长度。
【4】:当前bupf中的有效数据长度。
【5】:当前pbuf的类型。有四种: PBUF_RAM、PBUF_ROM、PBUF_REF、PBUF_POOL。
【6】:当前pbuf的类型。未使用。
【7】:该pbuf被引用的次数。初始化值为1.
- offset -【8】* :payload用来存储数据的包头的空间,如TCP包头、IP包头。可以是0
说白就是一个二级管理机制:
{包管理头(拆分包管理)} + {包数据头(数据帧管理)} + {数据}
注解:
- pbuf 链中第一个 pbuf 的 tot_len 字段表示整个数据包的长度,而最后一个 pbuf 的 tot_len
字段必和 len 字段相等。 - type 之 RAM -> 堆 -> mem_malloc -> {SIZEOF_STRUCT_PBUF + length + offset} -> 结构头和数据区的地址连续的。
- type 之 POOL -> memp_malloc(MEMP_PBUF_POOL)
- type 之 ROM & REF -> 堆中申请结构头空间 : ROM内 or RAM 内。-> memp_malloc(MEMP_PBUF)
- 对于一个数据包,它可能使用上述的任意的 pbuf 类型,很可能的情况是,一大串
不同类型的 pbufs 连在一起,用以保存一个数据包的数据 。
小知识汇总
- 数据包的管理有一个核心的东西,当数据在各层之间传递时,LWIP极力禁止数据的拷贝的工作,因为这样会耗费大量的时间和内存。