STM32上RTOS内存配置说明

1.说明

  在STM32上进行RTOS(以rt-thread为例)配置动态内存管理方式,我们需要设置一个动态内存管理的访问, 也就是管理区域的大小,起始地址等。

2.管理内存的范围

  在使用操作系统前,先看一下原始的分配情况:startup_stm32f103xe.s

; Amount of memory (in bytes) allocated for Stack
; Tailor this value to your application needs
; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Stack_Size      EQU     0x00000400 ;栈的大小

                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp

; <h> Heap Configuration
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

Heap_Size       EQU     0x00000200 ;堆的大小情况

                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem        SPACE   Heap_Size
__heap_limit

加载操作系统后,我们开始初始化heap区

rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);

从上面可以看到管理的范围为 HEAP_BEGIN~HEAP_END HEAP_BEGIN:

#if defined(__ARMCC_VERSION)
extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN      ((void *)&Image$$RW_IRAM1$$ZI$$Limit)
#elif __ICCARM__
#pragma section="CSTACK"
#define HEAP_BEGIN      (__segment_end("CSTACK"))
#else
extern int __bss_end;
#define HEAP_BEGIN      ((void *)&__bss_end)
#endif

我们使用armcc进行编译时:

#define HEAP_BEGIN      ((void *)&Image$$RW_IRAM1$$ZI$$Limit)

Image$$RW_IRAM1$$ZI$$Limit是链接器导出的符号,表示ZI段结束后,也就是程序执行区的RAM结束后的地址, 从编译生成的map文件可以看到: Total RW Size (RW Data + ZI Data) 22578 ( 22.05kB) 这就表示了静态RAM空间以及用掉了22.05k,芯片总RAM有多少K,减去已经消耗部分,其实这个部分就是.BSS段的 结束地址。 HEAP_END

/* Internal SRAM memory size[Kbytes] <8-64>, Default: 64*/
#define STM32_SRAM_SIZE      64
#define STM32_SRAM_END       (0x20000000 + STM32_SRAM_SIZE * 1024)
#define HEAP_END        STM32_SRAM_END

很好理解,就是SRAM结尾地址。