精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于DWC_ether_qos的以太網驅動開發-LWIP的內存池介紹

嵌入式USB開發 ? 來源:嵌入式Lee ? 作者:嵌入式Lee ? 2023-09-07 08:45 ? 次閱讀

本文轉自公眾號,歡迎關注

https://mp.weixin.qq.com/s/mBoGSf_u9edFF01U_OZT9g

一.前言

lwIP為基礎結構提供了專用的內存池管理,比如netconn,protocol控制塊,包緩存等。在memp.c下實現。

LWIP的內存池有兩種方式實現,通過宏MEMP_MEM_MALLOC配置,默認opt.h中配置為0.

配置為1使用mem_malloc/mem_free mem.c

配置為0使用單獨實現memp.c。

我們這里重點講后者。

二.相關源碼

src/core/memp.c

src/include/lwip/memp.h

src/include/lwip/priv/memp_std.h

src/include/lwip/priv/memp_priv.h

三.源碼分析

3.1數據結構

內存池的關鍵數據結構是struct memp_desc對應內存池節點,一個類型的內存池是一個節點,

多個類型的內存池可以作為鏈表一起管理。

內存池最基本的數據結構是由宏LWIP_MEMPOOL_DECLARE定義的,

該宏在memp.h根據MEMP_MEM_MALLOC的配置實現為

#define LWIP_MEMPOOL_DECLARE(name,num,size,desc)

#define LWIP_MEMPOOL_DECLARE(name,num,size,desc)

前者是使用mem_malloc/mem_free實現內存池時使用,后者是單獨實現時使用,我們重點關注后者。

其中LWIP_DECLARE_MEMORY_ALIGNED可以用戶實現,如果用戶未定義,arch.h默認是

#ifndef LWIP_DECLARE_MEMORY_ALIGNED

即定義了一個數組variable_name,其大小是LWIP_MEM_ALIGN_BUFFER(size)

LWIP_MEM_ALIGN_BUFFER可以用戶實現,如果用戶未定義,arch.h中默認為

#ifndef LWIP_MEM_ALIGN_BUFFER

即人為的放大了,保證對齊之后始終能保證有足夠size的空間。

比如size是8,但是數組的基地址則可能是任意地址,比如是0x0001,要保證地址4字節對齊,

那么只能往后移動實際用的地址是0x0004,那么前面就浪費了3字節,此時8+(4-1)多分配3字節則浪費了這3字節也能保證剩余8字節可用8+(4-1)-3=8。

如果地址是0x0002則浪費2字節,可用8+(4-1)-2>8大于2字節,其他情況類似。

其中MEM_ALIGNMENT在opt中默認為1,用戶在lwipopts.h中可以配置。

繼續來看宏LWIP_MEMPOOL_DECLARE_STATS_INSTANCE和LWIP_MEMPOOL_DECLARE_STATS_REFERENCE,memp_priv.h中

如果定義了宏MEMP_STATS即使能統計信息,則LWIP_MEMPOOL_DECLARE_STATS_INSTANCE定義了結構體變量static struct stats_mem name;

LWIP_MEMPOOL_DECLARE_STATS_REFERENCE即&name,該變量地址

否則都是空

#if MEMP_STATS

其中stats.h中truct stats_mem如下

/** Memory stats */

繼續看DECLARE_LWIP_MEMPOOL_DESC,memp_priv.h中

如果定義了宏LWIP_DEBUG,MEMP_OVERFLOW_CHECK,LWIP_STATS_DISPLAY三者之一,實際就是成員賦值為desc,否則為空。

#if defined(LWIP_DEBUG) || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY

繼續看LWIP_MEM_ALIGN_SIZE,在arch.h中默認實現,即向上對齊,MEM_ALIGNMENT對齊必須是2的指數。

#ifndef LWIP_MEM_ALIGN_SIZE

最終LWIP_MEMPOOL_DECLARE(name,num,size,desc)展開后為

