99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

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

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

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

聊聊FreeRTOS內(nèi)存管理方案及相關(guān)的優(yōu)化措施

冬至子 ? 來(lái)源:劍一二 ? 作者:劍一二 ? 2023-11-13 11:28 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

FreeRTOS 作為一個(gè)嵌入式實(shí)時(shí)操作系統(tǒng),其運(yùn)行的環(huán)境一般資源有限,特別是其內(nèi)存資源,可能只有幾 M,甚至是幾十 KB。針對(duì)不同的應(yīng)用場(chǎng)景,F(xiàn)reeRTOS 源碼中提供了 5 種內(nèi)存管理方案。本文就來(lái)聊聊這些內(nèi)存管理方案以及相關(guān)的優(yōu)化措施。

內(nèi)存管理相關(guān)的代碼在 lib/FreeRTOS/portable/MemMang 目錄下,從 heap_1.c 到 heap_5.c,文件相互獨(dú)立,并提供統(tǒng)一接口

void *pvPortMalloc( size_t xWantedSize );
void vPortFree( void *pv );

而 heap 的定義,可以是一塊靜態(tài)分配的數(shù)組作為 heap,也可以是指定的一塊區(qū)域作為 heap,本文就以靜態(tài)數(shù)組為例進(jìn)行講解。

#if( configAPPLICATION_ALLOCATED_HEAP == 1)
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif

實(shí)際上,內(nèi)存釋放接口并不一定都有效,因?yàn)?heap_1 方案是不支持內(nèi)存釋放的。在 heap_1 中調(diào)用 pvPortMalloc() 的時(shí)候,其具體實(shí)現(xiàn)如下所示:

圖片

pucAligendHeap: 對(duì)齊后的 heap 起始地址。

xNextFreeByte: 記錄下一次分配內(nèi)存的偏移值,實(shí)際就是已分配內(nèi)存的總大小。

pvReturn = pucAlignedHeap + xNextFreeByte;
xNextFreeByte += xWantedSize;

每次分配的時(shí)候,返回 pucAligendHeap + xNextFreeByte 的地址,然后更新 xNextFreeByte。當(dāng)然了,整個(gè)分配過(guò)程中,還有一些對(duì)齊操作。由于分配后的內(nèi)存不能進(jìn)行釋放,所以這種分配方案適用于不需要頻繁申請(qǐng)釋放內(nèi)存的場(chǎng)景。

相對(duì)于 heap_1 方案,在 heap_2 中增加了內(nèi)存釋放的函數(shù)。其實(shí)現(xiàn)是在每一次分配的內(nèi)存中增加了一些描述信息(也就是多分配一個(gè)結(jié)構(gòu)體大小的內(nèi)存,用于保存描述信息),這樣在釋放的時(shí)候,就可以根據(jù)這些信息回收內(nèi)存。

typedef struct A_BLOCK_LINK {
    struct A_BLOCK_LINK *pxNextFreeBlock;
    size_t xBlockSize;
} BlockLink_t;

static const uint16_t heapSTRUCT_SIZE = (( sizeof( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 )) & ~portBYTE_ALIGNMENT_MASK );

xWantedSize += heapSTRUCT_SIZE;  /*每次分配的時(shí)候自動(dòng)加上描述結(jié)構(gòu)體的大小*/

描述信息結(jié)構(gòu)體中包含了一個(gè)鏈表指針,用于在釋放的時(shí)候,將該內(nèi)存加入到空閑鏈表中,每次分配內(nèi)存實(shí)際就是從空閑鏈表上進(jìn)行分配(初始狀態(tài),整個(gè)鏈表除了頭尾,就一個(gè)成員,就是整個(gè)空閑的 heap 塊)。xBlockSize 用于描述分配內(nèi)存的大小。

圖片

其中,xStart 和 xEnd 是空閑鏈的頭尾節(jié)點(diǎn)。初始狀態(tài)時(shí),整個(gè) heap 就是一個(gè)空閑塊。分配的時(shí)候,從頭遍歷空閑鏈,找到第一個(gè)滿足大小的塊,也就是最先匹配原則(first fit),從中分裂出所需的大小,然后將剩余的插入到空閑鏈中。而釋放就是將其插入到空閑鏈中。

