435 lines
14 KiB
C
435 lines
14 KiB
C
/*----------------------------------------------------------------------------
|
|
* Copyright (c) Fenda Technologies Co., Ltd. 2021. All rights reserved.
|
|
*
|
|
* Description:sys_memory.c
|
|
*
|
|
* Author: saimen
|
|
*
|
|
* Create: 2021-08-25
|
|
*--------------------------------------------------------------------------*/
|
|
//lib
|
|
//os
|
|
//sdk
|
|
//drv
|
|
#include "sys_typedef.h"
|
|
#include "sys_config.h"
|
|
#include "sys_memory.h"
|
|
#include "sys_adapter.h"
|
|
//user
|
|
|
|
|
|
#define ENABLE_STATIC_PRINT false
|
|
extern uint32_t am_util_stdio_printf(const char *pcFmt, ...);
|
|
#define static_print_remind(...) am_util_stdio_printf(__VA_ARGS__)
|
|
#if ENABLE_STATIC_PRINT
|
|
#define static_print_info(...) am_util_stdio_printf(__VA_ARGS__)
|
|
#else
|
|
#define static_print_info(...)
|
|
#endif
|
|
|
|
#define EXTERNAL_MEMORY_XIPMM_MODE
|
|
|
|
//unsigned short int g_ext_memory_map_list[EXT_MEMORY_MALLOC_BLOCK_NUMBER];
|
|
//unsigned char g_ext_memory_malloc_buffer[EXTERNAL_MEMORY_MALLOC_BUFFER_SIZE];
|
|
|
|
//unsigned short int g_ui_memory_map_list[UI_MEMORY_MALLOC_BLOCK_NUMBER];
|
|
//unsigned char g_ui_memory_malloc_buffer[UI_MEMORY_MALLOC_BUFFER_SIZE];
|
|
|
|
static uint8_t g_mem_flag = false;
|
|
|
|
#ifndef EXTERNAL_MEMORY_XIPMM_MODE
|
|
//PSRAM内存管理LIST在片内。
|
|
//typedef struct A_BLOCK_NODE
|
|
//{
|
|
// struct A_BLOCK_NODE *next_free_block; /*<< The next free block in the list. */
|
|
// size_t block_size; /*<< The size of the free block. */
|
|
// size_t *data; /*<< data block. */
|
|
//} block_node_t;
|
|
|
|
void sys_ui_memory_init(void)
|
|
{
|
|
g_mem_flag = true;
|
|
memset((unsigned char *)g_ui_memory_map_list, 0, sizeof(g_ui_memory_map_list));
|
|
// memset((unsigned char *)g_ui_memory_malloc_buffer, 0, UI_MEMORY_MALLOC_BUFFER_SIZE);
|
|
}
|
|
|
|
void *sys_ui_malloc(unsigned int malloc_size)
|
|
{
|
|
unsigned int block_number = 0, free_block_find = 0;
|
|
int i= 0;
|
|
unsigned int j = 0;
|
|
|
|
static_print_info("ui_malloc:%d,%d\r\n", g_ui_mem_flag, malloc_size);
|
|
|
|
if((malloc_size == 0) || (malloc_size > UI_MEMORY_MALLOC_BUFFER_SIZE) || (g_mem_flag == false))
|
|
return NULL;
|
|
|
|
block_number = malloc_size / UI_MEMORY_MALLOC_BLOCK_SIZE;
|
|
|
|
if(malloc_size % UI_MEMORY_MALLOC_BLOCK_SIZE)
|
|
block_number++;
|
|
|
|
for ( i = ( UI_MEMORY_MALLOC_BLOCK_NUMBER - 1 ); i >= 0; i-- )
|
|
{
|
|
if ( g_ui_memory_map_list[i] == 0 )
|
|
free_block_find++;
|
|
else
|
|
free_block_find = 0;
|
|
|
|
if ( free_block_find == block_number )
|
|
break;
|
|
}
|
|
|
|
if(free_block_find == block_number)
|
|
{
|
|
for(j = 0; j < block_number; j++)
|
|
{
|
|
g_ui_memory_map_list[i + j] = block_number;
|
|
}
|
|
static_print_info("malloc_addr:0x%x len:%d \r\n", (i * UI_MEMORY_MALLOC_BLOCK_SIZE + UI_MEMORY_MALLOC_BASE_ADDR), malloc_size);
|
|
return (void *) (i * UI_MEMORY_MALLOC_BLOCK_SIZE + UI_MEMORY_MALLOC_BASE_ADDR);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void sys_ui_free(void *addr)
|
|
{
|
|
unsigned int index = 0;
|
|
unsigned int wait_free_block = 0;
|
|
unsigned int i = 0;
|
|
|
|
static_print_info("ui_free=0x%x\r\n", addr);
|
|
|
|
if((g_mem_flag == false))
|
|
return;
|
|
|
|
if(addr == NULL)
|
|
return;
|
|
|
|
//am_util_stdio_printf("ui_free=0x%x,0x%x\r\n", ui_memory_malloc_buffer, UI_MEMORY_MALLOC_BUFFER_SIZE);
|
|
|
|
if(((unsigned int) addr < ((unsigned int)UI_MEMORY_MALLOC_END_ADDR)) && ((unsigned int) addr >= (unsigned int)UI_MEMORY_MALLOC_BASE_ADDR))
|
|
{
|
|
index = ((unsigned int) addr - (unsigned int)UI_MEMORY_MALLOC_BASE_ADDR) / UI_MEMORY_MALLOC_BLOCK_SIZE;
|
|
wait_free_block = g_ui_memory_map_list[index];
|
|
|
|
for(i = 0; i < wait_free_block; i++)
|
|
{
|
|
g_ui_memory_map_list[index + i] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
unsigned char sys_ui_memory_used(void)
|
|
{
|
|
unsigned int used = 0;
|
|
unsigned int i = 0;
|
|
|
|
for(i = 0; i < UI_MEMORY_MALLOC_BLOCK_NUMBER; i++)
|
|
{
|
|
if(g_ui_memory_map_list[i])
|
|
used++;
|
|
}
|
|
|
|
return (used * 100) / (UI_MEMORY_MALLOC_BLOCK_NUMBER);
|
|
}
|
|
|
|
#else
|
|
|
|
/*-----------------------------------------------------------*/
|
|
#define UI_BYTE_ALIGNMENT ( ( size_t ) 16 )
|
|
|
|
#define UI_BYTE_ALIGNMENT_MASK ( ( size_t ) (UI_BYTE_ALIGNMENT-1) )
|
|
/* Work out the position of the top bit in a size_t variable. */
|
|
#define BLOCK_ALLOCATED_BIT ( ( size_t ) 0x80000000 )
|
|
/* saimen:Block sizes must not get too small.Double node_struct_size space */
|
|
#define UI_MINIMUM_BLOCK_SIZE ( ( size_t ) ( node_struct_size << 1 ) )
|
|
|
|
typedef struct A_BLOCK_NODE
|
|
{
|
|
struct A_BLOCK_NODE *next_free_block; /*<< The next free block in the list. */
|
|
size_t block_size; /*<< The size of the free block. */
|
|
} block_node_t;
|
|
|
|
/*-----------------------------------------------------------*/
|
|
static const size_t node_struct_size = (sizeof(block_node_t) + ((size_t)(UI_BYTE_ALIGNMENT - 1))) & ~((size_t) UI_BYTE_ALIGNMENT_MASK);
|
|
static block_node_t g_start_node ={0}, *g_end_node = NULL;
|
|
static size_t ui_current_free_bytes = 0U;
|
|
static size_t ui_minimum_free_bytes = 0U;
|
|
|
|
/*-----------------------------------------------------------*/
|
|
//static void ui_memory_init( void );
|
|
static void sys_ui_insert_node(block_node_t *insert_block);
|
|
|
|
/*-----------------------------------------------------------*/
|
|
void sys_debug_marker(uint8_t marker_type)
|
|
{
|
|
if(marker_type == 0)
|
|
{
|
|
static_print_info("%d ui_heep error.\r\n", xTaskGetTickCount());
|
|
|
|
while(1)
|
|
{
|
|
sys_smart_delay_ms(10);
|
|
}
|
|
}
|
|
|
|
//static_print_info("%d ui_heep warning:%d.\r\n",xTaskGetTickCount(),marker_type);
|
|
}
|
|
|
|
void *sys_ui_malloc(size_t wanted_size)
|
|
{
|
|
block_node_t *block_temp, *previous_block, *new_block;
|
|
void *return_p = NULL;
|
|
|
|
if(g_end_node == NULL)
|
|
{
|
|
sys_ui_memory_init();
|
|
}
|
|
else
|
|
{
|
|
sys_debug_marker(8);
|
|
}
|
|
|
|
//static_print_remind("%d ui_malloc:0x%x\r\n",xTaskGetTickCount(),wanted_size);
|
|
if((wanted_size & BLOCK_ALLOCATED_BIT) == 0)
|
|
{
|
|
if(wanted_size > 0)
|
|
{
|
|
wanted_size += node_struct_size;
|
|
|
|
if((wanted_size & UI_BYTE_ALIGNMENT_MASK) != 0x00)
|
|
{
|
|
/* Byte alignment required. */
|
|
wanted_size += (UI_BYTE_ALIGNMENT - (wanted_size & UI_BYTE_ALIGNMENT_MASK));
|
|
sys_debug_marker((wanted_size & UI_BYTE_ALIGNMENT_MASK) == 0);
|
|
}
|
|
}
|
|
|
|
if((wanted_size > 0) && (wanted_size <= ui_current_free_bytes))
|
|
{
|
|
previous_block = &g_start_node;
|
|
block_temp = g_start_node.next_free_block;
|
|
|
|
while((block_temp->block_size < wanted_size) && (block_temp->next_free_block != NULL))
|
|
{
|
|
previous_block = block_temp;
|
|
block_temp = block_temp->next_free_block;
|
|
}
|
|
|
|
if(block_temp != g_end_node)
|
|
{
|
|
return_p = (void *)(((uint8_t *) previous_block->next_free_block) + node_struct_size);
|
|
previous_block->next_free_block = block_temp->next_free_block;
|
|
|
|
if((block_temp->block_size - wanted_size) > UI_MINIMUM_BLOCK_SIZE)
|
|
{
|
|
new_block = (void *)(((uint8_t *) block_temp) + wanted_size);
|
|
sys_debug_marker((((size_t) new_block) & UI_BYTE_ALIGNMENT_MASK) == 0);
|
|
|
|
new_block->block_size = block_temp->block_size - wanted_size;
|
|
block_temp->block_size = wanted_size;
|
|
|
|
sys_ui_insert_node(new_block);
|
|
}
|
|
|
|
// else
|
|
// {
|
|
// sys_debug_marker(8);
|
|
// }
|
|
|
|
ui_current_free_bytes -= block_temp->block_size;
|
|
|
|
if(ui_current_free_bytes < ui_minimum_free_bytes)
|
|
{
|
|
ui_minimum_free_bytes = ui_current_free_bytes;
|
|
}
|
|
|
|
block_temp->block_size |= BLOCK_ALLOCATED_BIT;
|
|
block_temp->next_free_block = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
sys_debug_marker((((size_t) return_p) & (size_t) UI_BYTE_ALIGNMENT_MASK) == 0);
|
|
static_print_info("%d ok:0x%x,b_temp:0x%x,b_size:0x%x,c_free:0x%x,min_free:0x%x\r\n",xTaskGetTickCount(),return_p,block_temp,block_temp->block_size,ui_current_free_bytes,ui_minimum_free_bytes);
|
|
if(return_p == NULL)
|
|
{
|
|
static_print_remind("error: sys_ui_malloc() return_p==NULL,%d-%d-%d\r\n",wanted_size,ui_current_free_bytes,ui_minimum_free_bytes);
|
|
}
|
|
return return_p;
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
void sys_ui_free(void *pv)
|
|
{
|
|
uint8_t *puc = (uint8_t *) pv;
|
|
block_node_t *block_temp;
|
|
|
|
static_print_info("%d ui_free:0x%x\r\n",xTaskGetTickCount(),pv);
|
|
if(pv >= (void *)UI_MEMORY_MALLOC_BASE_ADDR)
|
|
{
|
|
puc -= node_struct_size;
|
|
|
|
block_temp = (void *) puc;
|
|
|
|
/* Check the block is actually allocated. */
|
|
//sys_debug_marker( ( block_temp->block_size & BLOCK_ALLOCATED_BIT ) != 0 );
|
|
//sys_debug_marker( block_temp->next_free_block == NULL );
|
|
|
|
if((block_temp->block_size & BLOCK_ALLOCATED_BIT) != 0)
|
|
{
|
|
if(block_temp->next_free_block == NULL)
|
|
{
|
|
block_temp->block_size &= ~BLOCK_ALLOCATED_BIT;
|
|
|
|
ui_current_free_bytes += block_temp->block_size;
|
|
sys_ui_insert_node(((block_node_t *) block_temp));
|
|
}
|
|
else
|
|
{
|
|
sys_debug_marker(9);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sys_debug_marker(9);
|
|
}
|
|
}
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
size_t sys_ui_get_free_size(void)
|
|
{
|
|
return ui_current_free_bytes;
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
size_t sys_ui_get_minimum_ever_free_size(void)
|
|
{
|
|
return ui_minimum_free_bytes;
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
void sys_ui_init_blocks(void)
|
|
{
|
|
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
void sys_ui_memory_init(void)
|
|
{
|
|
block_node_t *first_free_block;
|
|
uint8_t *aligned_heap;
|
|
size_t ux_address;
|
|
size_t total_heap_size = UI_MEMORY_MALLOC_BUFFER_SIZE;
|
|
|
|
ux_address = (size_t) UI_MEMORY_MALLOC_BASE_ADDR;
|
|
|
|
if((ux_address & UI_BYTE_ALIGNMENT_MASK) != 0)
|
|
{
|
|
ux_address += (UI_BYTE_ALIGNMENT - 1);
|
|
ux_address &= ~((size_t) UI_BYTE_ALIGNMENT_MASK);
|
|
total_heap_size -= ux_address - (size_t) UI_MEMORY_MALLOC_BASE_ADDR;
|
|
}
|
|
|
|
aligned_heap = (uint8_t *) ux_address;
|
|
|
|
g_start_node.next_free_block = (void *) aligned_heap;
|
|
g_start_node.block_size = (size_t) 0;
|
|
|
|
ux_address = ((size_t) aligned_heap) + total_heap_size;
|
|
ux_address -= node_struct_size;
|
|
ux_address &= ~((size_t) UI_BYTE_ALIGNMENT_MASK);
|
|
g_end_node = (void *) ux_address;
|
|
g_end_node->block_size = 0;
|
|
g_end_node->next_free_block = NULL;
|
|
|
|
first_free_block = (void *) aligned_heap;
|
|
first_free_block->block_size = ux_address - (size_t) first_free_block;
|
|
first_free_block->next_free_block = g_end_node;
|
|
|
|
ui_minimum_free_bytes = first_free_block->block_size;
|
|
ui_current_free_bytes = first_free_block->block_size;
|
|
}
|
|
/*-----------------------------------------------------------*/
|
|
|
|
static void sys_ui_insert_node(block_node_t *insert_block)
|
|
{
|
|
block_node_t *iterator_node;
|
|
uint8_t *puc;
|
|
|
|
for(iterator_node = &g_start_node; iterator_node->next_free_block < insert_block; iterator_node = iterator_node->next_free_block)
|
|
{
|
|
//static_print_remind("%d ui_insert_node 1:0x%x,0x%x\r\n",xTaskGetTickCount(),iterator_node,iterator_node->next_free_block);
|
|
}
|
|
|
|
/* Do the block being inserted, and the block it is being inserted after
|
|
make a contiguous block of memory? */
|
|
puc = (uint8_t *) iterator_node;
|
|
|
|
if((puc + iterator_node->block_size) == (uint8_t *) insert_block)
|
|
{
|
|
iterator_node->block_size += insert_block->block_size;
|
|
insert_block = iterator_node;
|
|
}
|
|
else
|
|
{
|
|
//sys_debug_marker(10);
|
|
}
|
|
|
|
/* Do the block being inserted, and the block it is being inserted before
|
|
make a contiguous block of memory? */
|
|
puc = (uint8_t *) insert_block;
|
|
|
|
if((puc + insert_block->block_size) == (uint8_t *) iterator_node->next_free_block)
|
|
{
|
|
if(iterator_node->next_free_block != g_end_node)
|
|
{
|
|
/* Form one big block from the two blocks. */
|
|
insert_block->block_size += iterator_node->next_free_block->block_size;
|
|
insert_block->next_free_block = iterator_node->next_free_block->next_free_block;
|
|
}
|
|
else
|
|
{
|
|
insert_block->next_free_block = g_end_node;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
insert_block->next_free_block = iterator_node->next_free_block;
|
|
}
|
|
|
|
/* If the block being inserted plugged a gab, so was merged with the block
|
|
before and the block after, then it's next_free_block pointer will have
|
|
already been set, and should not be set here as that would make it point
|
|
to itself. */
|
|
if(iterator_node != insert_block)
|
|
{
|
|
iterator_node->next_free_block = insert_block;
|
|
}
|
|
else
|
|
{
|
|
//sys_debug_marker(10);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
//
|
|
void sys_ext_memory_init ( void )
|
|
{
|
|
sys_ui_memory_init();
|
|
}
|
|
|
|
void *sys_ext_malloc ( unsigned int malloc_size )
|
|
{
|
|
return sys_ui_malloc(malloc_size);
|
|
}
|
|
|
|
void sys_ext_free ( void *addr )
|
|
{
|
|
sys_ui_free(addr);
|
|
}
|
|
|