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测试。等以后用上了在补充。


上一篇下一篇

猜你喜欢

热点阅读