LWIP数据包

数据包

数据包结构体pbuf

数据包管理机制中采用机构体pbuf来描述协议栈中使用的数据包,这个结构同bsd中的mbuf结构很类似。

//pbuf.h
/** Main packet buffer struct */
struct pbuf {
   
  /** next pbuf in singly linked pbuf chain */
  struct pbuf *next;	//指向下一个pbuf结构,所有描述同一个数据包的pbuf需要连接在一个链表上。

  /** pointer to the actual data in the buffer */
  void *payload;	//数据指针,指向该pbuf管理的数据区域起始地址。

  /**
   * 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;	//当前pbuf及其后续所有pbuf中包含的数据总长度

  /** length of this buffer */
  u16_t len;	//当前pbuf长度

  /** a bit field indicating pbuf type and allocation sources
      (see PBUF_TYPE_FLAG_*, PBUF_ALLOC_FLAG_* and PBUF_TYPE_ALLOC_SRC_MASK)
    */
  u8_t type_internal;	//当前pbuf类型

  /** misc flags */
  u8_t flags;	//状态位,没有关键作用,初始化的时候通常设为0

  /**
   * 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.
   */
  LWIP_PBUF_REF_T ref;	//pbuf被引用次数,当有其他指针需要指向该pbuf时,必须调用相关函数讲pbuf的ref字段值增加。

  /** For incoming packets, this contains the input netif's index */
  u8_t if_idx;
};

pbuf的类型

有一个专门的枚举类型来描述:

//pubf.h
/**
 * @ingroup pbuf
 * Enumeration of pbuf types
 */
typedef enum {
   
  /** pbuf data is stored in RAM, used for TX mostly, struct pbuf and its payload
      are allocated in one piece of contiguous memory (so the first payload byte
      can be calculated from struct pbuf).
      pbuf_alloc() allocates PBUF_RAM pbufs as unchained pbufs (although that might
      change in future versions).
      This should be used for all OUTGOING packets (TX).*/
PBUF_RAM = (PBUF_ALLOC_FLAG_DATA_CONTIGUOUS | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP),	//pbuf描述的数据在pbuf结构之后的连续内存堆中
  /** pbuf data is stored in ROM, i.e. struct pbuf and its payload are located in
      totally different memory areas. Since it points to ROM, payload does not
      have to be copied when queued for transmission. */
  PBUF_ROM = PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF,	//pbuf描述的数据在ROM中
  /** pbuf comes from the pbuf pool. Much like PBUF_ROM but payload might change
      so it has to be duplicated when queued before transmitting, depending on
      who has a 'ref' to it. */
  PBUF_REF = (PBUF_TYPE_FLAG_DATA_VOLATILE | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF),	//pbuf描述的数据在RAM中,但位置与pbuf结构所处位置无关
  /** pbuf payload refers to RAM. This one comes from a pool and should be used
      for RX. Payload can be chained (scatter-gather RX) but like PBUF_RAM, struct
      pbuf and its payload are allocated in one piece of contiguous memory (so
      the first payload byte can be calculated from struct pbuf).
      Don't use this for TX, if the pool becomes empty e.g. because of TCP queuing,
      you are unable to receive TCP acks! */
  PBUF_POOL = (PBUF_ALLOC_FLAG_RX | PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL)	//pbuf结构与其描述的数据处于同一内存池中
} pbuf_type;

PBUF_RAM型pbuf

PBUF_RAM类型的pbuf空间是通过内存堆分配得到的,申请PBUF_RAM类型的pbuf时,协议栈会在内存堆中分配相应的空间。这种类型的pbuf在协议栈中使用的最多,协议栈的待发送数据和应用程序的待发送数据一般都采用这个形式。

源代码申请PBUF_RAM型pbuf

p = (struct pbuf*)mem_malloc(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF + offset) + LWIP_MEM_ALIGN_SIZE(length));//p为pbuf类型指针

在这里插入图片描述

PBUF_POOL型pbuf

他的空间是通过内存池分配得到的,这种类型的pbuf可以在极短的时间内得到分配(得益于内存池的优点),在网卡接收数据包时,就使用这种方式包装数据。

在系统初始化内存池的时候,还会初始化两类与数据包pbuf密切相关的POOL,分别是MEMP_PBUF和MEMP_PBUF_POOL,前者用来存放pbuf结构,主要在PBUF_REF和PBUF_ROM这两类pbuf中用到;后者不仅包含pbuf结构,还包含LWIP认为协议栈中可能使用的最大TCP数据包空间。

源代码申请语句

p = memp_malloc(MEMP_PBUF_POOL);//p为pbuf类型指针

系统调用内存池分配函数memp_malloc进行内存分配,通常用户发送的数据可能会很长,系统会多次调用上面的语句,为用户分配多个POOL,按照pbuf链表的形式组织在一起。

在这里插入图片描述

由于每个MEMP_PBUF_POOL都是固定长度,所以这种方式会导致最后一个POOL的部分空间被浪费掉

PBUF_ROM和PBUF_REF类型

PBUF_ROM和PBUF_REF类型的pbuf基本相同,他们的申请都是在内存池中分配一个相应的pbuf结构(即MEMP_PBUF类型的POOL),而不申请数据区的空间。这点与PBUF_RAM和PBUF_POOL不同。

PBUF_ROM和PBUF_REF的区别在于前者指向ROM空间内的某段数据,后者指向RAM空间内的某段数据。在发生某些静态数据时,可以采用这两种类型的pbuf,这将大大节省协议栈的内存空间。

申请PBUF_ROM和PBUF_REF类型的源代码:

p = memp_malloc(MEMP_PBUF);

MEMP_PBUF类型的内存池恰好为一个pbuf结构的大小。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值