ZYNQ-pbuf操作指南(一)

简介: ZYNQ-pbuf操作指南

在网口调试中比较重要的部分就是对pbuf的操作,本文主要针对pbuf的结构体、pbuf层和pbuf的相关函数的操作指南进行讲解说明。

pbuf结构体


struct pbuf {  
        struct pbuf *next;                                                                                                                       
        void *payload;   
        u16_t tot_len;    
        u16_t len;  
        u8_t /*pbuf_type*/  type;                                                           
        u8_t flags;  
        u16_t ref;  
} ;  

image.png

pbuf类型


PBUF_RAM


PBUF_RAM类型的pbuf是调用mem_malloc函数从内存堆分配得到的,分配的大小由三部分组成:数据存储空间length、pbuf管理结构体空间SIZEOF_STRUCT_PBUF和存储协议栈头的offset。分配内存成功之后,就是对pbuf管理结构体的初始化。Pbuf管理结构体位于分配的堆内存的开始,接着的存储协议头的offset空间,最后才是存储数据的空间。

此种类型的pbuf内存布局如下:

image.png

PBUF_ROM和PBUF_REF


上述两种类型的pbuf相似。代码调用memp_malloc从内存池分配MEMP_PBUF类型的内存池,仅仅分配pbuf结构体大内存,指向存储数据空间的payload指针置位NULL,此值由调用者设置为另外的一片内存空间。

PBUF_POOL


PBUF_POOL类型的pbuf是调用memp_malloc函数从内存池中分配内存的。PBUF_POOL类型pbuf是从MEMP_PBUF_POOL内存的内存池中分配内存的,每种类型的内存池大小时固定的,如果存储数据和协议头所需要的空间大于此种类型内存池大小,则需要分配多个此种类型的内存池,并将这些内存池通过pbuf->next指针连接起来。而PBUF_RAM类型的pbuf是从内存堆中分配内存,之用申请的内存空间有剩余的连续空闲空间满足要求,则一次分配成功。

PBUF_POOL类型的pbuf内存布局如下:

image.png

pbuf 层


pbuf层包括如下:PBUF_TRANSPORT、PBUF_IP、PBUF_LINK、PBUF_RAW_TX、PBUF_RAW。

image.png

pbuf相关函数


pbuf_alloc


分配给定类型的 pbuf(可能是 PBUF_POOL 类型的链)。

为 pbuf 分配的实际内存由分配 pbuf 的层和请求的大小决定。(由参数决定)

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

image.png

pbuf_alloced_custom


该函数用于初始化已分配的pbuf,相当于自定义pbuf。

struct pbuf* pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p, void *payload_mem, u16_t payload_mem_len)

image.png

pbuf_realloc


该函数将 pbuf 链收缩到所需的长度。

void
pbuf_realloc(struct pbuf *p, u16_t new_len)

image.png

根据所需的长度,链中的前几个 pbuf 可能会被跳过并保持不变。新的链中最后一个 pbuf 将被调整大小,并且其他剩余的 pbuf 将被释放。

如果 pbuf 是 ROM/REF,则只调整 ->tot_len 和 ->len 字段 。 不能在数据包队列上调用。 pbuf_realloc 不能增加 pbuf(链)的大小。

pbuf_free


取消引用 pbuf 链或队列,并在此链或队列的头部释放任何不再使用的 pbuf。 减少 pbuf 引用计数。如果它达到零,则 pbuf 被释放。

对于 pbuf 链,这对链中的每个 pbuf 重复,直到第一个 pbuf 在递减后具有非零引用计数。因此,当所有引用计数为 1 时,整个链都被释放了。

u8_t
pbuf_free(struct pbuf *p)

image.png

假设现有链 a->b->c 具有以下引用计数,调用 pbuf_free(a) 结果:

 1->2->3 变成 free...1->3
 3->3->3 变成 2->3->3
 1->1->2 变成free...free...1
 2->1->1 变成 1->1->1
 1->1->1 变成free...free...free

pbuf_free对链操作的解释简单来说就是,当第一个被释放后才会对后面的脸引用计数进行释放,否者值对最前面的那个链进行释放操作。

