关于CM3内核的PSP和msp

1.它们是什么?

       它们是程序堆栈,一个主堆栈和一个进程堆栈,任何时候都只能有一个堆栈使用,可以在pendSV handler()中决定,改变他的sp指针类型并返回。

2.什么是堆栈?

       程序运行时存放程序数据的一个区域,一般存放,程序状态寄存器,程序入口地址,链接寄存器R14地址,R12,R3,R2,R1,R0(参数),R11~R4。这是一个最简单的堆栈区。一般由R13(sp指针)决定。

     举个例子:           

       

//这段代码是在特权模式下才能执行的,用的是MSP,进程模式严禁操作硬件,只能通过系统异常来提交
// 改变硬件的操作。
、....
   u32 task_stack[128];//一个任务堆栈

   u32 *ptop=task_stack-127;//栈顶指针
   ptop=(u32*) ptop&(~(u32)0x00000007)//栈顶对齐
   ....
   ptop-=8;//指向task_stack[119];
....
_asm
   psp=ptop;
   isb;
   orr r14,#0xd  
   bx r14//程序返回后会从msp切换到psp
...
  //关于LR(R14),进入异常中断时系统会写入0xffffffff
  //退出中断时检测到0xffffffff,系统就知道退出中断进入新模式。
  //0xfffffff1:handler模式 0xfffffff9:返回线程模式,sp=msp  0xfffffffd:返回线程模式,sp=psp

  这段代码执行会有那些操作呢?

         它创建了一个栈,然后又有一个栈顶指针,当汇编指令执行完成后,sp(堆栈指针)从msp变成psp。他会执行一个很恐怖的事情,就是:

        

//这一段代码是伪代码,不需要人管,机器会自动执行,psp的出栈操作
...
_asm
mov r0,psp//指向task_stack[119]
psp++
mov r1,psp//指向task_stack[120]
psp++
mov r2,psp//指向task_stack[121]
psp++
mov r3,psp//指向task_stack[122]
psp++
mov r12,psp//指向task_stack[123]
psp++
mov r14,psp//指向task_stack[124]
psp++
mov pc,psp//指向task_stack[125]
psp++
mov xpsr,psp//指向task_stack[126]
psp++
...
//出栈是从下往上,入栈是从上往下,所以这个栈是向下生长的,入栈先减4,是为了地址对齐

  就是相当于将堆栈中的数据给寄存器,然后程序照常运行。发现了吗?

 程序会自动从堆栈区读取数据和保存数据,这些数据就是程序运行时所需要的所有的状态地址。只要我们更改psp和msp所指向的地址,就可以决定程序从那个地方开始运行。

3.程序运行读写堆栈是设备自动读取的。

4.freertos的堆栈区存储的是这些数据:

   

       总结一下就是R0~R15和一个状态指针,知道点的都知道,汇编的所有操作就是这几个寄存器数据的变化,任何某一时刻这几个寄存器的数据都是特定的。保存它们到一个数组中,过一会拿出来放到相应寄存器,它们又可以继续运行。

     这就是Cm3内核的bootloader和freertos的任务切换原理。psp和msp所指向的堆栈中也就是存着这几个数据。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值