openharmony: 内存管理移植
2022-07-27 本文已影响0人
xEndLess
kernel:litoes_m
MCU:stm32f407zgt6
本文只介绍openharmony动态内存的移植过程。openharmony动态内存的原理请移步官网文档。
openharmony分静态内存和动态内存。我现在没明白为什么静态内存也能手动申请和释放。所以本文不涉及静态内存。
1.静态内存
。。。
2.动态内存
2.1单个内存空间
首先需要给liteos_m分配一块非连续的内存空间。有两种方法:
给一个大数组
只需在target_config.h
中增加宏定义即可。如下:
//target_config.h
#define LOSCFG_SYS_HEAP_SIZE (64 * 1024)
使用编译后剩下的内存空间
第一步:在链接文件中增加:
//STM32F407ZGTx_FLASH.ld
/* Uninitialized data section */
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* This is used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
} >RAM
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
/* 动态内存需要增加的部分 */
. = ALIGN(4);
__heap_addr_start__ = .;
__heap_addr_end__ = ORIGIN(RAM) + LENGTH(RAM);
__heap_addr_start__
定义了剩余内存的初始地址。__heap_addr_end__
定义了剩余内存的结束地址。其实就是RAM的结束地址。
第二步:target_config.h
中增加
//target_config.h
/* 动态内存管理 */
extern unsigned int __heap_addr_start__;
extern unsigned int __heap_addr_end__;
#define LOSCFG_SYS_EXTERNAL_HEAP 1
#define LOSCFG_SYS_HEAP_ADDR (void*)(&__heap_addr_start__)
#define LOSCFG_SYS_HEAP_SIZE (unsigned long)((unsigned long)(&__heap_addr_end__) - (unsigned long)(&__heap_addr_start__))
函数OsMemSystemInit()
在los_memory.c
中,函数OsMemSystemInit()
是liteos_m的内存管理初始化函数。OsMemSystemInit()
会在LOS_KernelInit()
中被调用。源码如下:
//los_memory.c
UINT32 OsMemSystemInit(VOID)
{
UINT32 ret;
#if (LOSCFG_SYS_EXTERNAL_HEAP == 0)
m_aucSysMem0 = g_memStart;
#else
m_aucSysMem0 = LOSCFG_SYS_HEAP_ADDR;
#endif
ret = LOS_MemInit(m_aucSysMem0, LOSCFG_SYS_HEAP_SIZE);
PRINT_INFO("LiteOS heap memory address:%p, size:0x%lx\n", m_aucSysMem0, LOSCFG_SYS_HEAP_SIZE);
return ret;
}
g_memStart
是一个数组,STATIC UINT8 g_memStart[LOSCFG_SYS_HEAP_SIZE];
。如果动态内存空间是一个数组的话,必须宏#define LOSCFG_SYS_EXTERNAL_HEAP 0
。
为了使用编译后的所有剩余空间,必须#define LOSCFG_SYS_EXTERNAL_HEAP 1
。然后需要指定LOSCFG_SYS_HEAP_SIZE
的大小。
测试结果如下:
//串口打印信息
entering kernel init...
[INFO][0LiteOS heap memory address:0x20000d00, size:0x1f300
Entering scheduler
//OHOS_Image.map
0x0000000020000d00 . = ALIGN (0x8)
0x0000000020000d00 . = ALIGN (0x4)
0x0000000020000d00 __heap_addr_start__ = .
0x0000000020020000 __heap_addr_end__ = (ORIGIN (RAM) + LENGTH (RAM))
可以看出,heap memory address是对的。
2.2多个非连续内存空间
暂时未使用过,需要外挂ram测试。等以后用上了在补充。