stm32h743_player/User/utils/heap.c
2024-04-05 00:36:26 +08:00

197 lines
4.9 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "heap.h"
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "tlsf.h"
#include "elog.h"
#include <sys/lock.h>
#include <string.h>
#include "stm32_lock.h"
// static const char *TAG = "system_memory";
static uint8_t __attribute__((section(".ram_dtcm"))) heap_dtcm[HEAP_DTCM_SIZE_KB * 1024];
static uint8_t __attribute__((section(".ram_axi"))) heap_axi[HEAP_AXI_SIZE_KB * 1024];
static uint8_t __attribute__((section(".ram_ahb"))) heap_ahb[HEAP_APB_SIZE_KB * 1024];
static tlsf_t tlsf_heap_dtcm;
static tlsf_t tlsf_heap_axi;
static tlsf_t tlsf_heap_ahb;
static LockingData_t malloc_lock_dtcm;
static LockingData_t malloc_lock_axi;
static LockingData_t malloc_lock_ahb;
static void tlsf_mem_walker(void* ptr, size_t size, int used, void* user)
{
tlsf_pool_statistics *statistics = (tlsf_pool_statistics *)user;
if (used) {
++ statistics->used_cnt;
statistics->used_size += size;
if(size > statistics->used_biggest_size) {
statistics->used_biggest_size = size;
}
} else {
++ statistics->free_cnt;
statistics->free_size += size;
if(size > statistics->free_biggest_size) {
statistics->free_biggest_size = size;
}
}
}
void get_tlsf_pool_statistics(tlsf_t tlsf_heap, tlsf_pool_statistics *statistics_out)
{
memset(statistics_out, 0, sizeof(tlsf_pool_statistics));
tlsf_walk_pool(tlsf_get_pool(tlsf_heap), tlsf_mem_walker, statistics_out);
}
void *malloc_dtcm(size_t size)
{
stm32_lock_acquire(&malloc_lock_dtcm);
void *p = tlsf_malloc(tlsf_heap_dtcm, size);
stm32_lock_release(&malloc_lock_dtcm);
// if (xTaskGetSchedulerState() == pdTRUE) {
// elog_verbose(TAG, "dtcm: allocating %d bytes memory @ %p", size, p);
// }
return p;
}
void free_dtcm(void *p)
{
if (p) {
stm32_lock_acquire(&malloc_lock_dtcm);
tlsf_free(tlsf_heap_dtcm, p);
stm32_lock_release(&malloc_lock_dtcm);
}
}
void *realloc_dtcm(void *oldmem, size_t bytes)
{
if (oldmem == NULL) { //当旧内存地址为空时此函数等于malloc函数
return malloc_dtcm(bytes);
}
void *p;
stm32_lock_acquire(&malloc_lock_dtcm);
p = tlsf_realloc(tlsf_heap_dtcm, oldmem, bytes);
stm32_lock_release(&malloc_lock_dtcm);
return p;
}
tlsf_pool_statistics *get_dtcm_heap_statistics(void)
{
static tlsf_pool_statistics statistics;
stm32_lock_acquire(&malloc_lock_dtcm);
get_tlsf_pool_statistics(tlsf_heap_dtcm, &statistics);
stm32_lock_release(&malloc_lock_dtcm);
return &statistics;
}
void *malloc_ahb(size_t size)
{
void *p;
stm32_lock_acquire(&malloc_lock_ahb);
p = tlsf_malloc(tlsf_heap_ahb, size);
stm32_lock_release(&malloc_lock_ahb);
return p;
}
void free_ahb(void *p)
{
if (p) {
stm32_lock_acquire(&malloc_lock_ahb);
tlsf_free(tlsf_heap_ahb, p);
stm32_lock_release(&malloc_lock_ahb);
}
}
void *realloc_ahb(void *oldmem, size_t bytes)
{
if (oldmem == NULL) { //当旧内存地址为空时此函数等于malloc函数
return malloc_ahb(bytes);
}
void *p;
stm32_lock_acquire(&malloc_lock_ahb);
p = tlsf_realloc(tlsf_heap_ahb, oldmem, bytes);
stm32_lock_release(&malloc_lock_ahb);
return p;
}
tlsf_pool_statistics *get_ahb_heap_statistics(void)
{
static tlsf_pool_statistics statistics;
stm32_lock_acquire(&malloc_lock_dtcm);
get_tlsf_pool_statistics(tlsf_heap_ahb, &statistics);
stm32_lock_release(&malloc_lock_dtcm);
return &statistics;
}
void *__wrap__malloc_r(struct _reent *ptr, size_t bytes)
{
UNUSED(ptr); //不使用newlib自带的基于重入的锁
stm32_lock_acquire(&malloc_lock_axi);
void *p = tlsf_malloc(tlsf_heap_axi, bytes);
stm32_lock_release(&malloc_lock_axi);
// elog_verbose(TAG, "axi: allocating %d bytes memory @ %p", bytes, p);
return p;
}
void __wrap__free_r(struct _reent *ptr, void *mem)
{
UNUSED(ptr); //不使用newlib自带的基于重入的锁
if (mem) {
stm32_lock_acquire(&malloc_lock_axi);
tlsf_free(tlsf_heap_axi, mem);
stm32_lock_release(&malloc_lock_axi);
}
}
void *__wrap__realloc_r(struct _reent *ptr, void *oldmem, size_t bytes)
{
UNUSED(ptr); //不使用newlib自带的基于重入的锁
if (oldmem == NULL) { //当旧内存地址为空时此函数等于malloc函数
return __wrap__malloc_r(ptr, bytes);
}
stm32_lock_acquire(&malloc_lock_axi);
void *p = tlsf_realloc(tlsf_heap_axi, oldmem, bytes);
stm32_lock_release(&malloc_lock_axi);
return p;
}
tlsf_pool_statistics *get_axi_heap_statistics(void)
{
static tlsf_pool_statistics statistics;
stm32_lock_acquire(&malloc_lock_dtcm);
get_tlsf_pool_statistics(tlsf_heap_axi, &statistics);
stm32_lock_release(&malloc_lock_dtcm);
return &statistics;
}
void heap_init(void)
{
stm32_lock_init(&malloc_lock_dtcm);
stm32_lock_init(&malloc_lock_axi);
stm32_lock_init(&malloc_lock_ahb);
tlsf_heap_dtcm = tlsf_create_with_pool(heap_dtcm, sizeof(heap_dtcm));
tlsf_heap_axi = tlsf_create_with_pool(heap_axi, sizeof(heap_axi));
tlsf_heap_ahb = tlsf_create_with_pool(heap_ahb, sizeof(heap_ahb));
}