【FreeRTOS】任务调度与任务切换

2023-05-16

目录

一、任务调度

二、任务切换

三、关于PendSV


一、任务调度

      

       在创建好任务函数后,需要调用函数vTaskStartScheduler()开启任务调度器,创建的任务在调度器的调度下执行。

       开启任务调度器函数为:

vTaskStartScheduler();          //开启任务调度

        该任务会创建一个函数名为prvIdleTask()的空闲任务,以及完成相关硬件初始化,如SysTick定时器、FPU(浮点运算)单元和PendSV中断。所谓空闲任务就是在处理器不执行其余任务时执行的任务(功能可自定)。

硬件初始化函数:

BaseType_t xPortStartScheduler( void )
{
     /*设置SysTick定时器中断和PendSV中断优先级为最低优先级*/
    portNVIC_SHPR3_REG |= portNVIC_PENDSV_PRI;  
    portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;

    vPortSetupTimerInterrupt();      /*SysTick定时器相关配置*/
    uxCriticalNesting = 0;           /*初始化临界嵌套计数器*/

    prvEnableVFP();                                 /*使能FPU单元*/        
    *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;     /*设置FPU相关寄存器*/

    prvStartFirstTask();        /*启动第一个任务*/
    return 0;

}

二、任务切换

       任务的切换是在PendSV中断函数里实现的,触发该中断的方法是向中断控制器和壮志寄存器ICSR的bit28写入1。

       PendSV中断函数是用汇编写的:

__asm void xPortPendSVHandler( void )
{
    extern uxCriticalNesting;
    extern pxCurrentTCB;
    extern vTaskSwitchContext;

/* *INDENT-OFF* */
    PRESERVE8

    mrs r0, psp
    isb

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

    /* Is the task using the FPU context?  If so, push high vfp registers. */
    tst r14, #0x10
    it eq
    vstmdbeq r0!, {s16-s31}

    /* Save the core registers. */
    stmdb r0!, {r4-r11, r14}

    /* Save the new top of stack into the first member of the TCB. */
    str r0, [ r2 ]

    stmdb sp!, {r0, r3}
    mov r0, # configMAX_SYSCALL_INTERRUPT_PRIORITY  
    msr basepri, r0                  //关中断,进入临界段
    dsb
    isb
    bl vTaskSwitchContext            //获取下一个执行的任务
    mov r0, # 0
    msr basepri, r0                  //开中断,退出临界段
    ldmia sp!, {r0, r3}

    /* The first item in pxCurrentTCB is the task top of stack. */
    ldr r1, [ r3 ]
    ldr r0, [ r1 ]

    /* Pop the core registers. */
    ldmia r0!, {r4-r11, r14}

    /* Is the task using the FPU context?  If so, pop the high vfp registers* too. */
    tst r14, # 0x10
    it eq
    vldmiaeq r0!, {s16-s31}

    msr psp, r0
    isb

    #ifdef WORKAROUND_PMU_CM001 /* XMC4000 specific errata */
        #if WORKAROUND_PMU_CM001 == 1

            push { r14 }
            pop { pc }
            nop
        #endif
    #endif

    bx r14

/* *INDENT-ON* */

}

       任务切换函数taskYIELD()和SysTick中断函数就是向中断控制器和壮志寄存器ICSR的bit28写入1触发PendSV函数完成任务的切换。

taskYIELD()函数实现:

#define portYIELD()                                 \
  {                                                   \

    /* Set a PendSV to request a context switch. */ \
    portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ //在ICSR的bit28写入1,触发PendSV中断
                                                        \

     __dsb( portSY_FULL_READ_WRITE );                           \
     __isb( portSY_FULL_READ_WRITE );                           \

  }

SysTick中断函数实现:

void xPortSysTickHandler( void )
{
   vPortRaiseBASEPRI();    //关中断,进入临界段
   {
     if( xTaskIncrementTick() != pdFALSE ) //增加时钟计数器xTickCount的值
     {
        /*在ICSR的bit28写入1,触发PendSV中断*/
      portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;  //( 1UL << 28UL ) 

     }
   }
    vPortClearBASEPRIFromISR();     //开中断,退出临界段
}

三、关于PendSV

       以下是在《Cortex-M3权威指南》中的部分截图:

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

【FreeRTOS】任务调度与任务切换 的相关文章

  • FreeRTOS例程4-串口DMA收发不定长数据

    FreeRTOS例程4 串口DMA收发不定长数据 知乎 zhihu com
  • FreeRTOS 软件定时器的使用

    FreeRTOS中加入了软件定时器这个功能组件 是一个可选的 不属于freeRTOS内核的功能 由定时器服务任务 其实就是一个定时器任务 来提供 软件定时器是当设定一个定时时间 当达到设定的时间之后就会执行指定的功能函数 而这个功能函数就叫
  • FreeRTOS软件定时器创建、复位、开始和停止(备忘)

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

    FreeRTOS简述和移植文档 文章目录 FreeRTOS简述和移植文档 1 前言 2 FreeRTOS简述 1 概述 2 实现 3 主要特色 4 支持平台 3 移植FreeRTOS 4 最后 1 前言 目前由于IOT的飞速发展 针对单片机
  • 一文教你学会keil软件仿真

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

    本文主要介绍如何在任务或中断中向队列发送消息或者从队列中接收消息 使用STM32CubeMX将FreeRTOS移植到工程中 创建两个任务以及两个消息队列 并开启两个中断 两个任务 Keyscan Task 读取按键的键值 并将键值发送到队列
  • freertos---软定时器

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

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

    传送门 博客汇总帖 传送门 Cortex M3 中断 异常 传送门 Cortex M3笔记 基础 笔记内容参考 正点原子的FreeRTOS开发手册 cortex m3权威指南 Cortex M3和Cortex M4权威指南等 文中stm32
  • FreeRTOS基础五:软件定时器

    软件定时器简介 软件定时器的作用 在指定的时间到来时执行指定的函数 或者以某个频率周期性地执行某个函数 被执行的函数叫做软件定时器回调函数 软件定时器由FreeRTOS内核实现 不需要硬件支持 软件定时器只有在软件定时器回调函数被调用时才需
  • freertos————互斥锁

    线程安全 多线程程序处于一个多变的环境 可访问的全局变量和堆数据随时可能被其他的线程改变 多个线程同时访问一个共享数据 可能造成严重的后果 出现问题的是之前移植了一个freemodbus的从站 多个任务访问全局变量保持寄存器区 导致最后读出
  • stm32f103zet6移植标准库的sdio驱动

    sdio移植 st官网给的标准库有给一个用于st出的评估板的sdio外设实现 但一是文件结构有点复杂 二是相比于国内正点原子和野火的板子也有点不同 因此还是需要移植下才能使用 当然也可以直接使用正点原子或野火提供的实例 但为了熟悉下sdio
  • 啊哈C的简单使用

    打开啊哈C 新建一个程序输出hello world include
  • Arduino IDE将FreeRTOS用于STM32

    介绍 适用于STM32F103C8的FreeRTOS STM32F103C是一种能够使用FreeRTOS的ARM Cortex M3处理器 我们直接在Arduino IDE中开始使用STM32F103C8的FreeRTOS 我们也可以使用K
  • STM32 Freertos 添加 外部sram heap_5.c

    1 添加外部SRAM 初始化 2 添加heap 5 c 3 初始化heap 5 c 外部堆栈 Define the start address and size of the two RAM regions not used by the
  • 13-FreeRTOS任务创建与删除

    任务创建和删除API函数位于文件task c中 需要包含task h头文件 task h里面包函数任务的类型函数 例如 对xTaskCreate的调用 通过指针方式 返回一个TaskHandle t 变量 然后可将该变量用vTaskDele
  • FreeRTOS 配置TICK_RATE_HZ

    我使用的是带有 5 4 版 FreeRTOS 的 MSP430f5438 我有一个有趣的问题 我无法弄清楚 基本上 当我将 configTICK RATE HZ 设置为不同的值时 LED 闪烁得更快或更慢 它应该保持相同的速率 我将 con
  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 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

