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学习(四)任务调度与切换 的相关文章

  • 心跳跟随的心形灯(STM32(HAL)+WS2812+MAX30102)

    文章目录 前言 介绍 系统框架 原项目地址 本项目开发开源地址 硬件PCB 软件功能 详细内容 硬件外壳制作 WS2812级联及控制 MAX30102血氧传感器 0 96OLED FreeRTOS 效果视频 总结 前言 在好几年前 我好像就
  • FreeRTOS系列

    1 多任务系统 1 1 前后台系统 单片机裸机开发时 一般都是在main函数里面用while 1 做一个大循环来完成所有的处理 循环中调用相应的函数完成所需的处理 有时也需要在中断中完成一些处理 相对于多任务系统而言 这就是单人单任务系统也
  • FreeRTOS内核配置说明---FreeRTOS Kernel V10.2.1

    FreeRTOS内核是高度可定制的 使用配置文件FreeRTOSConfig h进行定制 每个FreeRTOS应用都必须包含这个头文件 用户根据实际应用来裁剪定制FreeRTOS内核 这个配置文件是针对用户程序的 而非内核 因此配置文件一般
  • 解决错误“ #error “include FreeRTOS.h“ must appear in source files before “include event_groups.““例子分享

    今天来给大家分享一下 关于之前自己在学习FreeRTOS过程中遇到的一个错误提示 话不多说 我们直接来看 错误分析 首先 我们看一下错误的提示 error 35 error directive include FreeRTOS h must
  • 一文教你学会keil软件仿真

    仿真在我们调试代码中是非常重要的 通过仿真 我们可以快速定位到错误代码 或者错误逻辑的地方 这里我就以上一篇博客为例 教大家如何软件仿真 软件仿真不需要单片机 直接通过keil软件进行代码调试 一 打开工具 二 选择软件仿真 三 开始仿真
  • Freertos中vTaskDelay()是怎么用的

    1 常见的使用场景 void vLED Task void pvParameters while 1 Heartbeat LED vTaskDelay 1000 portTICK RATE MS 说明 上面这段代码的意思是 led翻转后经过
  • freertos---软定时器

    一 软件定时器介绍 freeRTOS软件定时器的时基是基于系统时钟节拍实现的 可以创建很多个 在硬件定时器资源不充足的情况下非常有用 软件定时器一般用作周期性地执行函数 在创建软件定时器时指定软件定时器的回调函数 在回调函数中实现相应的功能
  • FreeRTOS学习笔记<中断>

    中断概念 Cortex M的NVIC最多支持240个IRQ 中断请求 1个不可屏蔽中断 NMI 1个Systick 滴答定时器 定时器中断和多个系统异常 Cortex M处理器有多个用于管中断和异常的可编程寄存器 这些寄存器大多数都在 NV
  • FreeRTOS打印任务对CPU的占有率

    1 配置RTOS 1 打开RTOS Config Parameter 找到Run Time And Task States gathering related definitions 使能GENERATE RUN TIME STATS US
  • 基于HAL库的FREERTOS----------一.任务

    FreeROTS 就是一个免费的 RTOS 类系统 这里要注意 RTOS 不是指某一个确定的系统 而是指一类系统 比如 UCOS FreeRTOS RTX RT Thread 等这些都是 RTOS 类操作系统 FreeRTOS 是 RTOS
  • freeRTOS使用uxTaskGetStackHighWaterMark函数查看任务堆栈空间的使用情况

    摘要 每个任务都有自己的堆栈 堆栈的总大小在创建任务的时候就确定了 此函数用于检查任务从创建好到现在的历史剩余最小值 这个值越小说明任务堆栈溢出的可能性就越大 FreeRTOS 把这个历史剩余最小值叫做 高水位线 此函数相对来说会多耗费一点
  • FreeRTOS临界段和开关中断

    http blog sina com cn s blog 98ee3a930102wg5u html 本章教程为大家讲解两个重要的概念 FreeRTOS的临界段和开关中断 本章教程配套的例子含Cortex M3内核的STM32F103和Co
  • FreeRTOS笔记(一)简介

    这个笔记主要依据韦东山freertos快速入门系列记录 感谢韦东山老师的总结 什么是实时操作系统 操作系统是一个控制程序 负责协调分配计算资源和内存资源给不同的应用程序使用 并防止系统出现故障 操作系统通过一个调度算法和内存管理算法尽可能把
  • 基于STM32的FreeRTOS学习之中断测试实验(五)

    记录一下 方便以后翻阅 本章内容是接着上一章节进行的实际演练 1 实验目的 FreeRTOS可以屏蔽优先级低于configMAX SYSCALL INTERRUPT PRIORITY的中断 不会屏蔽高于其的中断 本次实验就是验证这个说法 本
  • FreeRTOS学习笔记(8)---- 软件定时器

    使用FreeRTOS软件定时器需要在文件FreeRTOSConfig h先做如下配置 1 configUSE TIMERS 使能软件定时器 2 configTIMER TASK PRIORITY 定时器任务优先级 3 configTIMER
  • FreeRTOS死机原因

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

    1 FreeRTOS的系统配置文件为FreeRTOSConfig h 在此配置文件中可以完成FreeRTOS的裁剪和配置 在官方的demo中 每个工程都有一个该文件 2 先说一下 INCLUDE 开始的宏 使用 INCLUDE 开头的宏用来
  • FreeRTOSConfig.h 配置优化及深入

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

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

    我使用 GCC ARM Embedded 和 FreeRTOS FreeRTOS具有的功能vTaskSwitchContext 仅在某些情况下使用 内联汇编代码 问题是 当我使用LTO时 GCC不考虑内联汇编代码并认为该函数没有被使用 因此

随机推荐

  • 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