lwip 2 pbuf 学习

7 篇文章 2 订阅
struct pbuf

{

    /** next pbuf in singly linked pbuf chain */

    struct pbuf *next;

    /** pointer to the actual data in the buffer */

    void *payload; 

    u16_t tot_len; 

    /** length of this buffer */

    u16_t len; 

    u8_t type_internal; 

    /** misc flags */

    u8_t flags; 

    LWIP_PBUF_REF_T ref; 

    /** For incoming packets, this contains the input netif's index */

    u8_t if_idx; 

}

typedef enum

{

PBUF_TRANSPORT  =   PBUF_LINK_ENCAPSULATION_HLEN +

                    PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN,


PBUF_IP         =   PBUF_LINK_ENCAPSULATION_HLEN +

                    PBUF_LINK_HLEN + PBUF_IP_HLEN, 


PBUF_LINK       =   PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN, 

PBUF_RAW_TX     =   PBUF_LINK_ENCAPSULATION_HLEN, (4)

PBUF_RAW = 0 (5)

} pbuf_layer

PBUF_RAM 类型的 pbuf 空间是通过内存堆分配而来的,这种类型的 pbuf 在协议栈中使用得最

多,一般协议栈中要发送的数据都是采用这种形式,在申请这种 pbuf 内存块的时候,协议栈会

在管理的内存堆中根据需要的大小进行分配对应的内存空间,这种 pbuf 内存块包含数据空间以

及 pbuf 数据结构区域,在连续的 RAM 内存空间中

PBUF_POOL 类型的 pbuf 与 PBUF_RAM 类型的 pbuf 都是差不多的,其 pbuf 结构体与数据缓冲

区也是存在于连续的内存块中,但它的空间是通过内存池分配的,这种类型的 pbuf 可以在极短

的时间内分配得到,因为这是内存池分配策略的优势,在网卡接收数据的时候,LwIP 一般就使

用这种类型的 pbuf 来存储接收到的数据,申请 PBUF_POOL 类型时,协议栈会在内存池中分配

适当的内存池个数以满足需要的数据区域大小

PBUF_ROM 和 PBUF_REF 类型的 pbuf 基本是一样的,它们在内存池申请的 pbuf 不包含数据区

域,只包含 pbuf 结构体 。PBUF_ROM 类型的 pbuf 的数据区域存储在 ROM 中,是一段静态数据,而 PBUF_REF 类型的 pbuf的数据区域存储在 RAM 空间中。

pbuf 内存申请

struct pbuf *

pbuf_alloc(

    pbuf_layer layer, //协议层  PBUF_TRANSPORT PBUF_IP PBUF_LINK PBUF_RAW_TX

    u16_t length, //内存大小

    pbuf_type type) //内存类型 PBUF_RAM PBUF_ROM  PBUF_REF  PBUF_POOL

  • 太网帧首部长度 PBUF_LINK_HLEN(14 字节)、
  • IP 数据报首部长度 PBUF_IP_HLEN(20 字节)、
  • TCP 首部长度 PBUF_TRANSPORT_HLEN(20 字节)

pbuf_free()

pbuf 中 ref 字段就是记录 pbuf 数据包被引用的次数, 在申请 pbuf 的时候,ref 字段就被初始化为 1,当释放 pbuf 的时候,先将 ref 减 1,如果 ref 减 1 后为 0,则表示能释放 pbuf 数据包

其它 pbuf 操作函数

pbuf_realloc() 函数在相应 pbuf(链表)尾部释放一定的空间,将数据包 pbuf 中的数据长度减少为 某个长度值。对于 PBUF_RAM 类型的 pbuf,函数将调用内存堆管理中介绍到的 mem_realloc() 函 数,释放这些多余的空间。对于其他三种类型的 pbuf,该函数只是修改 pbuf 中的长度字段值,并 不释放对应的内存池空间。

pbuf_header() 函数用于调整 pbuf 的 payload 指针(向前或向后移动一定字节数),在前面也说到 过,在 pbuf 的数据区前可能会预留一些协议首部空间,而 pbuf 被创建时,payload 指针是指向数 据区的,为了实现对这些预留空间的操作,可以调用 pbuf_header() 函数使 payload 指针指向数据 区前的首部字段,这就为各层对数据包首部的操作提供了方便。当然,进行这个操作的时候,len 和 tot_len 字段值也会随之更新。

pbuf_take() 函数用于向 pbuf 的数据区域拷贝数据。pbuf_copy() 函数用于将一个任何类型的 pbuf 中的数据拷贝到一个 PBUF_RAM 类型的 pbuf 中。pbuf_chain() 函数用于连接两个 pbuf(链表)为 一个 pbuf 链表。pbuf_ref 函数用于将 pbuf 中的值加 1。 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Car12

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值