参考
- 运行时访问
__initial_sp和__heap_base
无RTOS时的情况

在以上配置的情况下,生成工程。在工程的startup.s文件中,由如下代码:
Stack_Size EQU 0x400
AREA STACK, NOINIT, READWRITE, ALIGN=3
__Stack_top ; 自己添加
Stack_Mem SPACE Stack_Size
__initial_sp
IF :DEF:__MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
EXPORT __Stack_top ; 自己添加
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ALIGN
ENDIF
通过以上代码可以看出,需要使能MicroLib才会默认导出__initial_sp,__Stack_top,__heap_base,__heap_limit这几个变量。(如果不使能MicroLib,则需要在上面代码的ELSE下面也添加EXPORT语句将这几个变量导出)。
然后在main.c中添加如下代码,查看以上这些变量的值:
extern uint32_t __heap_base, __heap_limit;
extern uint32_t __Stack_top, __initial_sp;
extern uint32_t __Vectors, __Vectors_End, __Vectors_Size;
while (1)
{
// 0x200013A8 ~ 0x200015A8 size:0x200 RAM
printf("heapS[0x%08x], heapE[0x%08x]\r\n", (uint32_t)&__heap_base, (uint32_t)&__heap_limit);
// 0x200019A8 ~ 0x200015A8 size:0x400 RAM
printf("stackS[0x%08x], stackE[0x%08x]\r\n", (uint32_t)&__initial_sp, (uint32_t)&__Stack_top);
// 0x08000000 ~ 0x080000EC ROM
printf("VectS[0x%08x], VectE[0x%08x], VectSize[0x%x]\r\n\r\n", (uint32_t)&__Vectors, (uint32_t)&__Vectors_End, (uint32_t)&__Vectors_Size);
}
从上可以看到,__Stack_top和__heap_limit是一样的,说明这里分配的堆和栈是紧邻的。而且地址刚好也和我们在cubeMx中定义的一致。堆和栈是在RAM中,而中断向量表是在Flash中。
添加FreeRTOS



从以上三张图中,可以发现,我们给FreeRTOS总共分配了3072(0xC00) Bytes HEAP空间。而我们定义了一个defaultTask并分配了256 * 4 = 1024 Bytes,但是在最后的FreeRTOS Heap Usage页面看到,defaultTask实际使用了1144 Bytes,剩余3072 - 1144 = 1928 Bytes。(除了defaultTask多使用的1144 - 1024 = 120 Bytes外,其余都是可以对上的。)
生成工程后,我们还是将之前的那些堆栈指针地址打印出来,看一下MCU是如何进行地址分配的。只是这里还需要添加FreeRTOS中的堆栈信息了。首先通过追踪configTOTAL_HEAP_SIZE可以发现,堆空间定义为了一个数组:
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
uint8_t* osHeapPoint = ucHeap; // 由于以上变量是 static 类型,所有这里再定义一个指针指向这个 Heap 地址,以便在外部访问它;
然后我们就可以在defaultTask任务里面添加输出以上变量地址的代码了:
extern uint32_t __heap_base, __heap_limit;
extern uint32_t __Stack_top, __initial_sp;
extern uint32_t __Vectors, __Vectors_End, __Vectors_Size;
extern uint8_t* osHeapPoint;
for(;;) {
// 0x20002CF8 ~ 0x20002EF8 size:0x200 RAM
printf("HeapS[0x%08x], HeapE[0x%08x]\r\n", (uint32_t)&__heap_base, (uint32_t)&__heap_limit);
// 0x200032F8 ~ 0x20002EF8 size:0x400 RAM
printf("StackS[0x%08x], StackE[0x%08x]\r\n", (uint32_t)&__initial_sp, (uint32_t)&__Stack_top);
// 0x200020F8 size: 3072 Bytes(0xC00)
printf("OsHeapPoint[0x%08x]\r\n\r\n", (uint32_t)osHeapPoint);
// 0x08000000 ~ 0x080000EC ROM
printf("VectS[0x%08x], VectE[0x%08x], VectSize[0x%x]\r\n", (uint32_t)&__Vectors, (uint32_t)&__Vectors_End, (uint32_t)&__Vectors_Size);
}
在freeRTOS中调用malloc()动态分配空间时,这个空间是属于哪个堆呢?



















