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

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

3天內(nèi)不再提示

基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-LWIP的堆管理介紹

嵌入式USB開發(fā) ? 來源:嵌入式Lee ? 作者:嵌入式Lee ? 2023-09-08 08:40 ? 次閱讀

本文轉(zhuǎn)自公眾號歡迎關(guān)注

基于DWC_ether_qos的以太網(wǎng)驅(qū)動開發(fā)-LWIP的堆管理介紹 (qq.com)

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

一.前言

堆管理是重點的基礎(chǔ)代碼,需要重點關(guān)注,移植時也需要關(guān)注。所以這一篇就來講講LWIP的堆管理。

二.LWIP的堆管理實現(xiàn)

LWIP實現(xiàn)了內(nèi)部的堆管理,這樣無OS等環(huán)境也可以直接移植使用,不依賴系統(tǒng)的堆管理。

當然也可以配置為使用系統(tǒng)的堆管理。

源碼位于mem.c,mem.h

如果使能MEM_LIBC_MALLOC則使用系統(tǒng)的堆管理接口

需要配置以下宏

mem_clib_free

mem_clib_malloc

mem_clib_calloc

默認是

/* in case C library malloc() needs extra protection,

如果使能MEM_USE_POOLS則使用內(nèi)存池實現(xiàn),這個上一篇已經(jīng)講解了。

否則使用mem.c的實現(xiàn),我們重點關(guān)注這一部分。

三.堆的存儲分配

如果沒有定義LWIP_RAM_HEAP_POINTER則

mem.c中定義一個大數(shù)組LWIP_DECLARE_MEMORY_ALIGNED

大小是MEM_SIZE_ALIGNED + (2U * SIZEOF_STRUCT_MEM)

用戶可用空間是#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE)

即用戶定義的MEM_SIZE,默認值是1600

/**

這里多分配了2U * SIZEOF_STRUCT_MEM是一方面多一個ram_end標記末尾,作為末尾的邊界節(jié)點,一方面預留對齊的浪費空間。

用戶也可以直接定義宏LWIP_RAM_HEAP_POINTER指定存儲的位置。

個人覺得這里LWIP_RAM_HEAP_POINTER靜態(tài)指定,改為指針變量,初始化變量值為LWIP_RAM_HEAP_POINTER,然后也可以通過接口設定會更好。這樣用戶可以根據(jù)實際情況動態(tài)分配出這部分存儲來,否則靜態(tài)分配,程序不運行也要占用空間比較浪費。

LWIP_DECLARE_MEMORY_ALIGNED

實現(xiàn)如下

/** If you want to relocate the heap to external memory, simply define

四.源碼分析

4.1數(shù)據(jù)結(jié)構(gòu)

核心數(shù)據(jù)結(jié)構(gòu)如下struct mem

/**

* The heap is made up as a list of structs of this type.

* This does not have to be aligned since for getting its size,

* we only use the macro SIZEOF_STRUCT_MEM, which automatically aligns.

*/

struct mem {

/** index (-> ram[next]) of the next struct */

mem_size_t next;

/** index (-> ram[prev]) of the previous struct */

mem_size_t prev;

/** 1: this area is used; 0: this area is unused */

u8_t used;

#if MEM_OVERFLOW_CHECK

/** this keeps track of the user allocation size for guard checks */

mem_size_t user_size;

#endif

};

一個雙向鏈表來實現(xiàn),該結(jié)構(gòu)體描述某一個區(qū)塊,used表示當前區(qū)塊是否使用。

Next和prev分別指向前后區(qū)塊,用于入鏈表和出鏈表操作。

這里為什么沒有描述本區(qū)塊大小的字段呢?

因為可以直接從next減去當前區(qū)塊的基地址得到,所以不需要額外的大小信息了。

比如當前區(qū)塊基地址是ptr則當前區(qū)塊可用于分配的有效空間如下計算

(mem->next - (ptr + SIZEOF_STRUCT_MEM))

即后一個區(qū)塊的開始的地址-本區(qū)塊開始地址-信息頭。

這個實現(xiàn)其實和uCOS的堆管理實現(xiàn)差不多。

4.2接口

mem_init

初始化時,初始全局變量ram即對齊后的存儲空間,

lfree指向空閑塊的開頭,初始化時為ram,

lfree始終用于指向未分配的區(qū)塊。

此時只有一個整的未分配的區(qū)塊,next指向MEM_SIZE后,

MEM_SIZE外ram_end用于標記結(jié)束,這也是之前存儲多分配的原因。

wKgaomT6e8mAOc3CAABfv0oF-p8552.png

mem_malloc/mem_calloc

分配算法核心思想如下,

從lfree開始查找空閑空間大于等于需求size的塊。

如果找到了就分配它。

這里有一個處理,如果本塊比較大,則分配了size后還有剩余,所以要拆分,即分配出size后剩余的部分成為空閑塊。

這個到底多大要拆分,標準是大于等于(size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)拆分,即可用空間是MIN_SIZE_ALIGNED才拆分。

