搜索
bottom↓
回复: 5

uC/OS-II学习笔记(二)-堆栈和CPU寄存器

[复制链接]

出0入0汤圆

发表于 2013-10-16 15:00:11 | 显示全部楼层 |阅读模式

1. uC/OS-II有定义堆栈的生长方向,在OS_CPU.h里

#define OS_STK_GROWTH              1              //从高地址往低地址,STM32F10x就是往上生长方向

堆栈的是往上长的(就是说往顶的方向长,其实质是你的栈底是定死的不能动,入栈的东西只能不断往上
叠,这就像你在书桌上放书一样,桌底是定死的,所以你的书只能一本一本地往上堆,往上长)“先修改指
针,然后插入数据,出栈时刚好相反”,因为堆栈指针指向的总是栈顶元素,栈底不能动,所以数据入栈前
要先修改指针使它指向新的空余空间然后再把数据存进去,出栈的时候自然相反。

下图为任务的堆栈
;//                       Low Memory
//                       |     ....        |
;//                      |-----------------|
;//                      |     ....        |
;//                      |-----------------|
;//                      |     ....        |
;//                      |-----------------|       |---- 任务切换时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       |
;//        |             |-----------------|
;//        |             |  PC = task  |
;//        |             |-----------------|
;//        |             |      xPSR    |
;//                      |-----------------|
;//                        High Memory


2. 需要说明的是uC/OS-II在执行任务切换中断时
1)xPSR,PC,LR,R12,R0~R3,这几个寄存器在进入中断的时候自动保存,只有剩下的几个寄存器需要手动保存。
2)每个任务初始化堆栈的时候,将堆栈指针R13指向相应的任务地址,这样初始化以后进行任务切换时,就能将变量存入自己的任务堆栈

3. Cortex-M3 处理器拥有 R0-R15 的寄存器组


1) R0-R12:32位通用寄存器,用于数据操作。绝大多数 16位Thumb指令只能访问R0-R7,而 32位 Thumb-2指令可以访问所有寄存器。

2) R13:两个堆栈指针SP,但在同一时刻只能有一个可以看到,这也就是所谓的“banked”寄存器。
     主堆栈指针(MSP):复位后缺省使用的堆栈指针,用于操作系统内核以及异常处理例程(包括中断服务例程)
   进程堆栈指针(PSP):由用户的应用程序代码使用。
   在ARM变成领域中,凡是打断程序顺序执行的时间,都被称为异常(exception),除了外部中断之外,当有指令执行了“非法操作”,或者
   访问被禁的内存区间,因各种错误产生的错误Fault,以及不可屏蔽中断发生时,都会打断程序的执行,这些情况统称为异常,在不严格
   的上下文中,异常与中断也可以混用,程序代码也可以主动请求进入异常状态。
   堆栈指针的最低两位永远是0,即对阵总是4字节对齐的

3) R14:连接寄存器 ( LR )
   当调用一个子程序时,由R14存储返回地址。
   ARM为了减少访问内存的次数(访问内存的操作往往要 3个以上指令周期,带MMU和cache的就更加不确定了),把返回地址直接存储在寄存器
   中。这样足以使很多只有1级子程序调用的代码无需访问内存(堆栈内存),从而提高了子程序调用的效率。如果多于 1 级,则需要把前一级的
   R14 值压到堆栈里。在 ARM上编程时,应尽量只使用寄存器保存中间结果,迫不得以时才访问内存。在 RISC 处理器中,为了强调访内操作
   越过了处理器的界线,并且带来了对性能的不利影响,给它取了一个专业的术语:溅出。

4) R15:程序计数寄存器 ( PC )
   指向当前的程序地址。如果修改它的值,就能改变程序的执行流向(很多高级技巧就在这里面)。

5) 特殊功能寄存器
   Cortex-M3还在内核水平上搭载了若干特殊功能寄存器,包括
   程序状态字寄存器组(PSRs)
   中断屏蔽寄存器组(PRIMASK, FAULTMASK, BASEPRI)
   控制寄存器(CONTROL)
   
   Cortex-M3 中的特殊功能寄存器集合
   

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2013-10-17 11:33:03 | 显示全部楼层
Mark            

出0入8汤圆

发表于 2013-10-17 11:49:05 | 显示全部楼层

Mark                    

出0入0汤圆

发表于 2013-10-17 12:58:38 | 显示全部楼层
mark                                                                                      

出0入0汤圆

 楼主| 发表于 2013-10-22 11:08:11 | 显示全部楼层
处理器自动压栈到R0,也就是说,此时R0即为栈顶指针。在往后空出8个空间的地址,手动入栈R4-R11

出0入0汤圆

 楼主| 发表于 2013-10-30 08:47:25 | 显示全部楼层
              
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 22:12

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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