pbuf_clen


计算链中 pbuf 的数量 。

u16_t pbuf_clen(const struct pbuf *p)

image.png

pbuf_ref


增加 pbuf 的引用计数 。

void pbuf_ref(struct pbuf *p)

image.png

pbuf_cat


该函数用于连接两个pbuf,每个pbuf都可能是一个pbuf链。

void pbuf_cat(struct pbuf *h, struct pbuf *t)

image.png

使用此函数后,我们仅需要操作头部的pbuf即可,表示我们后面再也不会引用尾部的pbuf。 pbuf_clen得到的连接后的pbuf链中有2个pbuf。

pbuf_chain


将两个 pbuf(或 pbuf 链)链接在一起。一旦停止使用,调用者必须调用 pbuf_free(t)。如果不再使用 t,请改用 pbuf_cat()。

void pbuf_chain(struct pbuf *h, struct pbuf *t)

image.png

使用该函数会调整链中所有pbuf的tot_len字段、头的最后一个pbuf的next字段、尾的第一个pbuf的ref字段。

目录
相关文章
|
传感器
【STM32】I2C练习,SHT3X温度传感器的数据读取
【STM32】I2C练习,SHT3X温度传感器的数据读取
296 0
|
Linux 开发工具 内存技术
国产之路:复旦微zynq调试笔记2--PL网口
PL侧的网口需求相较于PS部分还是有一定区别的,主要需要添加axi ethernet 的移植
3530 0
|
12月前
|
算法 数据处理 C语言
C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合
本文深入解析了C语言中的位运算技巧,涵盖基本概念、应用场景、实用技巧及示例代码,并讨论了位运算的性能优势及其与其他数据结构和算法的结合,旨在帮助读者掌握这一高效的数据处理方法。
525 1
|
存储 数据管理 数据处理
处理STM32 DMA方式下的HAL_UART_ERROR_ORE错误
通过正确配置UART和DMA、实现有效的错误处理回调函数以及优化数据处理和缓冲区管理,可以有效处理STM32中DMA方式下的 `HAL_UART_ERROR_ORE`错误。这些方法确保了数据的高效传输和处理,避免了因数据溢出导致的通信中断和数据丢失。希望这些解决方案能够帮助您在实际应用中更好地应对和解决此类问题。
1672 0
|
存储 安全 Linux
从零开始学习DPDK:掌握这些常用库函数就够了(上)
从零开始学习DPDK:掌握这些常用库函数就够了
问题提解决:ERROR: Could not install packages due to an OSError: HTTPSConnectionPool(host=‘files.pythonhos
问题提解决:ERROR: Could not install packages due to an OSError: HTTPSConnectionPool(host=‘files.pythonhos
|
开发工具 Windows
OpenHarmony 3.2:制作OTA升级包,附脚本及配置
本文介绍了在OpenHarmony 3.2版本中手动制作OTA升级包的详细流程,包括编译镜像、创建OTA文件目录、编写配置文件、运行脚本制作升级包、推送验证以及OTA升级成功的标志和完整打印过程,并提供了一个基于RK3568的简要OTA打包脚本。
627 0
|
Linux 持续交付 开发工具
版本控制系统的选择:Git vs. Mercurial
【6月更文挑战第20天】Git vs. Mercurial: 两者都是流行的DVCS,Git由Linus Torvalds创建,以其速度和复杂分支管理著称,适合大型项目和有经验的开发者。Mercurial,由Matt Mackall开发,以其简洁命令行和易用性吸引初学者。Git社区更大,扩展更丰富,而Mercurial在某些场景下可能更直观。选择取决于项目需求、团队经验和偏好。
|
算法
数据结构和算法学习记录——时间复杂度的计算(嵌套循环、大O的渐进表示法、双重循环、常数循环、strchr、冒泡排序、二分查找、斐波那契数列递归)
数据结构和算法学习记录——时间复杂度的计算(嵌套循环、大O的渐进表示法、双重循环、常数循环、strchr、冒泡排序、二分查找、斐波那契数列递归)
901 1