分配完后,如果分配出的塊剛好是lfree位置,則要更新lfree指向后續(xù)空閑塊。

因為lfree始終是指向的空閑塊,即lfree鏈接起來的都是空閑塊。分配出的塊就從lfree中去掉了。

比如分配黃色空間后如下

wKgZomT6e8mADuLYAABqy7Qyj1Y058.png

注意返回的是結(jié)構(gòu)體之后的可用空間部分。

mem_free

區(qū)塊鏈接到lfree空閑塊中去,如果該塊前后為空閑則和前后拼接成大的空閑塊。

mem = (struct mem *)(void *)((u8_t *)rmem - (SIZEOF_STRUCT_MEM + MEM_SANITY_OFFSET));

先偏移結(jié)構(gòu)到塊頭。

如果mem小于lfree則要更新lfree為mem。

核心處理是plug_holes,判斷mem前后是否空閑,如果是空閑則和前后合并。

mem_trim

縮小

如果本塊縮小后剩余的空間不夠SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED,則沒有必要縮小,不處理。

如果縮小后剩余空間大于上述大小則看next是否空閑如果是則和next合并,否則單獨獨立出來一個空閑塊。

五.總結(jié)

LWIP實現(xiàn)了小型的堆管理,這樣無OS也可以直接移植使用,另外也可以配置為實用內(nèi)存池和系統(tǒng)實現(xiàn),比較靈活。

審核編輯 黃宇

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

    關(guān)注

    40

    文章

    5288

    瀏覽量

    169659
收藏 人收藏

    評論

    相關(guān)推薦

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-MAC幀格式介紹

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

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-MDIO驅(qū)動編寫與測試

    本文轉(zhuǎn)自公眾號歡迎關(guān)注 基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-MDIO驅(qū)動編寫與測試 一.前言
    的頭像 發(fā)表于 08-30 09:37 ?3278次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-MDIO<b class='flag-5'>驅(qū)動</b>編寫與測試

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-描述符鏈表介紹

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

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-數(shù)據(jù)流驗證過程

    轉(zhuǎn)自公眾號歡迎關(guān)注 https://mp.weixin.qq.com/s/klrHhaLMM_0W3FGVwHXFkA 基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-數(shù)據(jù)流驗證過程
    的頭像 發(fā)表于 08-31 08:41 ?1649次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-數(shù)據(jù)流驗證過程

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-收發(fā)驅(qū)動編寫與調(diào)試

    本文轉(zhuǎn)自公眾號,歡迎關(guān)注 基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-收發(fā)驅(qū)動編寫與調(diào)試 (qq.com) https://mp.wei
    的頭像 發(fā)表于 09-05 08:47 ?1918次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-收發(fā)<b class='flag-5'>驅(qū)動</b>編寫與調(diào)試

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-無OS環(huán)境移植LWIP

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

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-LWIP的內(nèi)存池介紹

    本文轉(zhuǎn)自公眾號,歡迎關(guān)注 https://mp.weixin.qq.com/s/mBoGSf_u9edFF01U_OZT9g 一.前言 lwIP為基礎(chǔ)結(jié)構(gòu)提供了專用的內(nèi)存池管理,比如netconn
    的頭像 發(fā)表于 09-07 08:45 ?1341次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的內(nèi)存池<b class='flag-5'>介紹</b>

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-LWIP(內(nèi)存池)未對齊導致問題的案例分享

    管理中也用到了地址(指針)強制轉(zhuǎn)換所以也會遇到這個問題。對于老手比較容易發(fā)現(xiàn),對于新手可能會比較疑惑。所以也單獨分享一個案例吧,權(quán)當一個小的check list的case。 二
    的頭像 發(fā)表于 09-09 08:44 ?1522次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>的<b class='flag-5'>堆</b>(內(nèi)存池)未對齊導致問題的案例分享

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-RTOS環(huán)境移植LWIP與性能測試

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

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-LWIP在PC上進行開發(fā)調(diào)試

    本文轉(zhuǎn)自公眾號歡迎關(guān)注 基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-LWIP在PC上進行開發(fā)
    的頭像 發(fā)表于 09-11 08:40 ?1673次閱讀
    基于<b class='flag-5'>DWC_ether_qos</b>的<b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>驅(qū)動</b><b class='flag-5'>開發(fā)</b>-<b class='flag-5'>LWIP</b>在PC上進行<b class='flag-5'>開發(fā)</b>調(diào)試

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-LWIP的定時器模塊詳解

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

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-LWIP的ARP模塊介紹

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

    以太網(wǎng)Lwip例程

    以太網(wǎng)Lwip例程
    發(fā)表于 12-06 16:53 ?25次下載
    <b class='flag-5'>以太網(wǎng)</b><b class='flag-5'>Lwip</b>例程

    設計軟件核心以太網(wǎng)服務質(zhì)量數(shù)據(jù)手冊免費下載

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

    基于DWC_ether_qos以太網(wǎng)驅(qū)動開發(fā)-包過濾

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