SVC和PendSV

转载于:http://book.2cto.com/201209/4625.html

1.SVC

SVC(Supervisor Call)指令用于产生一个SVC异常。它是用户模式代码中的主进程,用于创造对特权操作系统代码的调用。SVC是用于呼叫操作系统所提供API的正道。用户程序只需知道传递给操作系统的参数,而不必知道各API函数的地址。

SVC指令带一个8位的立即数,可以视为是它的参数,被封装在指令自身,如:

  SVC    3; 呼叫3号系统服务

则3被封装在这个SVC指令中。因此在SVC服务例程中,需要读取本次触发SVC异常的SVC指令,并提取出8位立即数所在的位段,从而判断系统调用号,工作流程如图7-7所示。

SVC和PendSV_第1张图片
 


实现上图功能的代码如下所示:
svc_handler
 TST       LR,   #0x4;  ;测试EXC_RETURN的比特2
 ITE       EQ;    ;如果为0
 MRSEQ   R0,   MSP;   ;则使用的是主堆栈,故把MSP的值取出
 MRSNE   R0,   PSP;   ;否则,使用的是进程堆栈,故把PSP的值取出
 LDR      R1,   {R0,#24}; ;从栈中读取PC值
 LDRB     R0,  {R1,#-2};  ;从SVC指令中读取立即数放到R0
; 准备调用系统服务函数。这需要适当调整入栈的PC值及LR(EXC_RETURN)来进入OS内部
  BX        LR;     ;借异常返回的形式,进入OS内部,最终调用系统服务函数

一旦获取了调用号,就可以用它来调用系统服务函数了。有理由相信,操作系统应该使用TBB/TBH查表跳转指令来加速定位正确的服务函数。然而,如果读者是设计OS的人员,则必须检查这个参数的合法性,以免因数字超出跳转表的范围而跳飞。因为不能在SVC服务例程中嵌套使用SVC,所以如果有需要,就要直接调用SVC函数,如使用BL指令。

2.PendSV

PendSV是为系统级服务提供的中断驱动。在一个操作系统环境中,当没有其他异常正在执行时,可以使用PendSV来进行上下文的切换。

在进入PendSV处理函数时:

(1)xPSR、PC、LR、R12、R0~R3已经在处理栈中被保存。

(2)处理模式切换到线程模式。

(3)栈是主堆栈。

由于PendSV在系统中被设置为最低优先级,因此只有当没有其他异常或者中断在执行时才会被执行。


你可能感兴趣的:(FreeRtos)