FreeRTOS动态内存分配怎么管理heap5
发表于:2025-11-09 作者:千家信息网编辑
千家信息网最后更新 2025年11月09日,今天小编给大家分享一下FreeRTOS动态内存分配怎么管理heap5的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收
千家信息网最后更新 2025年11月09日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安全错误
数据库的锁怎样保障安全
软件开发读研学费
一个客户端连接多个服务器
更改数据库表类型
服务器一键重装系统
全外显子测序数据库
公司网络安全人员技能
医药销售系统数据库课设总结
偃师软件开发报价
数据库访问技术应用
NIH医学数据库
互联网金融网络技术有限公司
软硬一体网络安全设备
洛阳软件开发优缺点
临沂安锐网络技术有限公司
开票服务器开票软件0530
住建大数据库
软件开发 太原分公司
2016数据库
网络安全考研学校排名
爬虫python 数据库
网络安全常用密码
服务器raid驱动在pe中注入
服务器安全运维管理
达梦数据库导入文件名
计算机网络技术基础多选题
把家里的电脑做云服务器
获取服务器管理口地址
参观网络安全宣传周展览
车载网络技术凌永成课件
观塘区的网络技术公司