Skip to content

网络数据包

TCP/IP是一种数据通信机制,因此,协议栈的实现本质上就是对数据包进行处理,为了实现高效的效率,lwIP数据包管理要提供一种高效处理的机制。协议栈各层能对数据包进行灵活的处理,同时减少数据在各层间传递时的时间与空间开销,这是提高协议栈工作效率的关键点。在lwIP中它称之为pbuf。

一般使用的时候会申请一个pbuf数据包, 填充数据以后依次在应用层, 传输层, 网络层之间传递依次添加头部, 然后把这一个数据复制到缓冲区里面, 然后使用DMA进行传递以及发送

image-20240704195659878

这是一个模糊分层的tcp/ip协议栈, 大大提升传输的速率

image-20240704201544886

c
/**
 * @ingroup pbuf
 * Enumeration of pbuf layers
 */
typedef enum {
  /** Includes spare room for transport layer header, e.g. UDP header.
   * Use this if you intend to pass the pbuf to functions like udp_send().
   */
  PBUF_TRANSPORT = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN,
  /** Includes spare room for IP header.
   * Use this if you intend to pass the pbuf to functions like raw_send().
   */
  PBUF_IP = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN,
  /** Includes spare room for link layer header (ethernet header).
   * Use this if you intend to pass the pbuf to functions like ethernet_output().
   * @see PBUF_LINK_HLEN
   */
  PBUF_LINK = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN,
  /** Includes spare room for additional encapsulation header before ethernet
   * headers (e.g. 802.11).
   * Use this if you intend to pass the pbuf to functions like netif->linkoutput().
   * @see PBUF_LINK_ENCAPSULATION_HLEN
   */
  PBUF_RAW_TX = PBUF_LINK_ENCAPSULATION_HLEN,
  /** Use this for input packets in a netif driver when calling netif->input()
   * in the most common case - ethernet-layer netif driver. */
  PBUF_RAW = 0
} pbuf_layer;

image-20240704201932861

PBUF_RAM 类型: PBUF_RAM 类型的pbuf的数据存放在RAM中(由内存堆分配而来),常用于发送数据的情况。 在申请这种类型的pbuf时,协议栈会根据所需要的大小申请对应内存空间。 其中,申请的内存包含pbuf数据结构大小以及所需要的数据空间大小。 PBUF_POOL 类型: PBUF_POOL类型的pbuf的数据结构大小以及所需要的数据空间大小也是连续的内存块中。 但是这个连续的内存块是由内存池进行分配的。 PBUF_ROM 与 PBUF_PEF 类型 PBUF_ROM 与 PBUF_PEF ,在内存池申请的pbuf只包含pbuf的数据结构大小。 PBUF_ROM 存放的数据区域在ROM中。 PBUF_PEF 存放的数据区域在RAM中。(与PBUF_RAM 相比,就是pbuf数据结构内存与所存放数据区域的内存是不连续的)

API函数

image-20240704202005053

pbuf.c文件里面实现

c
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)

pbuf_layer: 偏移的类型

length: 数据的长度

type: 类型

会根据不同的类型进行不同的分配方式, 使用PBUF_REF/ROM的时候, 会直接分配一个pbuf并进行初始化

在使用PBUF_POOL的时候, 会使用链表把这几个获取的pbuf连接起来

image-20240704211146887

image-20240704213026137

直接获取一个大的位置

c
u8_t pbuf_free(struct pbuf *p)

在实际释放的时候, 会检测这一个pbuf还有没有在使用