rt-thread-official/bsp/rockchip/common/drivers/drv_heap.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