STM32 dual stack and its use in uC/OS-II

Publisher:心灵舞动Latest update time:2018-12-03 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Note: There may be many wrong ideas in it. I hope everyone will correct them in time after discovering them.


First, let's learn about the dual stack. The following picture is from the "Cortex-M3 Definitive Guide". It's a bit boring, but you still need to read it.


1

2

3  

345

4

5

6

789

101112

1314


Summarize:


1. After the system is reset, the default is MSP. The state after reset is the privileged thread state. In this state, the register CONTROL[1] can be modified (see the picture above). After entering the user privilege state, these registers cannot be modified.


2. MSP or PSP can be used in user privileged mode (that is, non-interrupt service routines established by users), and only MSP can be used in privileged mode (interrupt service routines).


3. Another very important point is that if PSP is used in user mode, the value of the register is saved in the task stack space. After entering the interrupt program, MSP is used. If there is a high-priority interrupt, MSP will continue to be used. When the program exits the last level of interrupt, the user stack is used to restore the register.


The following uses uCOS-II as an example to illustrate:


First, create a stack OS_STK AppTaskStartStk[1024] //32 bits


STM32 is a full stack that grows downward. After the stack is initialized (before PSP is used, MSP is always used).

                 | .... | AppTaskStartStk[0]
                 |-----------------|
                 | .... | AppTaskStartStk[1]
                 |-----------------|
                 | .... |
                 |-----------------| |---- PSP
    Low Memory during Task Switching | .... | |
                 |-----------------| | |---------------| |----------------|
        ^ | R4 | <----|----|--OSTCBStkPtr |<-----| (OS_TCB *) |
        ^ |-----------------| |---------------| |----------------|
        ^ | R5 | | | OSTCBHighRdy
        | |-----------------| |---------------|
        | | R6 | | |
        | |-----------------| |---------------|
        | | R7 | | |
        | |-----------------| |---------------|
        | | R8 | Task's
        | |-----------------| OS_TCB
        | | R9 |
        | |-----------------|
        | | R10 |
      Stack |-----------------|
      Growth | R11 |
       = 1 |-----------------|
        | | R0 = p_arg | <-------- PSP at exception (full stack growing downward)
        | |-----------------|
        | | R1 |
        | |-----------------|
        | | R2 |
        | |-----------------|
        | | R3 |
        | |-----------------|
        | | R12 |
        | |-----------------|
        | | LR |  
        | |-----------------|
        | | SP = task | AppTaskStartStk[1022]
        | |-----------------|
        | | xPSR | AppTaskStartStk[1023]
    High Memory |-----------------|                                       


Before the first execution of the PendSV interrupt, PSP = 0 has been initialized. MSP is used before entering the interrupt, so the values ​​of the registers automatically pushed onto the stack are saved in the system stack. Since it is the first execution, there is no need to manually save PSP and {R4-R11} into the task stack, and then fetch data from the task stack space into registers {R4-R11}. When exiting the interrupt, set bit 2 of LR to ensure that PSP is used when exiting the interrupt, restore the values ​​of the remaining registers (the values ​​of these registers are automatically pushed onto the stack), and finally enter the task. When executing the task program, PSP is used, and any numbers that need to be pushed onto the stack will be entered into the task stack. Now consider two situations.


(1) If there is a high-priority interrupt to be executed, the register values ​​automatically pushed into the stack will be saved in the stack of the current task, and the MSP will be used after entering the interrupt service routine (if the remaining registers need to be saved, the compiler will automatically generate the corresponding assembly code and save it to the system stack instead of the task stack). If there are higher-priority interrupts later, the MSP will continue to be used.


(2) If there is a high-priority task that needs to be executed at this time, then xPSR, PC, LR, R12, R0-R3 are automatically saved to the stack of the current task by hardware, and then PSP and {R4-R11} need to be pushed into the stack manually.