需要注意的是,插入空閑鏈中,都是升序排列的,也就是說(shuō)在分配的時(shí)候,最先滿足的塊也是最優(yōu)的塊(best fit),可以減少碎片的產(chǎn)生。從實(shí)現(xiàn)來(lái)看,heap_2 雖然添加了釋放內(nèi)存函數(shù),但其在插入到空閑鏈的時(shí)候,沒(méi)有對(duì)相鄰的塊進(jìn)行合并,所以 heap_2 適用于操作固定大小內(nèi)存的場(chǎng)景。

heap_3 的方案沒(méi)有基于 heap_2 進(jìn)行優(yōu)化,而是直接使用 libc 庫(kù)中 malloc() / free() 接口,所以這里就不多做介紹。

事實(shí)上,相鄰塊合并功能是在 heap_4 中引入的。在將空閑塊插入到鏈表的時(shí)候,會(huì)判斷是否有空閑塊是相鄰的,如果相鄰就合并成一個(gè)更大的空閑塊,就能減少碎片的產(chǎn)生,進(jìn)而更適用于一般的內(nèi)存分配和釋放場(chǎng)景。注意 heap_4 在插入空閑鏈的時(shí)候,不再是升序排列,而是根據(jù)地址大小進(jìn)行排列,這樣便于判斷量表中前后兩個(gè)塊是否相鄰。

圖片

heap_5 相對(duì)于 heap_4 方案并沒(méi)有進(jìn)行算法上的優(yōu)化,它添加了一個(gè)接口可以指定某個(gè)內(nèi)存塊作為 heap。

void vPortDefineHeapRegions( const HeapRegion_t * const pRegions );

在前幾種內(nèi)存管理方案中,除了 heap_3,內(nèi)存塊都是靜態(tài)分配的。而在 heap_5 中 heap 不再是靜態(tài)定義的全局變量,而是需要顯示指定的一塊內(nèi)存區(qū)域作為 heap。這樣的好處就是,heap 的來(lái)源更加靈活,可以是和運(yùn)行空間不連續(xù)的一塊內(nèi)存,也可以將多個(gè)不連續(xù)的內(nèi)存塊作為 heap 進(jìn)行管理。

以上就介紹了 FreeRTOS 中原生的 5 種內(nèi)存管理方案??梢钥闯?,后面的內(nèi)存管理方案對(duì)前面的管理方案是兼容的,比如 heap_5 可以替代 heap_1, heap_2 和 heap_4 方案。這里可能就有個(gè)疑問(wèn)了,為什么不直接用 heap_5 方案呢?更豐富的功能,意味著復(fù)雜的一些實(shí)現(xiàn),在一些簡(jiǎn)單的場(chǎng)景中,heap_5 分配速度可能沒(méi)有 heap_1 或者 heap_2 來(lái)得快,所以 heap_1,heap_2 等方案也有其存在的意義。

在實(shí)際場(chǎng)景中,比如隨機(jī)的分配和釋放,而且分配的大小也不一致,這個(gè)時(shí)候,一般會(huì)選擇 heap_4。heap_4 引入了內(nèi)存合并功能,可以減少內(nèi)存碎片,但和 heap_2 相比,也把最優(yōu)匹配的原則去掉了。如下圖所示:

圖片

