freeRtos虚拟堆栈与内存分配

来源:互联网 发布:suse linux安装详解 编辑:程序博客网 时间:2024/06/06 10:52
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;之后得到:

00x2000006810x2000006C20x2000007030x2000007440x2000007850x2000007C60x20000080R4<==pxTopOfStack70x20000084R580x20000088R690x2000008CR7100x20000090R8110x20000094R9120x20000098R10130x2000009CR11140x200000A0R0pvParameters150x200000A4R1160x200000A8R2170x200000ACR3180x200000B0R12190x200000B4LRprvTaskExitError200x200000B8PCpxTaskCode210x200000BCxPSRportINITIAL_XPSR220x200000C0230x200000C4
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还有很长的路要走!!