FreeRTOS task source code analysis and the relationship between program stack and task stack

Publisher:平凡的梦想Latest update time:2024-07-10 Source: elecfansKeywords:FreeRTOS Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

——pxNewTCB->pxTopOfStack = pxPortInitialiseStack

The stack is initialized here as if it were interrupted by the scheduler. The 8 registers of the processor stacking, as well as r4-r11 and r14 agreed by FreeRTOS, are pushed into the stack, and the stack top pointer is updated to form the graphic state created above.

vTaskStartScheduler——thread mode, MSP, push r0-r4, lr into the stack, occupying 6*4=24=0x18 bytes, so the stack becomes 0x200100e0-0x18=0x200100c8

——xPortStartScheduler——Thread mode, MSP, push r4, lr into the stack, occupying 2*4=8=0x8 bytes, so the stack becomes 0x200100c8-0x8=0x200100c0

——prvStartFirstTask, thread mode, MSP, leaf function, no stack is used, but the stack is reset = 0x200100f8. Here, the task scheduling environment is initialized after the task scheduling environment is set up, for example, resetting MSP, enabling interrupts, and triggering system call exceptions (where the first task is started)

vPortSVCHandler, processing mode, MSP, exception entry, processor hardware stacking, a total of 8 regs, 4*8=32=0x20, the stack becomes 0x200100f8-0x20=0x200100d8

——Exception entry, when the exception enters, the processor has already performed stacking, here we use msp

——Main body, get the top of the current task stack, and restore r4-r11 and r14 agreed by FreeRTOS

Set PSP to the top of the updated task stack

Enable interrupts

Set LR = 0xFFFF FFFD, return to thread mode, PSP

——Exception return, when the exception exits, the processor performs unstacking, pops the 8 registers from the stack (these are set when creating the task initialization stack, where PC = task entry) and officially starts the first task

————————————————————Before this, MSP was used. After this, PSP was used. MSP was also used in exception handling.

Main_task

Enter the first task execution.

After that, it will enter xPortPendSVHandler, where MSP is still used. To operate the task stack, PSP needs to be read in. However, xPortPendSVHandler will no longer use MSP, because xPortPendSVHandler will no longer call other functions. This is a leaf function, and MSP will no longer be updated in the future.

About program stack and task stack

The program stack can be seen as the MSP and the task stack can be seen as the PSP.

Before creating a task, there is no task stack, only a program stack (let's call it this name for the time being, that is, the stack in the ordinary sense when there is no OS). The stack example project defines 0x200100f8.

Line 2, BLX is used during the call, PC+4 will be placed in LR, and at the same time, r4 and LR will be pushed onto the stack in SystemInit, because other functions are also called in SystemInit, that is, SystemInit is a non-leaf function, and the stack is used here.

Line 3, the call is completed, the stack is restored to 0x200100f8, and when calling __main, BX is used instead of BLX, so __main is a leaf function and should not use the stack. After calling __main, it will jump to the user's main function (__main cannot be single-stepped).


1                  LDR     R0, =SystemInit2                  BLX     R03                  LDR     R0, =__main4                  BX      R05                  ENDP


Starting from the main function, using thread mode, MSP (the processor uses thread mode and MSP by default after reset) will push r0-r4, lr into the stack, occupying 6*4=24=0x18 bytes. Therefore, the stack becomes 0x200100f8-0x18=0x200100e0 (the processor automatically pushes and pops the stack only when entering and leaving an exception. Ordinary function calls are in thread mode and no stacking and unstacking are performed).

About ARM-CM4F porting of FreeRTOS

Under GCC: FreeRTOSV7.3.0portableGCCARM_CM4Fport.c

Keil: FreeRTOSV7.3.0portableRVDSARM_CM4Fport.c (same as Keil and RVDS)

Regarding the differences in vPortSVCHandler, the actual assembly is the same, the difference lies in how the compiler recognizes the assembly code in the c file.

GCC下:


1 void vPortSVCHandler( void )

2 {

3     __asm volatile (

4                     "    ldr    r3, pxCurrentTCBConst2        n" /* Restore the context. */

5                     "    ldr r1, [r3]                    n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */

6                     "    ldr r0, [r1]                    n" /* The first item in pxCurrentTCB is the task top of stack. */

7                     "    ldmia r0!, {r4-r11, r14}        n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */

8                     "    msr psp, r0                        n" /* Restore the task stack pointer. */

9                     "    mov r0, #0                         n"

10                     "    msr    basepri, r0                    n"

11                     "    bx r14                            n"

12                     "                                    n"

13                     "    .align 2                        n"

14                     "pxCurrentTCBConst2: .word pxCurrentTCB                n"

15                 );

16 }


Under RVDS:


1 __asm void vPortSVCHandler( void )

2 {

3 PRESERVE8

4

5     /* Get the location of the current TCB. */

6     ldr    r3, =pxCurrentTCB

7     ldr r1, [r3]

8     ldr r0, [r1]

9     /* Pop the core registers. */

10 ldmia r0!, {r4-r11, r14}

11     msr psp, r0

12 supply r0, #0

13     msr    basepri, r0

14     bx r14

15 }


[1] [2] [3] [4] [5]
Keywords:FreeRTOS Reference address:FreeRTOS task source code analysis and the relationship between program stack and task stack

Previous article:Camera driver learning
Next article:ARM processor base Cortex-M4

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号