头文件
[mw_shl_code=c,true]#ifndef __bsp_Malloc_H
#define __bsp_Malloc_H
#include <stdlib.h>
#include "stm32f1xx_hal.h"
#define Ram1Addr (0x68000000UL)
#define Ram1Size (960*1024)
#define configMAX_INTERRUPT_PRIORITY 2
#ifndef TEST_MARKER
#define TEST_MARKER()
#endif
#ifndef myFORCE_INLINE
#define myFORCE_INLINE __forceinline
#endif
typedef struct myHeapRegion
{
uint8_t *pucStartAddress; //指向一个地址
size_t xSizeInBytes; //此内存块的大小
} myHeapRegion_t;
extern myHeapRegion_t xHeapRegions[];
void *myMalloc( size_t xWantedSize );
void myFree( void *pv );
size_t myGetFreeHeapSize( void );
size_t myGetMinimumEverFreeHeapSize( void );
void myDefineHeapRegions( const myHeapRegion_t * const pxHeapRegions );
#endif
[/mw_shl_code]
源文件
[mw_shl_code=c,true]#include "bsp_Malloc.h"
typedef long BaseType_t;
#define configUSE_MALLOC_FAILED_HOOK 0
#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) )
#define heapBITS_PER_BYTE ( ( size_t ) 8 )
#define portBYTE_ALIGNMENT 8
#define portBYTE_ALIGNMENT_MASK (portBYTE_ALIGNMENT - 1)
#define MallocInterruptMask( ) vPortSetBASEPRI( )
#define MallocInterruptRelease( ) vPortRaiseBASEPRI( )
#define mallocASSERT( x ) if ((x) == 0) { for( ;; );}
typedef struct A_BLOCK_LINK
{
struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */
size_t xBlockSize; /*<< The size of the free block. */
} BlockLink_t;
myHeapRegion_t xHeapRegions[] =
{
{ ( uint8_t * ) Ram1Addr, Ram1Size },
{ NULL, 0 }
};
/*-----------------------------------------------------------*/
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert );
/*-----------------------------------------------------------*/
static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK );
static BlockLink_t xStart, *pxEnd = NULL;
static size_t xFreeBytesRemaining = 0U;
static size_t xMinimumEverFreeBytesRemaining = 0U;
static size_t xBlockAllocatedBit = 0;
/*-----------------------------------------------------------*/
// 开中断
// 向basepri中写入0就表示开中断
static myFORCE_INLINE void vPortSetBASEPRI( void )
{
__asm
{
msr basepri, 0
}
}
// 关中断
// 向basepri中写入configMAX_INTERRUPT_PRIORITY,
// 表明优先级低于configMAX_INTERRUPT_PRIORITY的中断都会被屏蔽
static myFORCE_INLINE void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI = configMAX_INTERRUPT_PRIORITY;
__asm
{
msr basepri, ulNewBASEPRI
dsb
isb
}
}
void *myMalloc( size_t xWantedSize )
{
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
void *pvReturn = NULL;
mallocASSERT( pxEnd );
MallocInterruptMask();
{
if( ( xWantedSize & xBlockAllocatedBit ) == 0 )
{
if( xWantedSize > 0 )
{
xWantedSize += xHeapStructSize;
if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 )
{
xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) );
}
else
{
TEST_MARKER();
}
}
else
{
TEST_MARKER();
}
if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) )
{
pxPreviousBlock = &xStart;
pxBlock = xStart.pxNextFreeBlock;
while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) )
{
pxPreviousBlock = pxBlock;
pxBlock = pxBlock->pxNextFreeBlock;
}
if( pxBlock != pxEnd )
{
pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize );
pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock;
if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE )
{
pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize );
pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize;
pxBlock->xBlockSize = xWantedSize;
prvInsertBlockIntoFreeList( ( pxNewBlockLink ) );
}
else
{
TEST_MARKER();
}
xFreeBytesRemaining -= pxBlock->xBlockSize;
if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining )
{
xMinimumEverFreeBytesRemaining = xFreeBytesRemaining;
}
else
{
TEST_MARKER();
}
pxBlock->xBlockSize |= xBlockAllocatedBit;
pxBlock->pxNextFreeBlock = NULL;
}
else
{
TEST_MARKER();
}
}
else
{
TEST_MARKER();
}
}
else
{
TEST_MARKER();
}
}
MallocInterruptRelease();
#if( configUSE_MALLOC_FAILED_HOOK == 1 )
{
if( pvReturn == NULL )
{
extern void vApplicationMallocFailedHook( void );
vApplicationMallocFailedHook();
}
else
{
TEST_MARKER();
}
}
#endif
return pvReturn;
}
/*-----------------------------------------------------------*/
void myFree( void *pv )
{
uint8_t *puc = ( uint8_t * ) pv;
BlockLink_t *pxLink;
if( pv != NULL )
{
puc -= xHeapStructSize;
pxLink = ( void * ) puc;
mallocASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 );
mallocASSERT( pxLink->pxNextFreeBlock == NULL );
if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 )
{
if( pxLink->pxNextFreeBlock == NULL )
{
pxLink->xBlockSize &= ~xBlockAllocatedBit;
MallocInterruptMask();
{
xFreeBytesRemaining += pxLink->xBlockSize;
prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) );
}
MallocInterruptRelease();
}
else
{
TEST_MARKER();
}
}
else
{
TEST_MARKER();
}
}
}
/*-----------------------------------------------------------*/
size_t myGetFreeHeapSize( void )
{
return xFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
size_t myGetMinimumEverFreeHeapSize( void )
{
return xMinimumEverFreeBytesRemaining;
}
/*-----------------------------------------------------------*/
static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert )
{
BlockLink_t *pxIterator;
uint8_t *puc;
for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock )
{
/* Nothing to do here, just iterate to the right position. */
}
puc = ( uint8_t * ) pxIterator;
if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert )
{
pxIterator->xBlockSize += pxBlockToInsert->xBlockSize;
pxBlockToInsert = pxIterator;
}
else
{
TEST_MARKER();
}
puc = ( uint8_t * ) pxBlockToInsert;
if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock )
{
if( pxIterator->pxNextFreeBlock != pxEnd )
{
pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize;
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock;
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxEnd;
}
}
else
{
pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock;
}
if( pxIterator != pxBlockToInsert )
{
pxIterator->pxNextFreeBlock = pxBlockToInsert;
}
else
{
TEST_MARKER();
}
}
/*-----------------------------------------------------------*/
void myDefineHeapRegions( const myHeapRegion_t * const pxHeapRegions )
{
BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock;
size_t xAlignedHeap;
size_t xTotalRegionSize, xTotalHeapSize = 0;
BaseType_t xDefinedRegions = 0;
size_t xAddress;
const myHeapRegion_t *pxHeapRegion;
mallocASSERT( pxEnd == NULL );
pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
while( pxHeapRegion->xSizeInBytes > 0 )
{
xTotalRegionSize = pxHeapRegion->xSizeInBytes;
xAddress = ( size_t ) pxHeapRegion->pucStartAddress;
if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 )
{
xAddress += ( portBYTE_ALIGNMENT - 1 );
xAddress &= ~portBYTE_ALIGNMENT_MASK;
xTotalRegionSize -= xAddress - ( size_t ) pxHeapRegion->pucStartAddress;
}
xAlignedHeap = xAddress;
if( xDefinedRegions == 0 )
{
xStart.pxNextFreeBlock = ( BlockLink_t * ) xAlignedHeap;
xStart.xBlockSize = ( size_t ) 0;
}
else
{
mallocASSERT( pxEnd != NULL );
mallocASSERT( xAddress > ( size_t ) pxEnd );
}
pxPreviousFreeBlock = pxEnd;
xAddress = xAlignedHeap + xTotalRegionSize;
xAddress -= xHeapStructSize;
xAddress &= ~portBYTE_ALIGNMENT_MASK;
pxEnd = ( BlockLink_t * ) xAddress;
pxEnd->xBlockSize = 0;
pxEnd->pxNextFreeBlock = NULL;
pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap;
pxFirstFreeBlockInRegion->xBlockSize = xAddress - ( size_t ) pxFirstFreeBlockInRegion;
pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd;
if( pxPreviousFreeBlock != NULL )
{
pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion;
}
xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize;
xDefinedRegions++;
pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] );
}
xMinimumEverFreeBytesRemaining = xTotalHeapSize;
xFreeBytesRemaining = xTotalHeapSize;
mallocASSERT( xTotalHeapSize );
xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 );
}
[/mw_shl_code]
测试过可以在战舰V3使用
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
如果使用了系统,就使用系统提供的 任务挂起、恢复函数,
如果没有使用系统,就使用关总中断,开总中断的方法
貌似有人吧 heap4 改成了内存管理,而且可以管理很多个内存段,
http://www.openedv.com/forum.php ... 5026&highlight=heap
不过貌似这个里面的,如果使用 FreeRTOS 与 这个内存同时使用的话,貌似有些函数及相关的名称冲突,需要做相应的更改
一周热门 更多>