FreeRTOS学习(四)任务调度与切换

2023-05-16

文章目录

      • 1.任务调度
      • 2.任务切换
        • 2.1 SVC 和 PendSV
        • 2.2 上下文
        • 2.3 切换场景
        • 2.4 PendSV_Handler
      • 3.总结

1.任务调度

  在建立完任务后紧接着调用任务调度函数,便会使系统运行起来

void vTaskStartScheduler( void )  // 启动任务调度器

  概要来说,任务调度函数主要做了下面几件事:

  • 创建空闲任务,如果使用软件定时器,还会创建定时器
  • 设置中断优先级,包括 PendSVSysTick
  • 开启第一个任务,由 SVCHandler 实现

  任务调度器触发了 SVC 中断来启动第一个任务,之后的工作都靠 PendSVSysTick 中断触发来实现。接下来就来唠唠这三个中断,这三个中断都是在 FreeRTOSConfig.h 的配置文件中进行了宏定义。

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
   standard names. */
#define vPortSVCHandler    SVC_Handler
#define xPortPendSVHandler PendSV_Handler

/* IMPORTANT: FreeRTOS is using the SysTick as internal time base, thus make sure the system and peripherials are
              using a different time base (TIM based for example).
 */
#define xPortSysTickHandler SysTick_Handler

  如果这三个中断函数与移植平台有重定义冲突,前两个应该使用 FreeRTOS 定义的函数,SysTick_Handler使用STM32中断文件内定义的函数,但需要进行修改。至于原因,跟这三个中断的功能有关

  • SVC_Handler:开启第一个任务函数,只在任务调度中使用一次
  • PendSV_Handler:触发任务切换
  • SysTick_Handler:时间片调度,同一优先级有多个任务,其本质也是触发 PendSV 中断
void SysTick_Handler(void)
{
	HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
#if (INCLUDE_xTaskGetSchedulerState == 1 )
	if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
  	{
#endif /* INCLUDE_xTaskGetSchedulerState */
    xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
  	}
#endif /* INCLUDE_xTaskGetSchedulerState */
}

2.任务切换

2.1 SVC 和 PendSV

  在上一节中也提到了这两个中断的中断服务函数的功能,这里再详细介绍一下。
(1) SVC 中断
  SVC是系统服务调用,由 SVC 指令触发调用。在 FreeRTOS 中用来在任务调度中开启第一个任务。触发指令:

svc 0

(2) PendSV 中断
  与SVC相关的是PendSV中断,称为可悬起的系统调用。两者不同之处在于响应速度,SVC中断是要求被立刻得到响应的,而PendSV中断则可以延迟被响应,也就是PendSV中断可以先“悬起”,待其它重要中断被执行完成后再处理它。
在这里插入图片描述
  PendSV 中断的意义在于当需要发生任务切换时,如果当前正在执行一个中断,则等待中断执行完毕后,再进行任务切换。即不允许打断中断来切换任务
  悬起PendSV的方法是:手工往NVIC的PendSV悬起寄存器中写1,悬起后,如果优先级不够其它中断高,则将延迟等待执行

portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;  // 向中断控制和状态寄存器的bit28写入1挂起PendSV来启动PendSV中断

在这里插入图片描述

2.2 上下文

  任务切换的本质是任务上下文的切换,上文其实就是待切出任务(当前正在运行)的任务控制块TCBCPU相关寄存器状态,下文就是待切入(抢占)任务的任务控制块TCBCPU相关寄存器状态
  寄存器是宝贵资源,某个时刻只能储存某个任务的值,要使得当前任务的寄存器状态得到保留,需要把当前的寄存器压栈,恢复的时候再弹出到寄存器,这样一个寄存器就可以不断使用了。
在这里插入图片描述

2.3 切换场景

  发生任务切换的场合有2个,一个是优先级抢占,另一个是时间片轮转。在FreeRTOS中的表达为:

  1. 系统调用 ⇌ 优先级抢占
  2. SysTick中断 ⇌ 时间片轮转

  其中优先级抢占不一定是高优先级抢占,可能的情况还有任务调用系统API主动放弃CPU,让其它任务先行等等。如执行一个系统调用:taskYIELD()
  而时间片轮转发生在相同优先级的任务中,SysTick中断是FreeRTOS的周期性中断,每隔一段时间就会发生中断,调度器需要在里面执行一些自身的程序。

  无论是哪个场合,最终都需要PendSV中断的处理,比如系统调用taskYIELD(),跟踪源码可以发现设置如下