u8_t memp_memory_name_base[LWIP_MEM_ALIGN_BUFFER(((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size))))]

static struct stats_mem memp_stats_name;

static struct memp*memp_tab_name;

const struct memp_desc memp_name= {

desc,

&memp_stats_name,

LWIP_MEM_ALIGN_SIZE(size),

num,

memp_memory_ name_base,

&memp_tab_name

};

即定義一個數組作為存儲,一個統計變量,一個static struct memp指針變量,一個結構變量static struct memp。

其中struct memp

#if !MEMP_MEM_MALLOC || MEMP_OVERFLOW_CHECK

其中struct memp_desc

/** Memory pool descriptor */

3.2內存池接口

LWIP_MEMPOOL_DECLARE(my_private_pool, 10, sizeof(foo), "Some description")

即上面數據結構說明的,使用該宏定義節點相關存儲數組,變量等。

LWIP_MEMPOOL_INIT(my_private_pool) ->memp_init_pool

將節點的存儲鏈表形式串起來。

*desc->tab指向最后一個item。

void* my_new_mem = LWIP_MEMPOOL_ALLOC(my_private_pool);->memp_malloc_pool

從鏈表中取出一個item。

LWIP_MEMPOOL_FREE(my_private_pool, my_new_mem);->memp_free_pool

Item插入到鏈表中

這里管理內存池實際可以用上述的鏈表形式,也可以用bitmap形式。

上述用鏈表形式每次malloc(出鏈表),free(入鏈表)都是堆鏈表尾,*desc->tab操作,執行時間固定。

而bitmap需要使用for循環去查詢空閑bit執行時間不固定,當然也可以使用類似ucOS優先級調度的查表法來優化。

四.內部使用的內存池

數據結構中分析了LWIP_MEMPOOL_DECLARE宏,實際就是定義內存節點相關的變量(存儲數組,統計變量,描述結構等)

用戶可以直接使用內存池接口。

而lwip內部也使用了內存池進行管理,見memp.c/memp.h

4.1內部使用內存池

memp.h中

/* run once with empty definition to handle all custom includes in lwippools.h */

第一個#include "lwip/priv/memp_std.h"前因為LWIP_MEMPOOL為空,所以include memp_std.h進來所有的LWIP_MEMPOOL為空,此時相當于只是include進來memp_std.h中包含的頭文件。

后一個#include "lwip/priv/memp_std.h"前LWIP_MEMPOOL(name,num,size,desc) MEMP_##name,

所以include memp_std.h后相當于,定義了MEMP_xxx的枚舉

展開就是(當然要對應的宏使能才會有)

typedef enum {

RAW_PCB_RAW_PCB,

UDP_PCB_UDP_PCB,

......

MEMP_MAX

} memp_t;

注意每次memp_std.h中都undef了相關宏,所以不影響后續使用。

這里是一個小的編程技巧,一個頭文件不同的宏配置下展開為不同的內容。

而memp.c中

#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc)

第一個包含memp_std.h 根據LWIP_MEMPOOL_DECLARE,定義了各個內存池節點

后一個memp_std.h則根據LWIP_MEMPOOL(name,num,size,desc) & name展開

即定義了一個結構體數組,數組的成員即上面定義的內存池節點。

const struct memp_desc *const memp_pools[MEMP_MAX] = {

&RAW_PCB,

......

};

所有使用到內建內存池總結如下

4.2內部使用內存池接口

以下都是調用內存池接口,不再贅述。

memp_free

memp_free_pool

memp_malloc

memp_malloc_pool

memp_init

五.堆使用內存池實現

前面我們看到定義宏MEMP_MEM_MALLOC,memp.c內存池可以使用mem.c堆實現.

反過來定義宏MEM_USE_POOLS,mem.c也可以用memp.c內存池實現.所以可以看出LWIP的堆管理實現方式比較靈活的,可以根據實際應用配置。