當(dāng)要分配一個(gè) 32Bytes 的內(nèi)存(經(jīng)過(guò)對(duì)齊等處理后的大?。凑?heap_4 的分配方案,最先匹配原則,會(huì)從 56Bytes 大小的塊中分配一個(gè)32Bytes 出去,而不是從第二個(gè)空閑塊,剛剛好是 32Bytes 的塊中分配。這樣的分配方法就會(huì)產(chǎn)生碎片。碎片多了就會(huì)導(dǎo)致空閑內(nèi)存看似很多,但大的內(nèi)存塊已經(jīng)沒(méi)有了。

優(yōu)化的辦法也很簡(jiǎn)單,就是遍歷整個(gè)空閑鏈表,找到最優(yōu)的一個(gè)塊,其修改方法就是在原來(lái) first fit 的基礎(chǔ)上,遍歷剩余的鏈表:

/* first fit */
while ((pxBlock- >xBlockSize < xWantedSize) && (pxBlock- >pxNextFreeBlock != NULL))
{
   pxPreviousBlock = pxBlock;
   pxBlock = pxBlock- >pxNextFreeBlock;
}
/* best fit */
BlockLink_t *pxTmp = pxBlock;
BlockLink_t *pxPreTmp = pxPreviousBlock;while (pxTmp != pxEnd){
   if ((pxTmp- >xBlockSize >= xWantedSize) && (pxTmp- >xBlockSize < pxBlock- >xBlockSize))
  {
       pxBlock = pxTmp;
       pxPreviousBlock = pxPreTmp;
  }
   pxPreTmp = pxTmp;
   pxTmp = pxTmp- >pxNextFreeBlock;
}

最優(yōu)匹配的引入,不是一定就比原來(lái)的方案效果要好,因?yàn)楸闅v整個(gè)空閑鏈表,會(huì)導(dǎo)致分配內(nèi)存的時(shí)間變長(zhǎng)。這在某些對(duì)實(shí)時(shí)要求較高的環(huán)境中就不適應(yīng)了,比如在一些網(wǎng)絡(luò)環(huán)境中可能會(huì)因?yàn)槌瑫r(shí)而導(dǎo)致功能不正常。

