您的位置:首页 > 其它

threadx 系统栈和进程栈的使用情况

2018-02-01 13:15 197 查看
在启动代码中会初始化__init_sp , 同时把这个地址放在中断向量表的首位。

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

    Low Memory   |     ....        |       |

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

        ^        |       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    | AppTaskStartStk[1022]

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

        |        |      xPSR       | AppTaskStartStk[1023]

    High Memory  |-----------------|                                       
第一次执行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

    Low Memory   |     ....        |       |

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

        ^        |       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     |
        |        |-----------------|

        |        |  0x22222222     |
High Memory      |-----------------|
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