在opt.h中MEM_USE_POOLS是默認配置為0的,可以在lwipopts.h中修改配置。

#if !defined MEM_USE_POOLS || defined __DOXYGEN__

如果MEMP_USE_CUSTOM_POOLS配置為1,則MEMP_USE_CUSTOM_POOLS也要配置為1

此時

memp_std.h中

/*

可以看出,用戶必須提供lwippools.h文件,申明對應的內存池節點。

即在原來memp_t和memp_pools的基礎上后面繼續添加節點。

內容如下

LWIP_MALLOC_MEMPOOL_START

此時mem_malloc則從

memp_pools中

MEMP_POOL_FIRST~MEMP_POOL_LAST處

搜搜,找到有節點有空閑空間,大小滿足所需大小的即止。

即如下獲取MEMP_POOL_HELPER_FIRST和MEMP_POOL_HELPER_LAST

#if MEM_USE_POOLS && MEMP_USE_CUSTOM_POOLS

六.總結

內存池適合分配大小固定的動態內存分配,比如用于協議包等的緩存等;

算法簡單,執行時間固定,比較可靠。但是其存儲是單獨分配的靜態數組,相當于需要固定分配一部分空間,不管對應的程序運行還是不運行,比較浪費空間。

當然也可以定義宏MEMP_MEM_MALLOC使用mem_malloc堆的方式實現,而mem_malloc進一步可以配置使用LWIP的實現還是使用系統的malloc(配置宏MEM_LIBC_MALLOC)。

此時和系統堆共用,這樣存儲利用率更高。

LWIP內部實現了堆和內存池管理可以直接使用,也可以配置使用系統的堆管理,非常靈活,移植性也非常好。

wKgaomT5Jw6AbNkLAAPYEkmgmX8781.png

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 以太網
    +關注

    關注

    40

    文章

    5385

    瀏覽量

    171161
  • 內存
    +關注

    關注

    8

    文章

    3004

    瀏覽量

    73900
  • 驅動開發
    +關注

    關注

    0

    文章

    130

    瀏覽量

    12065
收藏 人收藏

    評論

    相關推薦

    基于DWC_ether_qos以太網驅動開發-MAC幀格式介紹

    本文轉自公眾號,歡迎關注 基于DWC_ether_qos以太網驅動開發-MAC幀格式介紹 (qq.com) 一.前言 ? 在
    的頭像 發表于 08-30 09:23 ?2236次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-MAC幀格式<b class='flag-5'>介紹</b>

    基于DWC_ether_qos以太網驅動開發-MDIO驅動編寫與測試

    本文轉自公眾號歡迎關注 基于DWC_ether_qos以太網驅動開發-MDIO驅動編寫與測試 一.前言
    的頭像 發表于 08-30 09:37 ?3635次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-MDIO<b class='flag-5'>驅動</b>編寫與測試

    基于DWC_ether_qos以太網驅動開發-描述符鏈表介紹

    本文轉自公眾號歡迎關注 一.描述符概述 1.0 前言 對于DWC Ethernet QoS驅動的編寫來說,初始化完成之后,核心操作就是DMA的描述符鏈表配置(linked list
    的頭像 發表于 08-30 09:39 ?4384次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-描述符鏈表<b class='flag-5'>介紹</b>

    基于DWC_ether_qos以太網驅動開發-數據流驗證過程

    轉自公眾號歡迎關注 https://mp.weixin.qq.com/s/klrHhaLMM_0W3FGVwHXFkA 基于DWC_ether_qos以太網驅動開發-數據流驗證過程
    的頭像 發表于 08-31 08:41 ?1908次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-數據流驗證過程

    基于DWC_ether_qos以太網驅動開發-收發驅動編寫與調試

    本文轉自公眾號,歡迎關注 基于DWC_ether_qos以太網驅動開發-收發驅動編寫與調試 (qq.com) https://mp.wei
    的頭像 發表于 09-05 08:47 ?2229次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-收發<b class='flag-5'>驅動</b>編寫與調試

    基于DWC_ether_qos以太網驅動開發-無OS環境移植LWIP

    本文轉自公眾號歡迎關注 基于DWC_ether_qos以太網驅動開發-無OS環境移植LWIP (qq.com) https://mp.we
    的頭像 發表于 09-06 08:40 ?1515次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-無OS環境移植<b class='flag-5'>LWIP</b>

    基于DWC_ether_qos以太網驅動開發-LWIP的堆管理介紹

    本文轉自公眾號歡迎關注 基于DWC_ether_qos以太網驅動開發-LWIP的堆管理介紹 (
    的頭像 發表于 09-08 08:40 ?1219次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-<b class='flag-5'>LWIP</b>的堆管理<b class='flag-5'>介紹</b>

    基于DWC_ether_qos以太網驅動開發-LWIP的堆(內存)未對齊導致問題的案例分享

    本文轉自公眾號歡迎關注 https://mp.weixin.qq.com/s/ErIa2ss2YZLGYbSwoJEzog 一.?前言 內存未對齊訪問問題這個已經是老生常談的問題了, 由于LWIP
    的頭像 發表于 09-09 08:44 ?1671次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-<b class='flag-5'>LWIP</b>的堆(<b class='flag-5'>內存</b><b class='flag-5'>池</b>)未對齊導致問題的案例分享

    基于DWC_ether_qos以太網驅動開發-RTOS環境移植LWIP與性能測試

    本文轉自公眾號,歡迎關注 基于DWC_ether_qos以太網驅動開發-RTOS環境移植LWIP與性能測試 (qq.com) https:
    的頭像 發表于 09-11 11:20 ?1941次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-RTOS環境移植<b class='flag-5'>LWIP</b>與性能測試

    基于DWC_ether_qos以太網驅動開發-LWIP在PC上進行開發調試

    本文轉自公眾號歡迎關注 基于DWC_ether_qos以太網驅動開發-LWIP在PC上進行開發
    的頭像 發表于 09-11 08:40 ?1918次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-<b class='flag-5'>LWIP</b>在PC上進行<b class='flag-5'>開發</b>調試

    基于DWC_ether_qos以太網驅動開發-LWIP的定時器模塊詳解

    一. 前言 LWIP的定時器模塊,實現了通用的軟件定時器,用于內部的周期事件處理,比如arp,tcp的超時等,用戶也可以使用。這一篇來分析該模塊的實現。 二.代碼分析 2.1源碼 源碼
    的頭像 發表于 09-18 09:33 ?1581次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-<b class='flag-5'>LWIP</b>的定時器模塊詳解

    基于DWC_ether_qos以太網驅動開發-LWIP的ARP模塊介紹

    TCP/IP通訊第一步需要先調通ARP,否則TCP/IP包都不知道MAC地址要發給誰。這一篇來基于LWIP的ARP實現進行相關的分析。
    的頭像 發表于 09-18 09:34 ?1780次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-<b class='flag-5'>LWIP</b>的ARP模塊<b class='flag-5'>介紹</b>

    以太網Lwip例程

    以太網Lwip例程
    發表于 12-06 16:53 ?26次下載
    <b class='flag-5'>以太網</b><b class='flag-5'>Lwip</b>例程

    設計軟件核心以太網服務質量數據手冊免費下載

    本文描述Synopsys設計軟件核心以太網服務質量DWC以太網QoS核心5.10A。DWC以太網
    發表于 10-23 08:00 ?16次下載
    設計軟件核心<b class='flag-5'>以太網</b>服務質量數據手冊免費下載

    基于DWC_ether_qos以太網驅動開發-包過濾

    以太網上數據非常多,如果所有數據都接收交給軟件去處理軟件負載會非常重,所以一般只需要接收發給自己的數據即可
    的頭像 發表于 09-02 09:19 ?1644次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-包過濾