嵌入式FreeRTOS学习七,系统任务中断时现场的保护

简单加法函数的示例

void add_val(int *pa,int *pb)
{  
   volatile int tmp;
   tmp = *pa;
   tmp = tmp +*pb;
   *pa = tmp;
}
int main(void)
{
  int a =1;
  int b =2;
  add_value(&a,&b);
  prvSetupHardware();
 
  xTaskCreate(vTask1,"Task1",1000,NULL,0,NULL);
  xTaskCreate(vTask1,"Task1",1000,NULL,0,NULL);
  xTaskCreate(vTask1,"Task1",1000,NULL,0,NULL);
  
  /*启动调度器*/
  vTaskStartScheduler();
}

在第六篇的内容中,分析了a=a+b这个简单的汇编实现过程,知道了参数在CPU寄存器和RAM内存中的作用过程,但是如果在任务执行过程中发生了任务中断,FreeRTOS该怎么保存中断前任务的一些参数呢?保存到哪里?保存那些东西?这就是接下来要说明的内容。

中断之前,CPU把传进来的r0(即第一个参数的值)的值读入R2寄存器中,R2中的值(R2=a=1)还没有使用,任务中断后得对R2的值进行保存,否则之前做的读取工作就白费了。保存R2的值,也就是保存现场,那么什么叫做现场?
现场就是当前任务被打断的瞬间,CPU里面所有寄存器的值!
FreeRTOS通常都是将所有寄存器的值保存到RAM内存中的栈空间中,例如保存CPU里的16个当前值寄存器,当中断任务结束重新从RAM内存中取值重新执行。位置保存在SP指向的位置,在内存RAM内存中开辟一处内存,同时SP=SP-64.
对于STM32F103,cortexM3,cortexM4平台,保存寄存器当前值的时候,有2种寄存器保存方式,一种是硬件保存,一种则是软件保存;硬件保存是保存一部分R0,R1,R2,只要用到了硬件中断,硬件自动保存,不需要代码实现;
软件保存则保存一些用到的寄存器,比如在函数调用的过程中有个约定,例如,函数A调用函数B,寄存器有个规定,R1,R2和R3寄存器用于函数A的参数传递,在函数B执行的过程中,并不需要保存这三个寄存器,相当于临时变量。
如果是任务切换,就是把CPU让出来给另外一个程序使用,上一个程序的寄存器值不能被破坏掉,并且上个任务用到了什么寄存器,这个无法知道,因此,在任务切换的过程中,当前任务被破坏后,所有的寄存器都要进行保存。以便中断任务结束后回来取值继续执行上一个任务。
恢复中断的过程则是相反,从SP指针指向的RAM内存读取到保存的寄存器的值,读取到CPU寄存器中重新执行中断前任务。恢复被中断程序的执行环境,继续执行被中断的程序。

猜你喜欢

转载自blog.csdn.net/weixin_44651073/article/details/127230579
今日推荐