温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

SylixOS中netdev_pbuf_alloc函数分析

发布时间:2020-08-04 01:45:24 来源:网络 阅读:797 作者:诸葛一帆丶 栏目:编程语言

1.netdev_pbuf_alloc函数简介

netdev_pbuf_alloc是网卡驱动中的内存申请函数,申请一块缓冲区用于存放网络报文数据。

2.pbuf结构分析

netdev_pbuf_alloc函数以pbuf结构申请内存空间,如程序清单 2.1所示。

程序清单 2.1  pbuf结构

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

3.pbuf_alloc函数封装

netdev_pbuf_alloc函数是pbuf_alloc函数的函数封装,对外提供的函数接口只带有一个参数用于指定申请的缓冲区大小。而pbuf_alloc函数有三个参数,分别是申请的pbuf数据缓冲区是否带有偏移,数据缓冲区大小及缓冲区类型。在netdev_pbuf_alloc函数中,申请的pbuf结构缓冲区数据偏移固定为0,缓冲区类型为PBUF_POOL。netdev_pbuf_alloc函数传入的第二个参数缓冲区大小在调用pbuf_alloc函数申请pbuf结构时会被增加一个reserve长度,用于协议栈中的部分特殊操作。

3.1 pbuf_alloc函数第一个参数分析

在网络中通信的数据报文,除了真正的数据段外,还包括了TCP/IP各层协议的报文头。如用户有特殊需求,要在应用层构建报文并直接通过网卡驱动发送,则需要申请pbuf结构的数据缓冲区带有各层偏移,如程序清单 3.1所示。

程序清单 3.1  pbuf_alloc第一个参数分析

typedef enum {
  PBUF_TRANSPORT,                                        /*  传输层报文头偏移          */
  PBUF_IP,                                               /*  IP层报文头偏移           */
  PBUF_LINK,                                             /*  链路层报文头偏移         */
  PBUF_RAW_TX,                                           /*  封装链路层偏移           */
  PBUF_RAW                                               /*  无偏移                 */
} pbuf_layer;

3.2 pbuf_alloc函数第三个参数分析

申请pbuf结构需要指定pbuf类型,原因是不同类型的pbuf申请内存的方式不同,如程序清单 3.2所示。

程序清单 3.2  pbuf_alloc第三个参数分析

typedef enum {
  PBUF_RAM,                                                 /*  内存堆分配             */
  PBUF_ROM,                                                 /*  指向ROM空间内数据      */
  PBUF_REF,                                                 /*  指向RAM空间内数据      */
  PBUF_POOL                                                 /*  内存池分配             */
} pbuf_type;

PBUF_RAM类型的pbuf主要通过内存堆分配得到,协议栈划分了一块空间用于申请PBUF_RAM类型的pbuf,划分的空间大小通过“libsylixos/SylixOS/config/net/net_perf_cfg.h”中的“LW_CFG_LWIP_MEM_SIZE”宏配置。

PBUF_REF和PBUF_ROM类型的pbuf基本相同,前者指向ROM空间内的某段数据,而后者指向RAM空间内的某段数据。PBUF_REF和PBUF_ROM类型的pbuf通过“libsylixos/SylixOS/config/net/net_perf_cfg.h”中的“LW_CFG_LWIP_NUM_PBUFS”宏配置在内存池中预分配pbuf的最大数量。

PBUF_POOL类型的pbuf通过内存池分配,这种类型的pbuf可以在极短时间内得到分配,在网卡驱动接收数据时,一般采用这种方式。协议栈会在内存池中预先分配适当数量和大小的内存空间,通过“libsylixos/SylixOS/config/net/net_perf_cfg.h”中的“LW_CFG_LWIP_POOL_SIZE和LW_CFG_LWIP_NUM_POOLS”宏配置。

3.3 PBUF_POOL类型pbuf申请流程

netdev_pbuf_alloc函数申请PBUF_POOL类型pbuf,若申请的缓冲区大于PBUF_POOL池中单个pbuf缓冲区长度,系统会分配多个固定大小的PBUF_POOL类型pbuf,并把这些pbuf链成一个链表,以满足用户的分配空间请求,如图 3.1所示。

SylixOS中netdev_pbuf_alloc函数分析

3.1  PBUF_POOL类型pbuf申请流程

4.实际应用

网卡驱动收到数据后,会调用netdev_pbuf_alloc函数申请pbuf结构,并将数据拷贝至pbuf。当有大量数据被网卡驱动接收时,可能会造成申请pbuf结构失败,原因是系统预分配的内存池中的pbuf结构已经全部被申请,还未被释放。可以尝试通过“libsylixos/SylixOS/config/net/net_perf_cfg.h”中的“LW_CFG_LWIP_POOL_SIZE和LW_CFG_LWIP_NUM_POOLS”宏配置增大pbuf缓冲区大小和数量解决pbuf结构申请失败问题。


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI