FreeRTOS中任务切换过程的分析

2023-05-16

FreeRTOS中Pendsv任务切换过程的分析

一、Pendsv中断任务解析 x切换代码

(1)uxCriticalNesting 是进入临界区的次数
(2)pxCurrentTCB是FreeRTOS运行时当前的任务块
(3)vTaskSwitchContext是用来选择下一个要运行任务的函数
(4)mrs r0, psp 是将进程栈指针送到r0
(5)isb是指令同步代码,由于CortexM3,4为哈弗结构,因此保证执行完之前指令之后再继续执行后续指令
(6)ldr r3, =pxCurrentTCB 将pxCurrentTCB的地址放入r3
(7)ldr r2, [r3] 获取当前的任务块地址(此处注意任务块首地也是指向任务栈的栈顶指针)
(8)stmdb r0!, {r4-r11} 保存剩下的8个寄存器,为什么是剩下的8个寄存器,在没有浮点运算的cortexM3,M4中,cpu中的普通寄存器有15个,分别为r0-r12,r13(SP:栈指针),r14(LR,链接寄存器,主要用来中断等返回),r15(PC:程序计数器,指向当前指令的之后的第4个地址,因为为3流水线结构),而在进入中断时,cpu会自动将r0-r3,r12,r14,返回地址,xPSR(程序状态寄存器)共8个寄存器压栈,而普通寄存器还剩r4-r11(SP是不用压栈的)
(9)str r0, [r2] 将r0的内容(即新的栈顶指针)写到任务块中(任务栈的栈顶指针),这样下次调任务的时候就可以执行出栈操作。
(10)stmdb sp!, {r3, r14},将r3,r14入栈,r3保存了pxCurrentTCB的地址,而r14用来中断返回的,由于下面调用了vTaskSwitchContext,防止这两个寄存器内容丢失。(注意此处压的栈是msp,并非psp,因为处理模式下只能使用msp)
(11)
mov r0,#configMAX_SYSCALL_INTERRUPT_PRIORITY
msr basepri, r0
dsb
isb
是用来屏蔽中断,即进入临界区,并进行数据指令同步
(12)bl vTaskSwitchContext选择下一个要运行的任务,注意此函数中将pxCurrentTCB的值改成了下一个要运行的任务,而r3指向的是pxCurrentTCB的地址,故取出来后的是下一个要运行任务的任务块的地址!!!(pxCurrentTCB是一个房间,此房间内容是要运行的任务块地址,而r3保存的是pxCurrentTCB的房间号,故取到的虽是同一个pxCurrentTCB的房间,但pxCurrentTCB的房间里面实际内容已经改变了,这是理解后面的关键)
(13)mov r0, #0
msr basepri, r0
打开中断,即退出临界区
(14)ldmia sp!, {r3, r14} 恢复r3,r14
(15)
ldr r1, [r3]
ldr r0, [r1]
ldmia r0!, {r4-r11}
此时r0指向下一个要运行任务的首地址,即任务栈顶(详细分析见(12)),恢复r4-r11的内容,故此处恢复的是即将运行任务的“环境”
(13)
msr psp, r0
isb
更新psp进程栈指针,即指向了下一个要运行任务的任务栈的地址(那些要运行的“环境”已经出栈了)
(14)
bx r14
nop
执行此代码后上述的8个寄存器将自动出栈,注意此处恢复的也是下个运行任务的8组寄存器(因为从该中断返回是进入线程模式,用的是psp,(13)中已将psp更新为下一任务的栈地址),故PC将指向下个任务,至此任务切换完成
【注】r14内容一直的是用来返回pendsv中断的

void vTaskSwitchContext( void )函数

选择下一个它运行任务函数
(1)如果任务调度器挂起则置位标志位
(2)taskSELECT_HIGHEST_PRIORITY_TASK();选则下一个要运行的函数

taskSELECT_HIGHEST_PRIORITY_TASK()

taskSELECT_HIGHEST_PRIORITY_TASK函数描述
(1)portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities );
其定义为 uxTopPriority = ( 31UL - ( uint32_t ) __clz( ( uxReadyPriorities ) ) )
__clz是前导零计算的汇编指令,即是检测uxTopReadyPriorities从高位到第一个不为0的0个数,用31减去则得到该第一个1对应的位数,即为最高优先级的任务。(获取最高优先级任务有软件通用方法和硬件方法两种:1硬件方法就是设置优先级标志组,即该字中每个位代表一个优先级,则可用前导零来获取最高优先级任务(但并不是所有cpu都提供该指令)但优先级数量只有32位 2利用软件方法获取,优先级数不受限制)
(2)listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) );因为同等最高优先级任务放在同一个uxTopReadyPriorities下标的链表中,则调用获取链表中第一个任务,并且更新到pxCurrentTCB中

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS中任务切换过程的分析 的相关文章

  • FreeRTOS快速上手

    FreeRTOS使用 一 源码下载和移植文件提取 1 1 源码下载 在网站https sourceforge net projects freertos 可以找到freertos最新的源码 1 2 移植文件提取 根据第一步 我们会得到一个f
  • FreeRTOS config开始的宏

    FreeRTOSConfig h系统配置文件中可以自定义 FreeRTOS h中定义默认值 configAPPLICATION ALLOCATED HEAP 默认情况下FreeRTOS的堆内存是由编译器来分配的 将宏configAPPLIC
  • FreeRTOS 软件定时器的使用

    FreeRTOS中加入了软件定时器这个功能组件 是一个可选的 不属于freeRTOS内核的功能 由定时器服务任务 其实就是一个定时器任务 来提供 软件定时器是当设定一个定时时间 当达到设定的时间之后就会执行指定的功能函数 而这个功能函数就叫
  • FreeRTOS-内核控制函数

    FreeRTOS 内核控制函数 FreeRTOS中有一些内核函数 一般来说这些内核函数在应用层不会使用 但是内核控制函数是理解FreeRTOS中断的基础 接下来我们逐一分析这些内核函数 taskYIELD 该函数的作用是进行任务切换 这是一
  • FreeRTOS学习笔记 6 - 互斥量

    目录 1 创建 2 获取 3 释放 4 测试 FreeRTOS不支持调度方式的设置 所以下面2个宏定义可以随意设置值 define RTOS IPC FLAG FIFO 0x00 define RTOS IPC FLAG PRIO 0x01
  • 【FreeRTOS开发问题】FreeRTOS内存溢出

    FreeRTOS内存溢出 如下图所示 FreeRTOS编译完成后可以看到 系统提示无法分配内存到堆 Objects Template axf Error L6406E No space in execution regions with A
  • freertos---软定时器

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

    1 RTOS简介 RTOS全称为 Real Time Operation System 即实时操作系统 RTOS强调的是实时性 又分为硬实时和软实时 硬实时要求在规定的时间内必须完成操作 不允许超时 而软实时里对处理过程超时的要求则没有很严
  • ZYNQ中FreeRTOS中使用定时器

    使用普通的Timer中断方式时 Timer中断可以正常运行 但是UDP通信进程无法启动 其中TimerIntrHandler是中断服务程序 打印程序运行时间与从BRAM中读取的数据 void SetupInterruptSystem XSc
  • freeRTOS手册 第六章 . 中断管理

    如果我对本翻译内容享有所有权 允许任何人复制使用本文章 不会收取任何费用 如有平台向你收取费用与本人无任何关系 第六章 中断管理 章节介绍和范围 事件 嵌入式实时系统必需对环境中的事件做出响应 比如 外部网络设备收到一个发送给TCP IP栈
  • FreeRTOS临界区

    FreeRTOS临界区是指那些必须完整运行 不能被打断的代码段 比如有的外设的初始化需要严格的时序 初始化过程中不能被打断 FreeRTOS 在进入临界区代码的时候需要关闭中断 当处理完临界区代码以后再打开中断 FreeRTOS 系统本身就
  • freeRTOS使用uxTaskGetStackHighWaterMark函数查看任务堆栈空间的使用情况

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

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • FreeRTOS学习(三)开关中断

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

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

    最近在做一个产品二代升级的项目 代码是上一任工程师留下的 很多BUG 而且融合了HAL库和LL库 以及github上下载的GSM源码 很不好用 我这边是将2G模块换成了4G 且添加了单独的BLE模块 因此只在源码的基础上 去除2G和BLE代
  • 13-FreeRTOS任务创建与删除

    任务创建和删除API函数位于文件task c中 需要包含task h头文件 task h里面包函数任务的类型函数 例如 对xTaskCreate的调用 通过指针方式 返回一个TaskHandle t 变量 然后可将该变量用vTaskDele
  • 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每一次中断都会触发内
  • C++ freeRTOS任务,非静态成员函数的无效使用

    哪里有问题 void MyClass task void pvParameter while 1 this gt update void MyClass startTask xTaskCreate this gt task Task 204

随机推荐