taskYIELD()
	portYIELD()
		portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; 

  而跟踪SysTick中断服务函数最终也会发现有一样的设置。表明时间片调度实现任务切换也是通过 PendSV 标志位置位触发 PendSV 中断实现,但有个前提条件,就是同一优先级有多个任务。

SysTick_Handler()
	xPortSysTickHandler();
		portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; 

  最终都是portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT,意思是手工往NVIC的PendSV悬起寄存器中写1

  扩展一点,在任务切换选择下一个要运行的任务时,有两种方法,通过宏configUSE_PORT_OPTIMISED_TASK_SELECTION 控制,1 表示硬件方法,否则使用通用方法。

  1. 通用方法:从就绪列表中选取,适用于任何处理器,但效率低
  2. 硬件方法:每个 bit 代表一个优先级,获取前导零个数判断最高优先级

2.4 PendSV_Handler

  因为任务切换最终都会发生PendSV中断,在PendSV中断服务函数中进行,中断服务函数为PendSV_Handler,但是在FreeRTOSConfig.h中被改名为xPortPendSVHandler,内容使用汇编编写的,它主要的工作如下
在这里插入图片描述
  比较关心的是改变pxCurrentTCB(回顾上一文),用到了一个函数vTaskSwitchContext(),调用层次下

vTaskSwitchContext()
	taskSELECT_HIGHEST_PRIORITY_TASK()
		portGET_HIGHEST_PRIORITY()		//得到高优先级任务
		listGET_OWNER_OF_NEXT_ENTRY()	//设置pxCurrentTCB

  到此,在PendSV_Handler中断服务函数中,就完成了任务的切换。

3.总结

  • SVC中断就是软中断,给用户提供一个访问硬件的接口
  • PendSV中断相对SVC来说,是可以被延迟执行的,用于任务切换
  • 任务切换可以发生在系统调用中,也可以发生在时间片轮转中
  • 无论哪个情况,任务切换最终都会进入PendSV中断服务函数
  • 任务切换的过程为:保存现场、跳转到下一个任务、恢复现场
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS学习(四)任务调度与切换 的相关文章

  • FreeRTOS系列

    1 多任务系统 1 1 前后台系统 单片机裸机开发时 一般都是在main函数里面用while 1 做一个大循环来完成所有的处理 循环中调用相应的函数完成所需的处理 有时也需要在中断中完成一些处理 相对于多任务系统而言 这就是单人单任务系统也
  • FreeRTOS记录(七、FreeRTOS信号量、事件标志组、邮箱和消息队列、任务通知的关系)

    我们在前面单独介绍过FreeRTOS的任务通知和消息队列 但是在FreeRTOS中任务间的通讯还有信号量 邮箱 事件组标志等可以使用 这篇文章就这些成员与消息队列和任务通知的关系进行说明分析 增加邮箱部分 任务通知发送消息 Demo 202
  • FreeRTOS软件定时器创建、复位、开始和停止(备忘)

    目录 一 简介 1 1 开发环境 1 2 摘要 二 STM32CubeIDE配置 三 创建定时器 3 1 头文件声明 3 2 工程文件定义 3 3 创建定时器 3 4 开启 复位 和关闭定时器 四 定时器回调函数 一 简介 1 1 开发环境
  • 【FreeRTOS】队列的使用

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • 基于HAL库的FREERTOS----------一.任务

    FreeROTS 就是一个免费的 RTOS 类系统 这里要注意 RTOS 不是指某一个确定的系统 而是指一类系统 比如 UCOS FreeRTOS RTX RT Thread 等这些都是 RTOS 类操作系统 FreeRTOS 是 RTOS
  • 【FreeRTOS】任务通知的使用

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • FreeRTOS学习(三)开关中断

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 背景知识 Cotex M3的NVIC最多支持240个IRQ 中断请求 1个不可屏蔽 NMI 1个Systick 滴答定时器 Cortex M处理
  • FreeRTOS之事件

    FreeRTOS之事件 声明 本人按照正点原子的FreeRTOS例程进行学习的 欢迎各位大佬指责和批评 谢谢 一 事件定义 事件 事件集 与高数上的集合意义差不多 事件啊 其实是实现任务间通信的机制 主要用于实现多任务间的同步 但是事件类型
  • FreeRTOS笔记(一)简介

    这个笔记主要依据韦东山freertos快速入门系列记录 感谢韦东山老师的总结 什么是实时操作系统 操作系统是一个控制程序 负责协调分配计算资源和内存资源给不同的应用程序使用 并防止系统出现故障 操作系统通过一个调度算法和内存管理算法尽可能把
  • 啊哈C的简单使用

    打开啊哈C 新建一个程序输出hello world include
  • 基于STM32的FreeRTOS学习之中断测试实验(五)

    记录一下 方便以后翻阅 本章内容是接着上一章节进行的实际演练 1 实验目的 FreeRTOS可以屏蔽优先级低于configMAX SYSCALL INTERRUPT PRIORITY的中断 不会屏蔽高于其的中断 本次实验就是验证这个说法 本
  • Arduino IDE将FreeRTOS用于STM32

    介绍 适用于STM32F103C8的FreeRTOS STM32F103C是一种能够使用FreeRTOS的ARM Cortex M3处理器 我们直接在Arduino IDE中开始使用STM32F103C8的FreeRTOS 我们也可以使用K
  • FreeRTOS死机原因

    1 中断回调函数中没有使用中断级API xxFromISR 函数 xSemaphoreGiveFromISR uart busy HighterTask 正确 xSemaphoreGive uart busy 错误 2 比configMAX
  • FreeRTOS之系统配置

    1 FreeRTOS的系统配置文件为FreeRTOSConfig h 在此配置文件中可以完成FreeRTOS的裁剪和配置 在官方的demo中 每个工程都有一个该文件 2 先说一下 INCLUDE 开始的宏 使用 INCLUDE 开头的宏用来
  • FreeRTOS多任务调度器基础

    Cortex M4中SysTick调度器核心 Cortex M4中的中断管理 Cortex M4中影子栈指针 Cortex M4中SVC和PendSV异常 1 Cortex M4中SysTick调度器核心 systick每一次中断都会触发内
  • FreeRTOSConfig.h 配置优化及深入

    本篇目标 基于上一篇的移植freertos stm32f4 freertos 上 修改 FreeRTOSConfig h 文件的相关配置来优化辅助 FreeRtos 的使用 并且建立一些基本功能 信号量 消息地列等 的简单应用位于 stm3
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥
  • 如何将 void* 转换为函数指针?

    我在 FreeRTOS 中使用 xTaskCreate 其第四个参数 void const 是传递给新线程调用的函数的参数 void connect to foo void const task params void on connect
  • FreeRTOS 匈牙利表示法 [重复]

    这个问题在这里已经有答案了 我是 RTOS 和 C 编程的新手 而且我仍在习惯 C 的良好实践 因此 我打开了一个使用 FreeRTOS 的项目 我注意到操作系统文件使用匈牙利表示法 我知道一点符号 但面临一些新的 标准 FreeRTOS

