FreeRTOS动态内存分配怎么管理heap5
发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,今天小编给大家分享一下FreeRTOS动态内存分配怎么管理heap5的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收
千家信息网最后更新 2026年11月02日FreeRTOS动态内存分配怎么管理heap5
今天小编给大家分享一下FreeRTOS动态内存分配怎么管理heap5的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。
heap_5.c
heap5与heap4分配释放算法完全相同,只是heap5支持管理多块不连续的内存,本质是将多块不连续内存用链表串成一整块内存,再用heap4算法来分配释放。若使用heap5则在涉及到分配释放的函数调用时要先调用vPortDefineHeapRegions把多块不连续内存串成一块初始化。
vPortDefineHeapRegions
此函数原型
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ),
参数在portable.h中定义,如下
/* Used by heap_5.c. */typedef struct HeapRegion{ uint8_t *pucStartAddress;//指向内存块首地址 size_t xSizeInBytes;//此内存块大小} HeapRegion_t;比如有2块内存要用heap5管理,地址0x80000000,大小0x10000,地址0x90000000,大小0xa0000,则如下定义该结构体数组
HeapRegion_t xHeapRegions[] = { { ( uint8_t * ) 0x80000000UL, 0x10000 }, { ( uint8_t * ) 0x90000000UL, 0xa0000 }, { NULL, 0 } };注意地址顺序要从小到大,最后要以{NULL,0}结尾(源码是以0做判断结束循环)
下面看初始化源码
void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ){BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock;size_t xAlignedHeap;size_t xTotalRegionSize, xTotalHeapSize = 0;BaseType_t xDefinedRegions = 0;size_t xAddress;const HeapRegion_t *pxHeapRegion; /* Can only call once! */ configASSERT( pxEnd == NULL ); pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); while( pxHeapRegion->xSizeInBytes > 0 ) { xTotalRegionSize = pxHeapRegion->xSizeInBytes; /* Ensure the heap region starts on a correctly aligned boundary. */ xAddress = ( size_t ) pxHeapRegion->pucStartAddress; if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) { xAddress += ( portBYTE_ALIGNMENT - 1 ); xAddress &= ~portBYTE_ALIGNMENT_MASK; /* Adjust the size for the bytes lost to alignment. */ xTotalRegionSize -= xAddress - ( size_t ) pxHeapRegion->pucStartAddress; } xAlignedHeap = xAddress; /* Set xStart if it has not already been set. */ if( xDefinedRegions == 0 ) { /* xStart is used to hold a pointer to the first item in the list of free blocks. The void cast is used to prevent compiler warnings. */ xStart.pxNextFreeBlock = ( BlockLink_t * ) xAlignedHeap; xStart.xBlockSize = ( size_t ) 0; } else { /* Should only get here if one region has already been added to the heap. */ configASSERT( pxEnd != NULL ); /* Check blocks are passed in with increasing start addresses. */ configASSERT( xAddress > ( size_t ) pxEnd ); } /* Remember the location of the end marker in the previous region, if any. */ pxPreviousFreeBlock = pxEnd; /* pxEnd is used to mark the end of the list of free blocks and is inserted at the end of the region space. */ xAddress = xAlignedHeap + xTotalRegionSize; xAddress -= xHeapStructSize; xAddress &= ~portBYTE_ALIGNMENT_MASK; pxEnd = ( BlockLink_t * ) xAddress; pxEnd->xBlockSize = 0; pxEnd->pxNextFreeBlock = NULL; /* To start with there is a single free block in this region that is sized to take up the entire heap region minus the space taken by the free block structure. */ pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap; pxFirstFreeBlockInRegion->xBlockSize = xAddress - ( size_t ) pxFirstFreeBlockInRegion; pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd; /* If this is not the first region that makes up the entire heap space then link the previous region to this region. */ if( pxPreviousFreeBlock != NULL ) { pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion; } xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize; /* Move onto the next HeapRegion_t structure. */ //下一块 xDefinedRegions++; pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); } xMinimumEverFreeBytesRemaining = xTotalHeapSize; xFreeBytesRemaining = xTotalHeapSize; /* Check something was actually defined before it is accessed. */ configASSERT( xTotalHeapSize ); /* Work out the position of the top bit in a size_t variable. */ xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );}常见问题
比如有多块内存,一块是内部ram,其他是外部ram,外部的地址能写死确定,但是内部的会随着程序开发不停改变,怎么确定呢,下面是官网给的例子
/* Define the start address and size of the two RAM regions not used by the linker. */#define RAM2_START_ADDRESS ( ( uint8_t * ) 0x00020000 )#define RAM2_SIZE ( 32 * 1024 )#define RAM3_START_ADDRESS ( ( uint8_t * ) 0x00030000 )#define RAM3_SIZE ( 32 * 1024 )/* Declare an array that will be part of the heap used by heap_5. The array will be placed in RAM1 by the linker. */#define RAM1_HEAP_SIZE ( 30 * 1024 )static uint8_t ucHeap[ RAM1_HEAP_SIZE ];/* Create an array of HeapRegion_t definitions. Whereas in Listing 6 the first entry described all of RAM1, so heap_5 will have used all of RAM1, this time the first entry only describes the ucHeap array, so heap_5 will only use the part of RAM1 that contains the ucHeap array. The HeapRegion_t structures must still appear in start address order, with the structure that contains the lowest start address appearing first. */const HeapRegion_t xHeapRegions[] ={ { ucHeap, RAM1_HEAP_SIZE }, { RAM2_START_ADDRESS, RAM2_SIZE }, { RAM3_START_ADDRESS, RAM3_SIZE }, { NULL, 0 } /* Marks the end of the array. */};这样就不用老是修改第一块的起始地址。
以上就是"FreeRTOS动态内存分配怎么管理heap5"这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注行业资讯频道。
内存
地址
分配
管理
知识
篇文章
大小
动态
内容
函数
源码
算法
不同
很大
相同
从小到大
不用
从小
例子
原型
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
什么是科技互联网
互联网佳科技有限公司
互联网科技巨头监管
互联网科技深圳
科技类互联网
互联网科技集团
互联网科技论文
丰台科技园 互联网
火传媒上海互联网科技
济南华为互联网科技产业总部基地
成都互联网科技公司工作好不好
朱啸虎曾投资哪些互联网科技企业
南博望互联网科技有限公司
怎样加入科技互联网
张召忠谈中国互联网科技
福建互联网展示科技馆设计
国产互联网科技公司
容联科技互联网电商
张家口科技产业互联网平台
安徽零酒互联网科技有限公司
科技互联网企业
互联网络科技有限公司
无线互联网科技
长亮科技 互联网金融
千方科技属于互联网企业吗
新兴科技互联网创新大赛颁奖典礼
科技互联网海报
云南省自由互联网科技有限公司
本届互联网大会上的黑科技
保山浩联互联网科技有限公司