硬汉嵌入式论坛

 找回密码
 立即注册
查看: 10981|回复: 1
收起左侧

[μCOS-II] STM32双堆栈及其在uC/OS-II中的使用

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106978
QQ
发表于 2012-5-26 22:23:54 | 显示全部楼层 |阅读模式
说明:里面可能有错误的观念,希望大家发现后及时的纠正。
     首先了解一下双堆栈的知识,下面的图片来自《Cortex-M3权威指南》,有点枯燥,但还是要看的。
1.png
2.png
3.png
345.png
4.png
5.png
6.png
7.png
8.png
9.png
14.png
10.png
11.png
12.png
13.png
14.png

总结:
1.系统复位后默认使用的是MSP,复位后的状态是特权级线程状态,在这个状态下是允许修改寄存器
   CONTROL[1](见上面的图片)的。进入到用户特权以后就不能修改这些寄存器了。
2.用户特权的情况(也就是用户建立的非中断服务程序)下可以使用MSP或PSP,特权模式(中断
   服务程序)只能使用MSP。
3.还有很重要的一条就是.假如在用户模式下使用的是PSP,那么寄存器的数值被保存到任务堆栈的空间,
  进入中断程序后就开始使用MSP,如果还有一个高优先级的中断难么就继续的使用MSP,在程序推出最
  后一级中断的时候就用用户堆栈恢复寄存器。
下面以uCOS-II为例进行说明:
首先建立一个堆栈  OS_STK   AppTaskStartStk[1024] //32位
STM32是向下生长的满栈,初始化堆栈后(在没有使用PSP以前,一直使用的是MSP)。                 

                |    ....            | AppTaskStartStk[0]
                |-----------------|
                |    ....           | AppTaskStartStk[1]
                |-----------------|
                |    ....           |
                |-----------------|       |---- 任务切换时PSP
                |    ....           |       |
                |-----------------|       |   |-----------------------|       |--------------------|
       ^       |      R4         | <----|----|--OSTCBStkPtr |<-----|   (OS_TCB*)   |
       ^       |-----------------|              |-----------------------|        |-------------------|
       ^       |      R5         |               |                           |        OSTCBHighRdy
       |       |-----------------|               |-----------------------|
       |       |      R6         |                |                           |
       |       |-----------------|               |-----------------------|
       |       |      R7         |               |                           |
       |       |-----------------|               |-----------------------|
       |       |      R8         |                Task's
       |       |-----------------|                OS_TCB
       |       |      R9         |
       |       |-----------------|
       |       |     R10        |
     Stack  |-----------------|
     Grow |     R11         |
      =1    |-----------------|
       |       |    R0 =p_arg <-------- 异常时的PSP (向下生长的满栈)
       |       |-----------------|
       |       |      R1         |
       |       |-----------------|
       |       |      R2         |
       |       |-----------------|
       |       |      R3        |
       |       |-----------------|
       |       |      R12       |
       |       |-----------------|
       |       |      LR         |  
       |       |-----------------|
       |       |    SP =task    |AppTaskStartStk[1022]
       |       |-----------------|
       |       |     xPSR      | AppTaskStartStk[1023]
                |-----------------|  
                             
第一次执行PendSV中断之前,已经初始化PSP =0 ,进入中断前使用的是MSP,所以自动入栈的寄存器的数值是保存在了系统堆栈里面,由于是第一次执行,不需要手动保存PSP和{R4-R11}到任务堆栈里面,然后从任务堆栈空间中取出数据到寄存器{R4-R11}中,退出中断的时候设置LR的位2,保证退出中断的时候使用PSP,恢复剩下的寄存器(这些寄存器的数值是自动入栈的)的数值,最后就进入到了任务里面,在执行任务程序的时候,使用的是PSP,有需要入栈的数,就会进入到任务堆栈里面。现在分两种情况进行考虑,
(1)有一个高优先级的中断要执行,那么自动入栈的寄存器数值会保存到当前任务的堆栈里面,进入到中断服务程序以后就开始使用MSP(剩下的的寄存器如果需要保存的话,会由编译器自动的生成相应的汇编代码,保存到系统堆栈,而不是任务堆栈),如后还有更高优先级的中断,那么就会一直使用MSP。
(2) 如果此时有一个高优先级的任务需要执行,那么xPSR,PC, LR, R12, R0-R3自动的由硬件保存到当前任务的堆栈里面,然后PSP和{R4-R11}需要手工的入栈。
假如在执行低优先级任务的过程中有两个数据压栈了。那么进入PendSV中断后保存寄存器的结果如下:

                 |     ....             | AppTaskStartStk[0]
                |-----------------|
                 |     ....            |AppTaskStartStk[1]
                 |-----------------|
                |     ....            |
                 |-----------------|       |----任务切换时PSP
                 |     ....            |       |
                |-----------------|       |      |--------------       -|        |--------------------|
        ^        |       R4        | <----|----|--OSTCBStkPtr  |<----- |   (OS_TCB *)   |
        ^       |-----------------|            |----------------------|        |--------------------|
        ^        |       R5          |           |                           |         OSTCBHighRdy
        |       |-----------------|            |----------------------|
        |        |      R6          |            |                           |
        |       |-----------------|            |----------------------|
        |        |      R7          |            |                           |
        |       |-----------------|            |----------------------|
        |        |      R8         |                 Task's
        |       |-----------------|                 OS_TCB
        |        |       R9        |
        |        |-----------------|
        |        |      R10        |
      Stack  |-----------------|
      Growth|      R11       |
       = 1     |-----------------|
        |        |    R0 = p_arg  |  <-------- 异常时的PSP (向下生长的满栈)
        |       |-----------------|
        |        |       R1          |
        |       |-----------------|
        |        |       R2          |
        |       |-----------------|
        |        |       R3          |
        |       |-----------------|
        |        |       R12        |
        |       |-----------------|
        |        |       LR          |  
       |        |-----------------|
        |        |    SP = task    |
        |        |-----------------|
        |        |      xPSR      |
        |        |-----------------|
        |        | 0x11111111  |  AppTaskStartStk[1022]
        |        |-----------------|
        |       | 0x22222222 | AppTaskStartStk[1023]
                 |-----------------|
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-12 17:04 , Processed in 0.184392 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表