随机推荐

  • 死锁的成因及其解决办法

    x1f512 一 什么是死锁 死锁就是两个或者两个以上的线程在执行过程中 由于资源竞争或者由于彼此通信而造成的阻塞现象 若无外力作用 都将无法推进下去 二 关于死锁的情况 x1f937 情况 一个线程 一把锁 如果是可重入锁不会产生死锁 不
  • Ubuntu 18.04 配置ROS melodic 配置qt包并且建立基础pub界面

    建立工作空间 mkdir p ros gui demo src cd ros pkg src sudo apt get install ros melodic qt create sudo apt get install ros melod
  • RFID 负载调制和反向散射调制

    我用我质朴的语言概述一下我的理解 xff0c 射频识别系统中 xff0c 阅读器和标签之间的通信通过电磁波来实现 按照通信距离 xff0c 可以划分为近场和远场 xff1b 按照频率又分 xff1a 低频 高频 超高频 相应的 xff0c
  • ubuntu虚拟机上配置深度学习环境

    学习笔记 xff0c 主要是记录自己目前进行的操作 xff0c 以便自己回顾 xff0c 各位大佬有指导意见也欢迎交流啊 一 安装miniconda Linux下安装miniconda linux 安装miniconda 摸鱼肥仔的博客 C
  • 如何创建一个项目(学习笔记)

    前言 xff1a 欢迎来到本次教程 这篇文章旨在深入解析在 B 站上的 Vue3 后台管理项目 xff0c 同时也为您提供了创建此类项目的实践思路 我们将通过这个笔记系统地梳理一个项目的整体框架 xff0c 涵盖了我们在 Vue 课程中学习
  • PX4学习之uorb

    PX4学习之uorb 1线程 1 1优点 在Linux系统下 xff0c 启动一个新的进程必须分配给它独立的地址空间 xff0c 建立众多的数据表来维护它的代码段 堆栈段和数据段 xff0c 这是一种 34 昂贵 34 的多任务工作方式 而
  • 53 Command “python setup.py egg_info“ failed with error

    53 1 引言 今天在Ubuntu环境下搭建安信科技的ESP8266开发环境 xff0c 到配置这一步骤时出现了 xff0c 一个问题 xff0c 网上一顿查阅 xff0c 然后并没有实际解决 xff0c 后面查到外文blog外国朋友遇到跟
  • vue2的钩子函数

    一 定义 钩子函数是一个组件从引入到销毁的全过程中提供的函数 xff0c 我们可以在钩子函数中写我们自己的代码 xff0c 比如说请求数据 赋值 注册事件等 二 钩子函数类型 钩子函数按照组件生命周期分为 xff1a 挂载阶段 xff08
  • gazebo打不开或者无响应?

    1 打不开 xff0c 显示无路径 报错 xff1a gazebo error while loading shared libraries libblas so 3 cannot open shared object file No su
  • 【超详细】树莓派4B 英特尔神经棒2代 Openvino安装记录

    主要参考了英特尔官方文档https docs openvinotoolkit org 2019 R3 1 docs install guides installing openvino raspbian html 还有同济子豪兄在达尔文的b
  • 2021-08-19-leetcode-00001

    二分查找 704 给定一个 n 个元素有序的 xff08 升序 xff09 整型数组 nums 和一个目标值 target xff0c 写一个函数搜索 nums 中的 target xff0c 如果目标值存在返回下标 xff0c 否则返回
  • FreeRTOS系统开发指南【精简版】

    文件说明 该文件主要根据FreeRTOS系统的功能 对FreeRTOS系统应用API函数进行项目开发进行指导和快速阅览 方便用户通过该文件快速使用FreeRTOS的内部资源来进行项目开发 其中涉及任务 时间管理 队列 信号量 定时器 内存管
  • 立创EDA学习笔记(3)——PCB绘制

    使用更新 转换原理图到PCB xff0c 将原理图导入PCB后 xff0c 点击工程中的PCB切换到该页面 xff0c 接下来进行PCB绘制 目录 一 放置板框 二 绘制定位孔 三 布局 四 布线 五 修改位号丝印大小 六 添加丝印 七 添
  • A star算法在三维避障路径规划的应用

    A star算法在三维避障路径规划的应用 前言 前言 在实际工程应用中 运动目标的外形 大小直接影响到路径选择 针对三维复杂场景的碰撞检测和路径规划问题 提出了一种基于层次包围盒碰撞检测的实时路径规划优化算法 该优化算法在进行碰撞检测时 通
  • Jetson TX2零基础学习(一)——连线、刷机

    目录 一 背景介绍 二 连线 三 刷机 四 鸣谢 五 结束语 系列文章 一 背景介绍 大家好 xff0c 我是潇湘小硕士 xff0c 注册账号已经两年有余 xff0c 今天第一次发文 xff0c 希望能够帮助到大家 我是通信专业研一学生一枚
  • 嵌入式Linux C多任务编程(进程篇)

    这俩天刚整理完进程部分内容 xff0c 再做个一个总结以便后期回顾 1 什么是多任务 xff1f 单任务vs多任务 单任务 xff1a 一个任务执行结束才能执行下一个任务 xff0c 或者说在一个任务执行得过程中不能响应其他任务 xff0c
  • 如何在Ubuntu上安装Boost

    本文翻译自 xff1a How to install Boost on Ubuntu I 39 m on Ubuntu and I want to install Boost 我在Ubuntu上 xff0c 并且想安装Boost I tri
  • A D 20:基于S T M 32的DDS信号源设计

    直接数字频率合成 xff08 DDS xff09 xff1a 根据正弦函数的产生原理 xff0c 直接对输入参考时钟进行抽样 数字化 xff0c 从相位出发 xff0c 用不同的相位给出不同的电压幅度 xff0c 最后经滤波平滑输出所需的频
  • 【STM32/FreeRTOS】SysTick定时器及FreeRTOS系统节拍

    目录 一 SysTick定时器 1 SysTick寄存器介绍 xff08 1 xff09 控制及状态寄存器 xff08 2 xff09 重装载数值寄存器 xff08 3 xff09 当前数值寄存器 2 SysTick寄存器配置函数 二 Fr
  • 【FreeRTOS】任务调度与任务切换

    目录 一 任务调度 二 任务切换 三 关于PendSV 一 任务调度 在创建好任务函数后 xff0c 需要调用函数vTaskStartScheduler 开启任务调度器 xff0c 创建的任务在调度器的调度下执行 开启任务调度器函数为 xf