FreeRTOS学习笔记【10】-----任务上下文切换

news2025/4/26 10:36:23

1 概念性内容

开机到调度需要经历的步骤有:

  • 系统初始化
  • 任务创建
  • 启动调度器
  • 上下文切换
  • 时间分片
  • 任务执行

1.1 任务本质

FreeRTOS 的 任务(Task)本质上就是一个运行在任务自己的栈区中无限循环的函数 + 一段上下文(context)数据
一个任务有四种状态:就绪态、挂起态、运行态、阻塞态

  • 就绪态:任务已准备好运行,处于就绪列表中,按优先级排序
  • 运行态:当前cpu正在执行该任务。
  • 阻塞态:因某些原因不能继续执行,被放入阻塞列表(延时会放入延时列表),阻塞消除会重新回到就绪列表。
  • 挂起态:手动调用api挂起,必须再调用resume才能恢复执行。
  • 终止态:不在调度器控制内。

1.2 什么是上下文

上下文其实就是线程的状态

线程状态包括:

类别保存内容
CPU寄存器R0~R12, LR, PC, xPSR
高级寄存器R4~R11(手动保存)
栈指针PSP(Process Stack Pointer)
状态寄存器xPSR
任务控制块保存任务的栈顶指针(SP)和其他调度信息

对寄存器不熟悉的同学可以参考:
ARM架构 中的寄存器内容

不同信息的保存实现:

类型内容描述
自动保存寄存器R0 ~ R3,
R12,
LR,
PC,
xPSR
由硬件在异常(中断)进入时自动压栈
手动保存寄存器R4~R11由 FreeRTOS 的上下文切换汇编代码手动压栈
特殊寄存器SP、
LR、
PSP/MSP
栈指针、返回地址,决定任务能否正确返回

FreeRTOS 会将这些上下文信息 保存在任务的栈中,并把 栈顶指针(即当前任务运行到哪)记录在任务的 TCB 中。

当再次切回这个任务时,就从它保存的栈中把这些寄存器恢复回来,任务就能从中断前的状态“无感恢复”。

2 代码

2.1 关键代码

(1)SVC_Handler
用途: SVC 异常通常用于实现系统调用,允许用户在特权级别(Supervisor)执行一些特殊的操作,例如请求操作系统服务。在启动调度时候会执行。
一般的,SVC_Handler主要用于启动第一个任务以及初始化系统的运行环境。在 FreeRTOS 启动过程中,prvStartFirstTask() 函数会被调用,该函数最终通过 SVC 请求来跳转至初始任务的执行路径。

__asm void vPortSVCHandler( void )
{
    PRESERVE8               // 保留R4-R11和LR寄存器,确保不会被改
    /* Get the location of the current TCB. */
    ldr    r3, =pxCurrentTCB   // pxCurrentTCB地址加载到寄存器r3。pxCurrentTCB:指向当前任务控制块的指针。
    ldr r1, [r3]            // pxCurrentTCB 的值加载到r1
    ldr r0, [r1]            // r1 指向的地址(TCB中的栈顶地址)加载到r0
    /* Pop the core registers. */
    ldmia r0!, {r4-r11, r14}// 加载多个寄存器,保存当前任务上下文
    msr psp, r0             // 更新程序堆栈指针(PSP)的值为r0,加载下一个任务的上下文

    isb             // 指令同步屏障,确保更新PSP
    mov r0, #0      // 将0移至寄存器r0,用于接下来重置基本优先级寄存器。
    msr    basepri, r0 // 中断优先级控制寄存器设置为零,允许所有中断。
    bx r14          // 使用r14(LR)的值返回到SVC调用之前的地址
}

(2)PendSVHandler

  • 为什么采用了pendSVHandler函数切换任务而不是在systick定时中断切换任务:
    如果优先级低,那么切换任务时会被别的高优先级任务打断,容易出问题。
    如果优先级高,那么高优先级任务执行切换任务的函数,耗时较长,实时性差。
  • 解决的办法:
    仅使用systick异常通知需要切换任务,
    使用优先级最低的PendSV_Handler中断函数来真正切换任务
__asm void xPortPendSVHandler( void )
{
    extern uxCriticalNesting;
    extern pxCurrentTCB;
    extern vTaskSwitchContext;

/* *INDENT-OFF* */
    PRESERVE8

    mrs r0, psp
    isb

    ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */
    ldr r2, [ r3 ]

    stmdb r0 !, { r4 - r11 } /* Save the remaining registers. */
    str r0, [ r2 ] /* Save the new top of stack into the first member of the TCB. */

    stmdb sp !, { r3, r14 }
    mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY
    msr basepri, r0
    dsb
    isb
    bl vTaskSwitchContext
    mov r0, #0
    msr basepri, r0
    ldmia sp !, { r3, r14 }

    ldr r1, [ r3 ]
    ldr r0, [ r1 ] /* The first item in pxCurrentTCB is the task top of stack. */
    ldmia r0 !, { r4 - r11 } /* Pop the registers and the critical nesting count. */
    msr psp, r0
    isb
    bx r14
    nop
/* *INDENT-ON* */
}

