——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 }
Previous article:Camera driver learning
Next article:ARM processor base Cortex-M4
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Detailed explanation of intelligent car body perception system
- How to solve the problem that the servo drive is not enabled
- Why does the servo drive not power on?
- What point should I connect to when the servo is turned on?
- How to turn on the internal enable of Panasonic servo drive?
- What is the rigidity setting of Panasonic servo drive?
- How to change the inertia ratio of Panasonic servo drive
- What is the inertia ratio of the servo motor?
- Is it better for the motor to have a large or small moment of inertia?
- What is the difference between low inertia and high inertia of servo motors?
- Problems with the Linux development board
- 【GD32L233C-START Review】 Second Development Board Function Review
- The drilling marks are clear, why is there a hole missing on the PCB?
- Why are XH connector manufacturers so stupid?
- A summary of the most downloaded electronic technical materials this week (2020.6.1~5)
- Synplify Quick Start
- upyLoader failed to initialize the file transfer. How can I solve this problem?
- Introduction to the factors that cause the switching power supply loop instability
- Several RP2040 boards added in recent MicroPython updates
- Analysis of the reasons why Lingdong MM32 cannot be burned