ARM异常处理(4):SVC和PendSV的作用详解

本文详细介绍了SVC(SupervisorCall)和PendSV(PendableServiceCall)两种异常处理机制。SVC用于生成系统函数调用,允许用户程序通过操作系统间接访问硬件资源;PendSV则用于操作系统中的上下文切换,通过挂起异常实现任务间的平滑过渡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SVC(Supervisor Call)和PendSV(Pendable Service Call)是针对软件和操作系统的两个异常。

1 SVC

SVC用于生成系统函数调用,例如,用户程序不允许直接访问硬件,操作系统可以通过SVC提供对硬件的访问。因此,当用户程序想要使用某些硬件时,可以使用SVC指令,然后执行操作系统中的软件异常处理程序,并提供用户应用程序请求的服务。通过这种方式,对硬件的访问由操作系统控制,操作系统可以阻止用户应用程序直接访问硬件,从而提供更可靠的系统。

SVC还可以使软件更具可移植性,因为用户程序不需要知道硬件的编程细节。用户程序只需要知道应用程序编程接口(API)函数ID和参数,而实际的硬件级编程是由设备驱动程序处理的。
在这里插入图片描述
SVC异常由SVC指令产生,该指令需要一个立即数作为参数,根据这个参数执行不同的SVC处理函数。例:

