319 lines
7.4 KiB
C
319 lines
7.4 KiB
C
/**
|
|
* Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
******************************************************************************
|
|
* @file drv_heap.c
|
|
* @version V0.2
|
|
* @brief heap interface
|
|
*
|
|
* Change Logs:
|
|
* Date Author Notes
|
|
* 2019-03-26 Cliff.Chen first implementation
|
|
* 2019-05-15 Cliff.Chen Add large heap
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
#include <rtthread.h>
|
|
#include "drv_heap.h"
|
|
|
|
#ifdef RT_USING_UNCACHE_HEAP
|
|
static struct rt_memheap _uncache_heap;
|
|
|
|
rt_err_t rt_uncache_heap_init(void *begin_addr, void *end_addr)
|
|
{
|
|
/* initialize a default heap in the system */
|
|
return rt_memheap_init(&_uncache_heap,
|
|
"ucheap",
|
|
begin_addr,
|
|
(rt_uint32_t)end_addr - (rt_uint32_t)begin_addr);
|
|
}
|
|
|
|
void *rt_malloc_uncache(rt_size_t size)
|
|
{
|
|
return rt_memheap_alloc(&_uncache_heap, size);
|
|
}
|
|
|
|
void rt_free_uncache(void *ptr)
|
|
{
|
|
rt_memheap_free(ptr);
|
|
}
|
|
#endif
|
|
|
|
#ifdef RT_USING_LARGE_HEAP
|
|
#include "hal_base.h"
|
|
|
|
static struct rt_memheap _large_heap;
|
|
|
|
rt_err_t rt_large_heap_init(void *begin_addr, void *end_addr)
|
|
{
|
|
/* initialize a default heap in the system */
|
|
return rt_memheap_init(&_large_heap,
|
|
"large",
|
|
begin_addr,
|
|
(rt_uint32_t)end_addr - (rt_uint32_t)begin_addr);
|
|
}
|
|
|
|
void *rt_malloc_large(rt_size_t size)
|
|
{
|
|
if (size < RT_LARGE_MALLOC_THRRESH)
|
|
return NULL;
|
|
|
|
return rt_memheap_alloc(&_large_heap, size);
|
|
}
|
|
RTM_EXPORT(rt_malloc_large);
|
|
|
|
void rt_free_large(void *ptr)
|
|
{
|
|
rt_memheap_free(ptr);
|
|
}
|
|
RTM_EXPORT(rt_free_large);
|
|
|
|
void *rt_dma_malloc_large(rt_size_t size)
|
|
{
|
|
void *align_ptr;
|
|
void *ptr;
|
|
rt_size_t align, align_size;
|
|
|
|
if (size < RT_LARGE_MALLOC_THRRESH)
|
|
return NULL;
|
|
|
|
align = 4;
|
|
align_size = 0;
|
|
|
|
#ifdef CACHE_LINE_SIZE
|
|
align = CACHE_LINE_SIZE;
|
|
#endif
|
|
|
|
#ifdef DMA_ALIGN_SIZE
|
|
align = align > DMA_ALIGN_SIZE ? align : DMA_ALIGN_SIZE;
|
|
#endif
|
|
|
|
align_size = RT_ALIGN(size, align) + align;
|
|
ptr = rt_memheap_alloc(&_large_heap, align_size);
|
|
if (ptr != RT_NULL)
|
|
{
|
|
/* the allocated memory block is aligned */
|
|
if (((rt_uint32_t)ptr & (align - 1)) == 0)
|
|
{
|
|
align_ptr = (void *)((rt_uint32_t)ptr + align);
|
|
}
|
|
else
|
|
{
|
|
align_ptr = (void *)(((rt_uint32_t)ptr + (align - 1)) & ~(align - 1));
|
|
}
|
|
|
|
/* set the pointer before alignment pointer to the real pointer */
|
|
*((rt_uint32_t *)((rt_uint32_t)align_ptr - sizeof(void *))) = (rt_uint32_t)ptr;
|
|
|
|
ptr = align_ptr;
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
RTM_EXPORT(rt_dma_malloc_large);
|
|
|
|
void rt_dma_free_large(void *ptr)
|
|
{
|
|
void *real_ptr;
|
|
|
|
real_ptr = (void *) * (rt_uint32_t *)((rt_uint32_t)ptr - sizeof(void *));
|
|
rt_memheap_free(real_ptr);
|
|
}
|
|
RTM_EXPORT(rt_dma_free_large);
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef RT_USING_DTCM_HEAP
|
|
#include "hal_base.h"
|
|
|
|
static struct rt_memheap _dtcm_heap;
|
|
extern int __dtcm_start__, __dtcm_end__;
|
|
|
|
#define RK_DTCM_BEGIN (&__dtcm_start__)
|
|
#define RK_DTCM_END (&__dtcm_end__)
|
|
|
|
int rt_dtcm_heap_init(void)
|
|
{
|
|
rt_err_t ret;
|
|
rt_device_t dsp;
|
|
|
|
dsp = rt_device_find("dsp0");
|
|
RT_ASSERT(dsp != RT_NULL);
|
|
|
|
ret = rt_device_open(dsp, RT_DEVICE_FLAG_RDWR);
|
|
RT_ASSERT(ret == RT_EOK);
|
|
|
|
return rt_memheap_init(&_dtcm_heap,
|
|
"dtcmheap",
|
|
RK_DTCM_BEGIN,
|
|
(rt_uint32_t)RK_DTCM_END - (rt_uint32_t)RK_DTCM_BEGIN);
|
|
|
|
return RT_EOK;
|
|
}
|
|
INIT_COMPONENT_EXPORT(rt_dtcm_heap_init);
|
|
|
|
void *rt_malloc_dtcm(rt_size_t size)
|
|
{
|
|
//rt_kprintf("rt_malloc_dtcm: size = %d\n", size);
|
|
if (size < RT_DTCM_MALLOC_THRRESH)
|
|
return NULL;
|
|
|
|
return rt_memheap_alloc(&_dtcm_heap, size);
|
|
}
|
|
RTM_EXPORT(rt_malloc_dtcm);
|
|
|
|
void rt_free_dtcm(void *ptr)
|
|
{
|
|
rt_memheap_free(ptr);
|
|
}
|
|
RTM_EXPORT(rt_free_dtcm);
|
|
|
|
void *rt_dma_malloc_dtcm(rt_size_t size)
|
|
{
|
|
void *align_ptr;
|
|
void *ptr;
|
|
rt_size_t align, align_size;
|
|
|
|
//rt_kprintf("rt_dma_malloc_dtcm: size = %d\n", size);
|
|
if (size < RT_DTCM_MALLOC_THRRESH)
|
|
return NULL;
|
|
|
|
align = 4;
|
|
align_size = 0;
|
|
|
|
#ifdef CACHE_LINE_SIZE
|
|
align = CACHE_LINE_SIZE;
|
|
#endif
|
|
|
|
#ifdef DMA_ALIGN_SIZE
|
|
align = align > DMA_ALIGN_SIZE ? align : DMA_ALIGN_SIZE;
|
|
#endif
|
|
|
|
align_size = RT_ALIGN(size, align) + align;
|
|
ptr = rt_memheap_alloc(&_dtcm_heap, align_size);
|
|
if (ptr != RT_NULL)
|
|
{
|
|
/* the allocated memory block is aligned */
|
|
if (((rt_uint32_t)ptr & (align - 1)) == 0)
|
|
{
|
|
align_ptr = (void *)((rt_uint32_t)ptr + align);
|
|
}
|
|
else
|
|
{
|
|
align_ptr = (void *)(((rt_uint32_t)ptr + (align - 1)) & ~(align - 1));
|
|
}
|
|
|
|
/* set the pointer before alignment pointer to the real pointer */
|
|
*((rt_uint32_t *)((rt_uint32_t)align_ptr - sizeof(void *))) = (rt_uint32_t)ptr;
|
|
|
|
ptr = align_ptr;
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
RTM_EXPORT(rt_dma_malloc_dtcm);
|
|
|
|
void rt_dma_free_dtcm(void *ptr)
|
|
{
|
|
void *real_ptr;
|
|
|
|
real_ptr = (void *) * (rt_uint32_t *)((rt_uint32_t)ptr - sizeof(void *));
|
|
rt_memheap_free(real_ptr);
|
|
}
|
|
RTM_EXPORT(rt_dma_free_dtcm);
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef RT_USING_PSRAM_HEAP
|
|
#include "hal_base.h"
|
|
|
|
static struct rt_memheap _psram_heap;
|
|
extern int __psramheap_start__, __psramheap_end__;
|
|
|
|
#define RK_PSRAMHEAP_BEGIN (&__psramheap_start__)
|
|
#define RK_PSRAMHEAP_END (&__psramheap_end__)
|
|
|
|
int rt_psram_heap_init(void)
|
|
{
|
|
return rt_memheap_init(&_psram_heap,
|
|
"psramheap",
|
|
RK_PSRAMHEAP_BEGIN,
|
|
(rt_uint32_t)RK_PSRAMHEAP_END - (rt_uint32_t)RK_PSRAMHEAP_BEGIN);
|
|
}
|
|
INIT_COMPONENT_EXPORT(rt_psram_heap_init);
|
|
|
|
void *rt_malloc_psram(rt_size_t size)
|
|
{
|
|
//rt_kprintf("rt_malloc_dtcm: size = %d\n", size);
|
|
if (size < RT_PSRAM_MALLOC_THRRESH)
|
|
return NULL;
|
|
|
|
return rt_memheap_alloc(&_psram_heap, size);
|
|
}
|
|
RTM_EXPORT(rt_malloc_psram);
|
|
|
|
void rt_free_psram(void *ptr)
|
|
{
|
|
rt_memheap_free(ptr);
|
|
}
|
|
RTM_EXPORT(rt_free_psram);
|
|
|
|
void *rt_dma_malloc_psram(rt_size_t size)
|
|
{
|
|
void *align_ptr;
|
|
void *ptr;
|
|
rt_size_t align, align_size;
|
|
|
|
//rt_kprintf("rt_dma_malloc_dtcm: size = %d\n", size);
|
|
if (size < RT_PSRAM_MALLOC_THRRESH)
|
|
return NULL;
|
|
|
|
align = 4;
|
|
align_size = 0;
|
|
|
|
#ifdef CACHE_LINE_SIZE
|
|
align = CACHE_LINE_SIZE;
|
|
#endif
|
|
|
|
#ifdef DMA_ALIGN_SIZE
|
|
align = align > DMA_ALIGN_SIZE ? align : DMA_ALIGN_SIZE;
|
|
#endif
|
|
|
|
align_size = RT_ALIGN(size, align) + align;
|
|
ptr = rt_memheap_alloc(&_psram_heap, align_size);
|
|
if (ptr != RT_NULL)
|
|
{
|
|
/* the allocated memory block is aligned */
|
|
if (((rt_uint32_t)ptr & (align - 1)) == 0)
|
|
{
|
|
align_ptr = (void *)((rt_uint32_t)ptr + align);
|
|
}
|
|
else
|
|
{
|
|
align_ptr = (void *)(((rt_uint32_t)ptr + (align - 1)) & ~(align - 1));
|
|
}
|
|
|
|
/* set the pointer before alignment pointer to the real pointer */
|
|
*((rt_uint32_t *)((rt_uint32_t)align_ptr - sizeof(void *))) = (rt_uint32_t)ptr;
|
|
|
|
ptr = align_ptr;
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
RTM_EXPORT(rt_dma_malloc_psram);
|
|
|
|
void rt_dma_free_psram(void *ptr)
|
|
{
|
|
void *real_ptr;
|
|
|
|
real_ptr = (void *) * (rt_uint32_t *)((rt_uint32_t)ptr - sizeof(void *));
|
|
rt_memheap_free(real_ptr);
|
|
}
|
|
RTM_EXPORT(rt_dma_free_psram);
|
|
|
|
#endif
|