其實(shí)分配快,內(nèi)存碎片少的方法有很多,只是他們的實(shí)現(xiàn)成本會(huì)有所不同,一個(gè)算法不可能適用所有的場(chǎng)景,分配方案中也沒(méi)有哪個(gè)比哪個(gè)一定更好,找到適合應(yīng)用場(chǎng)景的就是好的算法。這也許就是 FreeRTOS 中保留了多種分配方案的原因吧。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    FreeRTOS內(nèi)存機(jī)制詳解

    FreeRTOS是一種實(shí)時(shí)操作系統(tǒng),它提供了多種內(nèi)存分配方式,包括動(dòng)態(tài)內(nèi)存分配和靜態(tài)內(nèi)存分配。
    的頭像 發(fā)表于 12-31 16:49 ?3373次閱讀
    <b class='flag-5'>FreeRTOS</b><b class='flag-5'>內(nèi)存</b>機(jī)制詳解

    第28章 FreeRTOS動(dòng)態(tài)內(nèi)存管理

    28.4 實(shí)驗(yàn)例程說(shuō)明28.5總結(jié)28.1動(dòng)態(tài)內(nèi)存管理介紹 FreeRTOS支持5種動(dòng)態(tài)內(nèi)存管理方案
    發(fā)表于 09-11 07:15

    FreeRTOS內(nèi)存管理的算法解析?

    關(guān)于FreeRTOS內(nèi)存管理,有人測(cè)試過(guò)它給定的算法么?會(huì)不會(huì)有內(nèi)存碎片的出現(xiàn),如果產(chǎn)品一直運(yùn)行,會(huì)不會(huì)出現(xiàn)內(nèi)存崩潰的情況。求證啊。目前用h
    發(fā)表于 07-30 11:39

    Freertos關(guān)于堆內(nèi)存管理相關(guān)資料分享

    內(nèi)存管理Malloc、Free防止內(nèi)存碎片Freertos
    發(fā)表于 12-27 08:12

    什么是內(nèi)存優(yōu)化?有那些優(yōu)化措施?

    什么是內(nèi)存優(yōu)化?有那些優(yōu)化措施?
    發(fā)表于 01-14 06:22

    通信設(shè)備中內(nèi)存管理優(yōu)化

    通過(guò)對(duì)內(nèi)存管理的分析,提出了內(nèi)存優(yōu)化算法。該算法解決了通信設(shè)備中由于大量消息的發(fā)送導(dǎo)致內(nèi)存管理
    發(fā)表于 02-21 11:42 ?22次下載

    FreeRTOS代碼剖析之1:內(nèi)存管理Heap

    內(nèi)存管理是一個(gè)操作系統(tǒng)的重要組成部分之一,所有應(yīng)用程序都離不開(kāi)操作系統(tǒng)的內(nèi)存管理。因此,在剖析FreeRTOS的內(nèi)核代碼之前,前對(duì)
    發(fā)表于 02-09 05:25 ?1123次閱讀
    <b class='flag-5'>FreeRTOS</b>代碼剖析之1:<b class='flag-5'>內(nèi)存</b><b class='flag-5'>管理</b>Heap

    FreeRTOS代碼剖析之3:內(nèi)存管理Heap

    FreeRTOS8.0.1的第三個(gè)模型Heap_3,可以說(shuō)是最容易理解的一個(gè)內(nèi)存管理模型。因?yàn)樵谶@個(gè)模型里,FreeRTOS直接將標(biāo)準(zhǔn)C庫(kù)中的malloc()和free()進(jìn)行加工打
    發(fā)表于 02-09 05:30 ?550次閱讀

    嵌入式操作系統(tǒng)FreeRTOS內(nèi)存如何管理和堆

    嵌入式操作系統(tǒng)FreeRTOS內(nèi)存管理和堆
    的頭像 發(fā)表于 01-10 15:17 ?5301次閱讀
    嵌入式操作系統(tǒng)<b class='flag-5'>FreeRTOS</b><b class='flag-5'>內(nèi)存</b>如何<b class='flag-5'>管理</b>和堆

    FreeRTOS高級(jí)篇7---FreeRTOS內(nèi)存管理分析

    FreeRTOS操作系統(tǒng)將內(nèi)核與內(nèi)存管理分開(kāi)實(shí)現(xiàn),操作系統(tǒng)內(nèi)核僅規(guī)定了必要的內(nèi)存管理函數(shù)原型,而不關(guān)心這些
    發(fā)表于 01-26 17:36 ?8次下載
    <b class='flag-5'>FreeRTOS</b>高級(jí)篇7---<b class='flag-5'>FreeRTOS</b><b class='flag-5'>內(nèi)存</b><b class='flag-5'>管理</b>分析

    FreeRTOS系列第8篇---FreeRTOS內(nèi)存管理

    本文介紹內(nèi)存管理的基礎(chǔ)知識(shí),詳細(xì)源碼分析見(jiàn)《 FreeRTOS高級(jí)篇7---FreeRTOS內(nèi)存管理
    發(fā)表于 01-26 17:56 ?17次下載
    <b class='flag-5'>FreeRTOS</b>系列第8篇---<b class='flag-5'>FreeRTOS</b><b class='flag-5'>內(nèi)存</b><b class='flag-5'>管理</b>

    FreeRTOS的源碼下載

    內(nèi)存管理文件在FreeRTOS\portable\MemMang文件夾下,FreeRTOS提供了五種內(nèi)存
    的頭像 發(fā)表于 02-10 11:00 ?5979次閱讀
    <b class='flag-5'>FreeRTOS</b>的源碼下載

    freeRTOS源碼中內(nèi)存管理方案

    freeRTOS源碼中提供了五種內(nèi)存管理方案,可以說(shuō)是很方便了。實(shí)際需要使用哪一種,可以根據(jù)自己項(xiàng)目的需要進(jìn)行選擇,都是可以的。
    的頭像 發(fā)表于 02-10 11:11 ?1188次閱讀

    FreeRTOS內(nèi)存管理簡(jiǎn)介

    ,比如任務(wù)創(chuàng)建函數(shù) xTaskCreateStatic(),使用此函數(shù)創(chuàng)建任務(wù)的時(shí)候需要由用戶定義任務(wù)堆棧,我們不討論這種靜態(tài)方法。 使用動(dòng)態(tài)內(nèi)存管理的時(shí)候 FreeRTOS 內(nèi)核在創(chuàng)建任務(wù)、隊(duì)列、信號(hào)量的時(shí)候會(huì)動(dòng)態(tài)的申請(qǐng) RA
    的頭像 發(fā)表于 07-30 10:26 ?941次閱讀

    FreeRTOS內(nèi)存管理實(shí)現(xiàn)

    FreeRTOS是一個(gè)為嵌入式系統(tǒng)設(shè)計(jì)的開(kāi)源實(shí)時(shí)操作系統(tǒng)。它提供了一個(gè)多任務(wù)內(nèi)核和一系列功能,適合在資源受限的設(shè)備上管理實(shí)時(shí)任務(wù)和應(yīng)用程序。FreeRTOS內(nèi)存
    的頭像 發(fā)表于 10-10 16:17 ?1156次閱讀
    <b class='flag-5'>FreeRTOS</b><b class='flag-5'>內(nèi)存</b><b class='flag-5'>管理</b>實(shí)現(xiàn)