SVC #0x3 ; 调用SVC函数3
SVC 0x3 ;   传统的语法(没有#)也可行

在C语言中,可以使用编译器关键字函数__svc或者使用内联汇编代码来执行SVC指令。

对于操作系统来说,当SVC处理程序被执行时,我们可以通过读取堆栈中的PC值来确定SVC指令中的立即数据值,然后从该地址读取指令并屏蔽不需要的位。如果使用的PSP堆栈,则还需要通过LR寄存器判断当前使用的是哪个堆栈。


SVC和软件中断指令(ARM7)
在ARM7中有一个软件中断指令SWI(Software interrupt instruction)。实际上,SVC指令的二进制编码与ARM7中的SWI是相同的。由于异常模型发生了变化,这条指令被重命名,以确保程序员能够正确地将软件代码从ARM7移植到Cortex-M3。


由于Cortex-M3中的中断优先级模型,我们不能在SVC处理程序中使用SVC指令(因为优先级与当前优先级相同),这样做将导致Usage fault。出于同样的原因,在NMI处理程序或Hard fault处理程序中使用SVC也是不允许的。

2 PendSV

PendSV与操作系统中的SVC协同工作。SVC不能挂起,它将立即被执行;而PendSV可以暂时挂起异常,对于操作系统来说这很有用,它可以等待一个重要的任务执行完毕后再处理该异常。

PendSV异常通过向NVIC Interrupt Control State Register中的PENDSVSET置1来产生。

PendSV的一个典型应用就是上下文切换。例如,一个系统可能有两个任务,上下文切换可以通过调用SVC函数或被Systick触发。
在这里插入图片描述
如果中断请求发生在Systick异常之前,Systick异常将抢占IRQ处理程序。在这种情况下,操作系统不应该进行上下文切换,否则IRQ处理程序进程将被延迟执行。对于Cortex-M3,如果操作系统在中断active时试图切换到线程模式,可能会产生Usage fault,如下图所示:
在这里插入图片描述
为了避免延迟处理IRQ处理的问题,一些操作系统在没有任何IRQ处理程序正在执行时才执行上下文切换。但这可能导致任务切换有很大的延迟,特别是当中断源的频率接近Systick异常的频率时。

PendSV异常通过延迟上下文切换请求直到IRQ处理程序完成来解决这个问题。为此,PendSV异常的优先级设置为最低,如果操作系统检测到一个IRQ当前处于活动状态(IRQ处理程序正在运行并且被Systick抢占),它通过挂起PendSV异常来延迟上下文切换。如下图所示:
在这里插入图片描述
(1)任务A调用SVC进行任务切换(如等待其它任务释放一个信号量)
(2)操作系统接收请求,准备上下文切换,并挂起PendSV异常。
(3)当CPU退出SVC时,它立即进入PendSV并进行上下文切换。
(4)当PendSV完成并返回到线程级别时,它执行任务B。
(5)IRQ产生并进入中断处理程序
(6)当运行中断处理程序时,发生Systick异常
(7)操作系统执行基本操作,然后挂起PendSV异常,为上下文切换做好准备
(8)当SYSTICK异常退出时,它返回到中断服务例程。
(9)当中断服务例程完成时,PendSV启动并执行实际的上下文切换操作。
(10)当PendSV完成时,程序返回到线程级别,继续执行任务A

------2023.12.13
SVC和PendSV的区别
SVC指令要求SVC异常的优先级高于当前优先级级别,并且该异常未被类似于PRIMASK的屏蔽寄存器屏蔽。否则,将触发错误异常。因此,在NMl处理程序或HardFault处理程序中,我们不能使用SVC,因为这些处理程序的优先级始终高于SVC异常。

总得来说就是SVC由用户调用SVC #<immed>时立即触发,而PendSV则是置相应的异常标志位,等待比PendSV优先级高的异常执行完后,再执行PendSV。

在FreeRTOS中,使用SVC异常来开启第一个任务的调度。然后将PendSV异常优先级设置为最低,保证中断的实时性,后续的上下文切换全由PendSV来实现。

<think>好的,用户想了解FreeRTOS中的PendSV机制,特别是它的作用用法。首先,我需要回忆一下FreeRTOS的任务切换机制。根据之前的引用资料,知道PendSV在任务切换中扮演重要角色,尤其是在中断服务函数中完成切换。 接下来,我应该确定PendSV的基本概念。根据引用[5],PendSV是可挂起的异常,SVC一起使用。它能够延迟执行,这对操作系统来说很重要,因为可以在处理完高优先级中断后再进行任务切换,避免在中断上下文中立即切换导致的问题。 然后,PendSV在FreeRTOS中的具体应用。引用[2]提到任务切换最终在PendSV中断服务函数中完成,这说明PendSV是任务切换的实际执行点。需要解释为什么选择PendSV而不是其他异常或中断,这可能涉及到优先级设置,引用[1]提到PendSVSysTick优先级都设置为最低,这样确保高优先级中断处理完毕后再切换任务。 还要说明PendSV如何被触发。通常,在SysTick中断或其他需要任务切换的地方,会挂起PendSV,使其延迟执行。具体步骤可能包括保存当前任务上下文、切换任务控制块、恢复新任务上下文等,这部分需要结合引用[4][5]中的信息。 此外,需要强调PendSV的优势,比如减少中断延迟,提高系统响应能力。可能还需要提到配置方法,如设置优先级,这在移植FreeRTOS时需要注意,引用[3]提到移植相关文件,可能涉及配置中断优先级的部分。 最后,生成相关问题时要覆盖机制细节、优先级设置原因、触发场景、与其他方法的对比以及移植中的注意事项。确保回答结构清晰,分点阐述,并正确引用资料中的内容。</think>### FreeRTOS中PendSV作用及用法详解 #### 1. **PendSV的基本概念** PendSV(可挂起的系统调用)是ARM Cortex-M内核的一个异常类型,主要用于在操作系统(如FreeRTOS)中实现**任务切换**。其核心特点是**可延迟执行**,即可以通过设置挂起位的方式,等待更高优先级的中断处理完成后再触发[^5]。这种特性使其非常适合作为任务切换的触发机制。 #### 2. **PendSV在任务切换中的作用** - **延迟任务切换**:在实时操作系统中,若直接在高优先级中断(如SysTick)中执行任务切换,可能导致中断嵌套或上下文保存不完整。通过PendSV,任务切换被推迟到所有高优先级中断处理完成后执行,保证系统稳定性[^1][^5]。 - **上下文保存与恢复**:PendSV中断服务函数(如`xPortPendSVHandler`)负责保存当前任务的寄存器状态(压栈),并加载新任务的上下文(出栈),从而实现任务切换[^2][^4]。 #### 3. **PendSV的使用方法** 1. **优先级设置**: 在FreeRTOS中,PendSVSysTick的优先级通常被设置为**最低优先级**,以确保高优先级中断不会被任务切换阻塞[^1]。 ```c // 示例:设置PendSV优先级为最低 NVIC_SetPriority(PendSV_IRQn, 0xFF); ``` 2. **触发PendSV**: 当需要任务切换时(如SysTick中断触发调度器),通过向PendSV挂起寄存器写入1来延迟触发: ```c // 挂起PendSV portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; ``` 3. **中断服务函数**: PendSV的中断服务函数包含任务切换的核心逻辑,例如保存当前任务栈指针、选择新任务、恢复新任务上下文等[^4]。 #### 4. **PendSV的优势** - **减少中断延迟**:通过延迟任务切换,避免在高优先级中断中执行耗时操作。 - **提高系统响应能力**:任务切换仅在安全时机(无高优先级中断)执行,保证关键中断的实时性[^5]。 #### 5. **典型应用场景** - **SysTick触发调度**:SysTick中断中请求PendSV,实现基于时间片的任务切换。 - **主动任务切换**:调用`taskYIELD()`时触发PendSV,手动切换任务[^5]。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tilblackout

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值