美文网首页
openharmony: 内存管理移植

openharmony: 内存管理移植

作者: xEndLess | 来源:发表于2022-07-27 10:48 被阅读0次

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


    相关文章

      网友评论

          本文标题:openharmony: 内存管理移植

          本文链接:https://www.haomeiwen.com/subject/yxboirtx.html