随机推荐

  • Http Digest认证协议

    http blog csdn net htjoy1202 article details 7067287 其认证的基本框架为挑战认证的结构 xff0c 如下图所示 xff1a xfeff xfeff 1 客户端希望取到服务器上的某个资源 x
  • 【系统分析师之路】嵌入式系统章节错题集锦

    系统分析师之路 嵌入式系统章节错题集锦 系分章节错题集第01题 xff1a 红色 01 雷达设计人员在设计数字信号处理单元时 xff0c 其处理器普遍采用DSP芯片 xff08 比如 xff1a TI公司的TMS320C63xx xff09
  • 【软工】程序编码

    目录 前言正文 程序设计语言 分类 选择原则 程序编码总原则 好程序的标准 结构化程序设计 主要内容 主要原则 程序设计风格 源程序文档化 数据说明 语句结构 输入输出方法 程序设计质量评价 正确性结构清晰性易修改性 易读性 简单性 程序复
  • TPM1.2到TPM 2.0的变化

    原文地址 xff1a http www vonwei com mod 61 pad amp act 61 view amp id 61 11 TPM 1 2规范主要面向PC平台 xff0c 其103版本在2009年被接受为ISO标准 xff
  • 关于Cmake与CmakeLists(一)--背景,须知,示例

    一 背景及须知 1 背景 xff1a VS2019与VS2010在编写程序时都是创建了一个工程 xff0c 然后直接打开 sln即可 但是vscode仅仅是一个编辑器 xff0c 打开之后只有 c或者 cpp文件 xff0c 故需要手动编译
  • webgl(three.js)实现室内定位,楼宇bim、实时定位三维可视化解决方案——第五课

    webgl three js 实现室内定位 楼宇bim 实时定位三维可视化解决方案 第五课 参考文章 xff1a xff08 1 xff09 webgl three js 实现室内定位 楼宇bim 实时定位三维可视化解决方案 第五课 xff
  • Linux虚拟机在线扩容lvm类型root分区

    目录 Linux虚拟机在线扩容lvm类型root分区写在前面正文写在后面 Linux虚拟机在线扩容lvm类型root分区 写在前面 这是我在CSDN上的第一篇文章 作为一个半江湖的IT人 xff0c 这些年来也在CSDN受益很多 今天是20
  • 无vCenter创建vSAN集群

    无vCenter创建vSAN集群 最近仍有朋友在问题 xff0c vCenter如果 挂了 xff0c vSAN还能正常运行吗 xff1f 这个小文通过手动创建vSAN集群的方式来解答下这个问题吧 xff08 生产环境慎用 xff01 xf
  • 记一次mdadm软raid1升级容量

    MDRaid 2块4TB做了软RAID1 xff0c 需要升级成2块8TB盘 查看磁盘信息 xff0c SerialNumber等会儿会用到 xff0c 防止换错盘 span class token function sudo span h
  • [简洁版]youtube-dl下载命令

    简介 YouTube dl是python上的pip模块 xff08 开源 xff09 xff0c 可以用来下载YouTube Bilibili等多个平台的视频 音频文件 xff0c 可谓是居家旅行必备小工具 本文主要介绍一些常用的youtu
  • [简版]VMware强大的管理工具-PowerCLI

    一 PowerCLI介绍 什么是 PowerCLI PowerCLI 是一个命令行工具 xff0c 可以用于自动化vSphere管理 xff0c 包括网络 存储 虚拟机以及其他很多功能 PowerCLI包含超过700个命令 要安装Power
  • [简版]使用PowerCLI自定义vSphere ISO安装镜像

    一 什么情况下要自定义ISO镜像 一般来说 xff0c 对于DELL Lenovo HPE这类主流的服务器厂商 xff0c VMware官方vSphere ISO镜像或者官网的第三方客制镜像 xff08 由服务器厂商提供的封装镜像 xff0
  • [简版] 关于vSphere漏洞-OpenSLP

    一 前言 近期vSphere OpenSLP漏洞在野利用的新闻频频被爆出来 xff0c 大伙儿非常关注 由于vSphere虚拟化客户之广泛 xff0c 很多朋友都表达了自己的焦虑 xff0c 同时也会担心自己管理的vSphere虚拟化平台是
  • [简版] Linux搭建SAMBA文件共享服务

    SMB服务搭建 更多参数含义参考链接 常用配置 安装samba span class token comment Ubuntu span span class token function sudo span span class toke
  • STM32 HAL库详解

    STM32 HAL库整体总结 STM32 之二 HAL库详解 及 手动移植 本篇博客是对以上参考资源的一个二次总结与整理 1 HAL库文件结构 对于开发人员而言 xff0c 首先要清楚 HAL 库的文件结构 根据文件类型可认为以下两大类 x
  • STM32 HAL库学习(四):DMA之串口空闲中断

    STM32CubeMX 配置实现参考这里 1 串口空闲中断 1 1 UART DMA方式接收数据 STM32串口使用DMA方式接收数据可以减小CPU的开销 对于接收定长数据 xff0c 可以将DMA接收缓冲区的长度设定为待接收数据的长度 x
  • Android Studio 启动模拟器出现“Timed out after 300seconds waiting for emulator to come online“解决方案

    Android Studio 启动模拟器出现 34 Timed out after 300seconds waiting for emulator to come online 34 解决方案 参考文章 xff1a xff08 1 xff0
  • 结构体中的位定义

    1 结构体位定义 在工作中 xff0c 经常遇到按位 xff08 bit xff09 定义结构体 的情况 由于一个字节有8个位 xff0c 这时 xff0c 程序员往往对bit的位置产生困惑 现在给出2个例子 xff0c 来说明位的定义次序
  • 蓝牙基础(三):蓝牙协议栈总体认知

    蓝牙基础 xff08 三 xff09 xff1a 蓝牙协议栈总体认知 0 前言 初入门经典蓝牙学习 xff0c 网上资料参差不齐 xff0c 本博客旨在整理自己的一些总结内容 xff0c 建立整体功能认识 xff0c 以便后续深入学习 1
  • FreeRTOS学习(四)任务调度与切换

    文章目录 1 任务调度2 任务切换2 1 SVC 和 PendSV2 2 上下文2 3 切换场景2 4 PendSV Handler 3 总结 1 任务调度 在建立完任务后紧接着调用任务调度函数 xff0c 便会使系统运行起来 span c