Toriyung

导航

freertos-内部机制:栈和寄存器变化

首先为了不会绕晕,需要明确概念:寄存器是公用的,栈是私有的,因为寄存器轮着用所以才需要将寄存器值压入栈,当压入栈后,寄存器就可以进行值的更新。

 

创建任务

  创建任务本质是伪造现场,由于之后的启动任务需要进行现场的保存,但在没有任务即任务现场不存在的情况下需要进行伪造。

  具体是栈的创建分配和寄存器值的写入:如下图,比较重要的是任务函数的地址(写入返回地址,因为中断切换任务时,主要就是切入到任务函数中)和传参R0

  然后需要将这个栈的地址R4如图中200003CC保存在一个记录栈地址的数组中

 

启动任务

  主栈

    启动任务或者任务调度本身是一个死循环while,通过中断进行任务调度。按程序顺序分析,在main函数中调用任务启动start_task函数,此时由于从main函数进入了子函数,LR寄存器记录了start_task函数的下一条指令;在start_task中进入while死循环,当任务1启动即出现中断时,“返回地址”寄存器记录了中断返回地址为while,即中断结束回到while循环;产生中断时,硬件自动将包含LR和“返回地址”等寄存器压入主栈;同时LR被赋予一个特殊值(EXC_RETURN);进入中断,首先进入System_Handler_asm,这里软件将R4~R11寄存器和LR压入主栈,同时LR写入R0,R1指向主栈。

  任务1栈

    进入System_Handler,传参为R0,R1,此时由于进入子函数LR赋值为System_Handler下一条指令;System_Handler中,有三条分支,其中分支2为启动任务,首先找出任务1栈的地址,进入函数StartTask_asm,传参为任务1栈和R0,根据任务1栈软件恢复R4~R11寄存器,同时BX R0指令实现硬件恢复剩余寄存器。

  

 

 

切换任务

  任务1栈:
    硬件自动将包含LR和“返回地址”等寄存器压入任务1栈,同时LR被赋予一个特殊值(EXC_RETURN);进入中断,首先进入System_Handler_asm,软件保存任务1的R4~R11寄存器值到任务1栈,同时LR写入R0,R1指向任务1栈。

  任务2栈:

    进入System_Handler,传参为R0,R1,此时由于进入子函数LR赋值为System_Handler下一条指令;System_Handler中,有三条分支,其中分支3为切换任务,首先记录任务1栈进入数组,找出任务栈2的地址,进入函数StartTask_asm,传参为任务2栈和R0,根据任务2栈软件恢复R4~R11寄存器,同时BX R0指令实现硬件恢复剩余寄存器。

 

posted on 2022-10-28 16:44  Toriyung  阅读(257)  评论(0编辑  收藏  举报