If two data are pushed onto the stack during the execution of a low-priority task, the result of saving the registers after entering the PendSV interrupt is as follows:


   | .... | AppTaskStartStk[0]
                 |-----------------|
                 | .... | AppTaskStartStk[1]
                 |-----------------|
                 | .... |
                 |-----------------| |---- PSP
    Low Memory during Task Switching | .... | |
                 |-----------------| | |---------------| |----------------|
        ^ | R4 | <----|----|--OSTCBStkPtr |<-----| (OS_TCB *) |
        ^ |-----------------| |---------------| |----------------|
        ^ | R5 | | | OSTCBHighRdy
        | |-----------------| |---------------|
        | | R6 | | |
        | |-----------------| |---------------|
        | | R7 | | |
        | |-----------------| |---------------|
        | | R8 | Task's
        | |-----------------| OS_TCB
        | | R9 |
        | |-----------------|
        | | R10 |
      Stack |-----------------|
      Growth | R11 |
       = 1 |-----------------|
        | | R0 = p_arg | <-------- PSP on exception (full stack growing downwards)
        | |-----------------|
        | | R1 |
        | |-----------------|
        | | R2 |
        | |-----------------|
        | | R3 |
        | |-----------------|
        | | R12 |
        | |-----------------|
        | | LR |  
        | |-----------------|
        | | SP = task |

        | |------------------|
        | | xPSR |

        | |-----------------|

        | | 0x11111111 |

        | |------------------|
        | | 0x22222222 |

High Memory |-----------------|


Keywords:STM32 Reference address:STM32 dual stack and its use in uC/OS-II

Previous article:About assert_param() in STM32
Next article:STM32 interrupts and exceptions

Recommended ReadingLatest update time:2024-11-16 16:56

stm32 notes: key input (simplified version)
C Code   //GPIOA8 is LED0   //GPIOA13 is KEY0 only contains startup code STM32F10x.s      #define GPIOA_CRL (*(volatile unsigned long *)(0x40000000+0x10000+0x0800+0x00))   #define GPIOA_CRH (*(volatile unsigned long *)(0x40000000+0x10000+0x0800+0x04))   #define GPIOA_IDR (*(volatile unsigned long *)(0x40000000
[Microcontroller]
stm32 notes: key input (simplified version)
Summary of 8 working modes of GPIO in STM32
 1. Push-pull output: can output high and low levels, connect digital devices; push-pull structure generally refers to two transistors being controlled by two complementary signals, one transistor is always turned on while the other is turned off. The high and low levels are determined by the power supply of the IC. A
[Microcontroller]
Summary of 8 working modes of GPIO in STM32
STM32 study notes Ethernet communication + lwip protocol transplantation
STM32F107 comes with MAC controller Some chips combine Mac and PHY together, such as ENC28J60 Ethernet communication is based on the TCP/IP protocol, which is the LWIP protocol. This LWIP protocol can run on STM32. STM32F107 is a library specifically made for Ethernet peripherals. Directly download the correspon
[Microcontroller]
STM32: Flash erase and read and write operations
Application platform: STM32F030F4P6 ST official library: STM32Cube_FW_F0_V1.9.0 background knowledge For most MCUs and microcontrollers (ARM, x86), the address space is in bytes, which means that one address is one byte. Flash memory has a characteristic that it can only write 0, not 1. So if there is data at the
[Microcontroller]
STM32 USB Design--Hardware
The STM32 chip integrates USB peripherals, which greatly reduces the design burden of USB circuits. You only need to design the USB interface circuit to realize the USB communication design of the circuit board based on the STM32 chip. (This article will specifically describe the USB design based on the STM32F103RBT6 c
[Microcontroller]
STM32 USB Design--Hardware
(V) STM32 engineering code HardFault exception error checking and debugging method
1. There are many reasons for exceptions, such as directly using pointers to unallocated space, stack overflow, and other illegal operations that will cause the program to enter the HardFault exception state. The following describes how to find the exceptions in the program. Next, in the keil_MDK project, compile th
[Microcontroller]
(V) STM32 engineering code HardFault exception error checking and debugging method
stm32 rtc error experiment
1. stm32f103re, using external crystal oscillator 32.768k, without calibrating the rtc clock, using the serial port to print time, and using a serial port tool with timestamp to record the time received by the serial port. 2. The test lasts one day. Data are as follows: Start timing: Computer time stm32 time 00
[Microcontroller]
STM32 motor control synchronous electrical angle test description
Preface When using the ST   FOC motor library , when using the Hall signal as the position signal, it is necessary to input the synchronous electrical angle data. This data is input according to the characteristics of the current motor in use, and the electrical angle will be synchronized every time the Hall signal ch
[Microcontroller]
STM32 motor control synchronous electrical angle test description
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
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号