其中vTaskSwitchContext的函数实现如下

void vTaskSwitchContext( void )
{
    //如果调度器挂起那就不能进行任务切换
    if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE )
    {
        xYieldPending = pdTRUE;
    }
    else
    {
        xYieldPending = pdFALSE;
        traceTASK_SWITCHED_OUT();
        taskCHECK_FOR_STACK_OVERFLOW();     /* Check for stack overflow, if configured. */
        taskSELECT_HIGHEST_PRIORITY_TASK(); 
        /* 获取最高优先级的任务
        实现是一个宏,首先执行从任务列表中获取最高优先级任务,
        然后在最高优先级的任务就绪列表中获取下一个任务的控制块TCP。 */
        traceTASK_SWITCHED_IN();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2343184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Appium自动化开发环境搭建

自动化 文章目录 自动化前言 前言 Appium是一款开源工具,用于自动化iOS、Android和Windows桌面平台上的本地、移动web和混合应用程序。原生应用是指那些使用iOS、Android或Windows sdk编写的应用。移动网页应用是通过移动浏览器访问的网页应用(appum支持iOS和Chrom…

C++学习-入门到精通-【1】C++编程入门,输入/输出和运算符

C学习-入门到精通-【1】C编程入门,输入/输出和运算符 C编程入门,输入/输出和运算符 C学习-入门到精通-【1】C编程入门,输入/输出和运算符第一个C程序:输出一行文本算术运算 第一个C程序:输出一行文本 // 文本打印程序…

面向高性能运动控制的MCU:架构创新、算法优化与应用分析

摘要:现代工业自动化、汽车电子以及商业航天等领域对运动控制MCU的性能要求不断提升。本文以国科安芯的MCU芯片AS32A601为例,从架构创新、算法优化到实际应用案例,全方位展示其在高性能运动控制领域的优势与潜力。该MCU以32位RISC-V指令集为基…

某地农产品交易中心钢网架自动化监测项目

1. 项目简介 本项目规划建设现代物流产业园,新建6万平方米仓库,具体为新建3栋钢构仓库2万平方米,2栋砖混结构仓库1万平方米,3栋交易中心2万平方米,改造现有3栋3层砖混结构仓库1万平方米,配备智能化仓库物流…

【无人机】无人机位置估计出现偏差的原因分析

目录 #0、原因分析 #1、过度振动的测定 #2、确定过度陀螺仪偏差 #3、偏航精度差的测定 #4、确定 GPS 精度差 #5、确定 GPS 数据丢失 #6、气压计地面效应补偿 #0、原因分析 位置背离的最常见原因是: 参考:Using the ECL EKF | PX4 Guide (v1.15)…

element-plus(vue3)表单el-select下拉框的远程分页下拉触底关键字搜索实现

一、基础内核-自定义指令 1.背景 2.定义 3.使用 4.注意 当编辑时需要回显,此时由于分页导致可能匹配不到对应label文本显示,此时可以这样解决 二、升级使用-二次封装组件 三、核心代码 1.自定义指令 定义 ----------------selectLoadMoreDirective.…

轻松完成视频创作,在线视频编辑器,无需下载软件,功能多样实用!

小白工具的在线视频编辑https://www.xiaobaitool.net/videos/edit/ 功能丰富、操作简便,在线裁剪或编辑视频工具,轻松完成视频创作能满足多种视频编辑需求。 格式支持广泛:可编辑超百种视频格式,基本涵盖常见和小众视频格式&#…

豆瓣图书数据采集与可视化分析(三)- 豆瓣图书数据统计分析

文章目录 前言一、数据读取与保存1. 读取清洗后数据2. 保存数据到CSV文件3. 保存数据到MySQL数据库 二、不同分类统计分析1. 不同分类的图书数量统计分析2. 不同分类的平均评分统计分析3. 不同分类的平均评价人数统计分析4. 不同分类的平均价格统计分析5. 分类综合分析 三、不同…

c++进阶——类与继承

文章目录 继承继承的基本概念继承的基本定义继承方式继承的一些注意事项 继承类模板 基类和派生类之间的转换继承中的作用域派生类的默认成员函数默认构造函数拷贝构造赋值重载析构函数默认成员函数总结 不能被继承的类继承和友元继承与静态成员多继承及其菱形继承问题继承模型…

复杂地形越野机器人导航新突破!VERTIFORMER:数据高效多任务Transformer助力越野机器人移动导航

作者: Mohammad Nazeri 1 ^{1} 1, Anuj Pokhrel 1 ^{1} 1, Alexandyr Card 1 ^{1} 1, Aniket Datar 1 ^{1} 1, Garrett Warnell 2 , 3 ^{2,3} 2,3, Xuesu Xiao 1 ^{1} 1单位: 1 ^{1} 1乔治梅森大学计算机科学系, 2 ^{2} 2美国陆军研究实验室&…

Jsp技术入门指南【十】IDEA 开发环境下实现 MySQL 数据在 JSP 页面的可视化展示,实现前后端交互

Jsp技术入门指南【十】IDEA 开发环境下实现 MySQL 数据在 JSP 页面的可视化展示,实现前后端交互 前言一、JDBC 核心接口和类:数据库连接的“工具箱”1. 常用的 2 个“关键类”2. 必须掌握的 5 个“核心接口” 二、创建 JDBC 程序的步骤1. 第一步&#xf…

数据库未正常关闭后,再次启动时只有主进程,数据库日志无输出

瀚高数据库 目录 环境 症状 问题原因 解决方案 环境 系统平台:银河麒麟svs(X86_64) 版本:4.5.8 症状 现象:使用pg_ctl stop停止数据库,未正常关闭;使用pg_ctl stop -m i 强制关闭数据库后&…

Oracle Recovery Tools修复ORA-00742、ORA-600 ktbair2: illegal inheritance故障

接到客户反馈,一套运行在虚拟化平台中的Oracle数据库,由于机房断电,导致数据库无法启动,最初启动报错 2025-04-22T16:59:48.92222708:00 Completed: alter database mount exclusive alter database open 2025-04-22T16:59:52.60972608:00 Ping without log force is disabled:…

基于 Netmiko 的网络设备自动化操作

学习目标 掌握 Netmiko 库的核心功能与使用场景。能够通过 Netmiko 连接多厂商设备并执行命令和配置。实现批量设备管理、配置备份与自动化巡检。掌握异常处理、日志记录与性能优化技巧。理解 Netmiko 在自动化运维体系中的角色。 1. Netmiko 简介 1.1 什么是 Netmiko Netmi…

LeNet5 神经网络的参数解析和图片尺寸解析

1.LeNet-5 神经网络 以下是针对 LeNet-5 神经网络的详细参数解析和图片尺寸变化分析,和原始论文设计,通过分步计算说明各层的张量变换过程。 经典的 LeNet-5架构简化版(原始论文输入为 32x32,MNIST 常用 28x28 需调整&#xff09…

Axure大屏可视化模板:多领域数据决策的新引擎

在数据驱动决策的时代,Axure大屏可视化模板凭借交互性与可定制性,成为农业、园区管理、智慧城市、企业及医疗领域的创新工具,助力高效数据展示与智能决策。 核心应用场景 1. 农业精细化:实时监控土壤湿度、作物生长曲线&#x…

代码随想录算法训练营第60期第十七天打卡

今天我们继续进入二叉树的下一个章节,今天的内容我在写今天的博客前大致看了一下部分题目难度不算大,那我们就进入今天的题目。 第一题对应力扣编号为654的题目最大二叉树 这道题目的坑相当多,我第一次题目没有看明白就是我不知道到底是如何…

SOC估算:开路电压修正的安时积分法

SOC估算:开路电压修正的安时积分法 基本概念 开路电压修正的安时积分法是一种结合了两种SOC估算方法的混合技术: 安时积分法(库仑计数法) - 通过电流积分计算SOC变化 开路电压法 - 通过电池电压与SOC的关系曲线进行校准 方法原…

使用 SSE + WebFlux 推送日志信息到前端

为什么使用 SSE 而不使用 WebSocket, 请看 SEE 对比 Websocket 的优缺点。 特性SSEWebSocket通信方向单向(服务器→客户端)双向(全双工)协议基于 HTTP独立协议(需 ws:// 前缀)兼容性现代浏览器&#xff08…

二叉树的遍历(广度优先搜索)

二叉树的第二种遍历方式,层序遍历,本质是运用队列对二叉树进行搜索。 层序遍历是指将二叉树的每一层按顺序遍历,通过队列实现就是先将根节点push入队,统计此时的队列中的元素数量size,将size元素全部pop出去&#xff0…