freeRtos虚拟堆栈与内存分配

static void vTaskLED1(void *pvParameters)
{
uint8_t j = 0;
    while(1) {
	j++;
	vTaskDelay(3);
   }
}
StackType_t    user1_puxStackBuffer[24] = {0};
StaticTask_t   user1_pxTaskBuffer[256] = {0};

int main(void)
{	  
    xTaskCreateStatic(vTaskLED1, "vTaskLED1", 24, NULL, 1, user1_puxStackBuffer, user1_pxTaskBuffer);
    vTaskStartScheduler();
}

其中user1_puxStackBuffer的首地址是0x20000068

执行函数xTaskCreateStatic,当执行完pxNewTCB->pxTopOfStack = pxTopOfStack;之后得到:

0 0x20000068
1 0x2000006C
2 0x20000070
3 0x20000074
4 0x20000078
5 0x2000007C
6 0x20000080 R4 <==pxTopOfStack
7 0x20000084 R5
8 0x20000088 R6
9 0x2000008C R7
10 0x20000090 R8
11 0x20000094 R9
12 0x20000098 R10
13 0x2000009C R11
14 0x200000A0 R0 pvParameters
15 0x200000A4 R1
16 0x200000A8 R2
17 0x200000AC R3
18 0x200000B0 R12
19 0x200000B4 LR prvTaskExitError
20 0x200000B8 PC pxTaskCode
21 0x200000BC xPSR portINITIAL_XPSR
22 0x200000C0
23 0x200000C4

watchlist如下图:


然后执行到图的位置发现watchlist没有任何变化,如下图:


但是上图可以看到 j  的值已经变为 1 了。

然后单步(快捷键F11)进入taskdelay,看到寄存器R0的值变味3,如下图:


然后再单步运行一步(快捷键F11),如下图:


可以看到register界面的R4也变为1,右侧watchlist的虚拟堆栈[18]的值有个1.

然后全速运行(快捷键F5),如下图:


可以看到上图右侧watchlist虚拟堆栈的[17]值是0x61000000,这个位置正是xPSR的位置,在本文的开头xPSR的位置在[21]的位置,可以看出虚拟栈的位置向低地址挪了(21-17)*4=16字节,挪出来给虚拟堆(就是给临时变量)使用了。




另外,非常值得注意的几点:

(1)仔细观察可以发现上图[21]有个0x08000423,。

经过试验发现,如果把临时变量弄多一点,比如把变量j改成个数组,那么类似于0x08000423就没了。说白了就是说这个0x08000423是什么我还是没有搞清楚。

(2)task下的临时内存定义了,即便没有调用,也会占用虚拟堆的资源。因为这个虚拟毕竟是虚拟的,没有真实的编译器那么智能,真实的编译器(就是说非OS情况下)会判断临时变量没有被使用,不将其编译进去(就是不分配内存),即便在优先级是0的情况下。这个ARMCC编译器还是很牛的。


一点心得,长路漫漫,离真正弄懂这个freeRtos还有很长的路要走!!

阅读更多
版权声明:本文为博主unsv29原创文章,未经博主允许不得转载。 https://blog.csdn.net/unsv29/article/details/78690099
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