FreeRtos内存管理heap

xiaoxiao2025-05-29  17

        FreeRTOS提供的内存管理都是从内存堆中分配内存的。默认情况下,FreeRTOS内核创建任务、队列、信号量、事件组、软件定时器都是借助内存管理函数从内存堆中分配内存。最新的FreeRTOS版本(V9.0.0及其以上版本)可以完全使用静态内存分配方法,也就是不使用任何内存堆。

对于heap_1.c、heap_2.c和heap_4.c这三种内存管理策略,内存堆实际上是一个很大的数组,定义为: static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];

1.heap_1.c

        这是5个内存管理策略中最简单的一个,我们称为第一个内存管理策略,它简单到只能申请内存。是的,跟你想的一样,一旦申请成功后,这块内存再也不能被释放。对于大多数嵌入式系统,特别是对安全要求高的嵌入式系统,这种内存管理策略很有用,因为对系统软件来说,逻辑越简单越容易兼顾安全。实际上,大多数的嵌入式系统并不需要动态删除任务、信号量、队列等,而是在初始化的时候一次性创建好,便一直使用,永远不用删除。所以这个内存管理策略实现简洁、安全可靠,使用的非常广泛。我对这个对内存管理策略也情有独钟。

size_t xNextFreeByte = ( size_t ) 0;已经分配内存的大小 static uint8_t *pucAlignedHeap = NULL;指向八字节对齐的的内存位置

申请分配内存=>

void *pvPortMalloc( size_t xWantedSize ) { void *pvReturn = NULL;//static uint8_t *pucAlignedHeap = NULL;

#ifdef __SRAM_SUPPORT__     if (xWantedSize % 2)     {         xWantedSize += 1;     } #endif    /*__SRAM_SUPPORT__*/          /* Ensure that blocks are always aligned to the required number of bytes. */保证字节数是8的倍速     #if portBYTE_ALIGNMENT != 1         if( xWantedSize & portBYTE_ALIGNMENT_MASK )         {             xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );         }     #endif

算法总结:X+=8-(X&0111)  =>X最终的结果总会是8的倍数。

vTaskSuspendAll();     {         if( pucAlignedHeap == NULL )//开第一次分配内存         {             /* Ensure the heap starts on a correctly aligned boundary. */             pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ( portPOINTER_SIZE_TYPE ) ~portBYTE_ALIGNMENT_MASK ) );         }

        /* Check there is enough room left for the allocation. */         if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&             ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte )    )/* Check for overflow. */         {             /* Return the next free byte then increment the index past this block. */             pvReturn = pucAlignedHeap + xNextFreeByte;             xNextFreeByte += xWantedSize;         }

        traceMALLOC( pvReturn, xWantedSize );     }     ( void ) xTaskResumeAll();

    #if( configUSE_MALLOC_FAILED_HOOK == 1 )     {         if( pvReturn == NULL )         {             extern void vApplicationMallocFailedHook( void );             vApplicationMallocFailedHook();         }     }     #endif

    return pvReturn; }

转载请注明原文地址: https://www.6miu.com/read-5030927.html

最新回复(0)