IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> FreeRTOS系列文章(2):PendSV功能,为什么需要PendSV -> 正文阅读

[嵌入式]FreeRTOS系列文章(2):PendSV功能,为什么需要PendSV

背景

大多数嵌入式RTOS在Cortex-M3/M4上的移植都需要PendSV,比如uCOS、RT-Thread、FreeRTOS等,本文就对PendSV的功能作用,以及为什么需要PendSV进行详细的分析。

PendSV是什么?

我们先引用《Cortex-M3权威指南》对PendSV的介绍:

PendSV(可悬起的系统调用),它是一种CPU系统级别的异常,它可以像普通外设中断一样被悬起,而不会像SVC服务那样,因为没有及时响应处理,而触发Fault。

个人理解PendSV的英文全称应该是:Pend System Service Call,简称PendSV.
所以PendSV的最大特点就是,它是系统级别的异常,但它又天生支持【缓期执行】。

PendSV使用场景

由于PendSV的特点就是支持【缓期执行】,所以嵌入式OS可以利用它这个特点,进行任务调度过程的上下文切换。而为什么要使用【缓期执行】的特点来进行上下文切换呢?简单的说就是任何嵌入式RTOS,都需要尽量不打断外设中断。
我们来举例说明,假如一个系统中有2个就绪的任务,上下文切换被切换的场合有:

  1. 执行了一个系统调用SVC。
  2. 系统滴答定时器SYSTICK中断,触发了任务的调度。

没有外部中断,OS直接切换任务

假如我们在Systick中断服务程序中,启动上下文切换,流程图如下:
在这里插入图片描述

上图中,似乎一切都正常,任务调度很流畅,但现实总是很骨感的,不可能这么简单,假如在产生异常时,CPU正在响应另一个中断ISR1,而SysTick的优先级又大于ISR1,在这种情况下,SysTick就会抢占ISR1,获取CPU使用权,但是在SysTick中不能进行上下文切换,因为这将导致中断ISR1被延迟,这在实时要求的系统中是不能容忍的,但是这个说辞只是为了方便理解,更重要的是:

在Cortex-M3中,如果OS在某个中断活跃时,抢占了该中断,而且又发生了任务调度,并执行了任务,切换到了线程运行模式,将直接触发Fault异常。

SysTick优先级高于外部中断,OS抢占IRQ进行任务调度触发Fault

如下图所示:
在这里插入图片描述
为了解决这个问题,早起的OS大多会检测当前是否有中断在活跃中,只有在无任何中断需要响应时,才进行上下文切换,切换期间无法响应中断。
这个时候,可能会有人想,既然有上面的原因限制,我能不能将SysTick的优先级设置为最低,然后在SysTick中进行上下文切换,然后任务调度呢? 答案是:可以。这一点在Cortex-M3权威指南中没有解释,反而影响了很多读者对于PendSV的理解。按照上面的思路,我们分析一下整体流程:

Systick中断优先级低与IRQ,任务调度流程 在这里插入图片描述

在上图中我们可以看到,当OS的Systick中断级别低于外部中断时,确实不会触发Fault,但是这带来了一个问题:

一般OS在调度任务时,会关闭中断,也就是进入临界区,而OS任务调度是要耗时的,这就会出现一种情况:
在任务调度期间,如果新的外部IRQ发生,CPU将不能够快速响应处理。

将SysTick的优先级调低,避免了触发Fault的问题,但是会影响外部中断IRQ的处理速度,那有没有进一步优化的方法呢?答案就是PenSV。因为PendSV有【缓期执行】的特点,所以可以将上图中的OS拆分,分成2段:

  1. 滴答定时器中断,制作业务调度前的判断工作,不做任务切换。
  2. 触发PendSV,PendSV并不会立即执行,因为PendSV的优先级最低,如果此时正好有IRQ请求,那么先响应IRQ,最后等到所有优先级高于PendSV的IRQ都执行完毕,再执行PendSV,进行任务调度。

Systick、PendSV优先级低,只在PendSV中进行上线文切换,任务调度

在这里插入图片描述
上述的流程就是目前常见的嵌入式RTOS的任务调度流程,uC/OS和FreeRTOS都会将Systick和PendSV的优先级设置为最低。
到这里,可能会有人又有疑问,这样做是不是也有缺点:

  1. SysTick的优先级最低,那如果外部IRQ比较频繁,是不是会导致SysTick经常被挂起,然后滞后,导致Systick的节拍延长,进而导致不准啊?
  2. 因为1的原因,导致任务的执行调度就不够快了?

答案:确实存在这些问题,但是这些问题影响面已经很小了。我们能不能将SysTick的优先级设置成最高,将PendSV的优先级设置为低,就能完美的解决上述问题,我们不妨分析下这种情况:
在这里插入图片描述
这样似乎解决了问题,但是又带来了一个问题,因为SysTick的优先级最高,而且又是周期性的触发,会导致经常抢占外部IRQ,这就会导致外部IRQ响应变慢,这在一些对实时性要求高的,比如按键、断电中断等待,是不能接受的,你肯定不希望你的按键扫描体验卡顿。
所以,没有十全十美的解决方案,关键是要看我们更关注什么?对于CPU来说,嵌入式OS也是一个程序,跟普通的裸机程序是一样的,无非就是复杂一些,涉及到了手动切换堆栈、PC等高级操作而已,OS的优先级天生就没有外部中断的优先级高。

小结

  1. PendSV是可悬起系统中断,具有【缓期执行】特征。
  2. PendSV一般被嵌入式OS用于 任务调度的上下文切换。
  3. 使用PendSV时,一般会将PendSV的优先级设置为最低,让外部IRQ先执行,等到没有外部中断后,在执行上下文切换。
  4. 嵌入式实时操作系统的【实时】概念,并不仅仅指应用程序、任务的调度实时,而是指整个系统的实时性高,具备【可剥夺】特点,当有高优先级的中断、任务具备执行条件时,立刻中断当前正在运行的任务,去执行高优先级的IRQ和高优先级任务。
  5. 嵌入式OS一般会将SysTick的优先级也设置为最低,保证外部中断IRQ优先,详细的分析,我们下一篇文章讨论。
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-05-24 18:23:18  更:2022-05-24 18:24:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 7:46:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计