EFM32jg之FreeRTOS(5)-任务调度、创建、切换

2023-05-16

@EFM32JG移植FreeRTOS

1、任务调度器

1)创建空闲任务,优先级为0,表示最低优先级,在无其他高优先级任务的情况下,执行空闲任务,若打开configUSE_IDLE_HOOK,则可以再空闲任务中增加自己想要执行的代码,定义勾子函数void vApplicationIdleHook( void )。

2)变量 xSchedulerRunning 设置为 pdTRUE,表示调度器开始运行。

3)设置 PendSV、滴答定时器 的中断优先级,为最低优先级。所以若为事件调度,需要关闭滴答定时器,在优先级最高的任务循环之前加入: SysTick->CTRL = 0,即可关闭。

4)利用SVC异常来启动第一个任务,SVC 中断服务函数应该为 SVC_Handler(),但是FreeRTOSConfig.h 中通过#define 的方式重新定义为了 xPortPendSVHandler()。

2、任务创建

1)为堆栈申请任务内存,大小为分配的值*4

2)为任务控制块申请内存

3)使用函数 prvInitialiseNewTask()初始化任务
A、若使能了互斥信号量功能,则初始化相应字段
B、初始化列表项 xStateListItem 和 xEventListItem
C、设置列表项xEventListItem的字段xItemValue,值越大,优先级就越小,在插入列表时需要排序
D、调用函数 pxPortInitialiseStack()初始化任务堆栈

4)任务创建完成以后就会被添加到就绪列表 pxReadyTasksLists[]中
A、变量 uxCurrentNumberOfTasks 为全局变量,用来统计任务数量,若为1,则表示创建第一个任务,需要初始化相应列表。
B、若新创建的任务优先级比正在运行的任务优先级高,需要修改 pxCurrentTCB 为新
建任务的任务控制块。
C、调用函数 prvAddTaskToReadyList()将任务添加到就绪列表中
D、如果该任务的任务优先级最高,而且调度器已经开始正常运行了,那么就调用函数taskYIELD_IF_USING_PREEMPTION()完成一次任务切换。

3、任务切换

1)任务切换是使用PendSV来切换任务的,它是不精确的
通过向中断控制和壮态寄存器 ICSR 的 bit28 写入 1 挂起 PendSV 来启动 PendSV 中断。

任务切换的场合是执行一次系统调用,或系统滴答定时器中断。

为了解决上下文切换与中断的冲突问题,防止中断被打断而造成异常,因此上下文切换放到中断中完成。

2)任务切换函数taskYIELD()

此函数使用时,会直接切换成优先级最高的任务,当任务优先级一致的时候,会切换为别的任务,但是当优先级不一致,当前任务优先级最高,而且任务还没有挂起,会导致重新运行该任务,不会切换为别的任务。
所以我是用的事件触发的任务切换使用延时函数切换,vTaskDelay(1),可将任务阻塞,并执行下个任务。在使用事件去切换任务时,当注意控制好该延时,1表示一次事件周期,需保证一次事件周期可以让任务都执行一遍,防止把低优先级任务饿死。

3)滴答定时器中断

void SysTick_Handler(void)
{
		if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
		{
				xPortSysTickHandler();
		}
		HAL_IncTick();
}

当利用事件触发任务时,使用下面的代码即可,添加到事件中,每次事件达成,即开启一次任务调度,否则可以在低功耗模式下休眠,以降低功耗。

if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)//系统已经运行
{
		xPortSysTickHandler();
}

宏configUSE_TIME_SLICING虽然在例程的FreeRTOSConfig.h 文件中未定义,但是默认为1,表示在同一优先级下可进行任务切换

函数xPortSysTickHandler()调用xTaskIncrementTick,进行时钟节拍计数,并检查是否有任务需要解除阻塞。当计数溢出时,切换延时列表,实现计数溢出切换,此方法可在其他地方借鉴使用!!!!!

解除延时阻塞,可以是任务延时,也可以是事件超时退出。直接将任务添加到就绪列表中。并判断当前任务优先级,使用优先级最高的任务。

4)延时函数(相对延时)
将任务加入延时列表,计算出唤醒时间,xTimeToWake = xConstTickCount + xTicksToWait;,xConstTickCount=xTickCount,xTickCount 是时钟节拍计数器,每次调用xTaskIncrementTick时xTickCount 都会加一。
当溢出时,会将任务放入溢出的延时列表,当计数溢出时,切换列表则可以实现翻转计数。
将任务阻塞后,开始进行任务切换。

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

EFM32jg之FreeRTOS(5)-任务调度、创建、切换 的相关文章

  • FreeRTOS-内核控制函数

    FreeRTOS 内核控制函数 FreeRTOS中有一些内核函数 一般来说这些内核函数在应用层不会使用 但是内核控制函数是理解FreeRTOS中断的基础 接下来我们逐一分析这些内核函数 taskYIELD 该函数的作用是进行任务切换 这是一
  • 一文教你学会keil软件仿真

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

    记录一下一个实际项目由裸机程序改成FreeRTOS 以前产品的平台还是C8051单片机上面的程序 硬件平台改成了STM32L051 同时使用STM32CubeMX生成的工程 使用FreeRTOS系统 EEPROM数据存储读取函数修改更新 2
  • 【FreeRTOS】任务通知的使用

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

    http blog sina com cn s blog 98ee3a930102wg5u html 本章教程为大家讲解两个重要的概念 FreeRTOS的临界段和开关中断 本章教程配套的例子含Cortex M3内核的STM32F103和Co
  • FreeRTOS基础五:软件定时器

    软件定时器简介 软件定时器的作用 在指定的时间到来时执行指定的函数 或者以某个频率周期性地执行某个函数 被执行的函数叫做软件定时器回调函数 软件定时器由FreeRTOS内核实现 不需要硬件支持 软件定时器只有在软件定时器回调函数被调用时才需
  • FreeRTOS,串口中断接收中使用xQueueOverwriteFromISR()函数,程序卡死在configASSERT

    原因 UART的中断优先级设置的太高 高于了configMAX SYSCALL INTERRUPT PRIORITY宏定义的安全中断等级 UART的中断等级小于等于宏定义的优先等级即可
  • FreeRTOS之软件定时器

    FreeRTOS之软件定时器 声明 本人按照正点原子的FreeRTOS例程进行学习的 欢迎各位大佬指责和批评 谢谢 include sys h include delay h include usart h include led h in
  • RT-Thread记录(五、RT-Thread 临界区保护与FreeRTOS的比较)

    本文聊聊临界区 以及RT Thread对临界区的处理 通过源码分析一下 RT Thread 对临界区保护的实现以及与 FreeRTOS 处理的不同 目录 前言 一 临界区 1 1 什么是临界区 1 2 RTOS中的临界区 二 RT Thre
  • freeRTOS出现任务卡死的情况。

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

    1 临界段 在访问共享资源时不希望被其他任务或者中断打断的代码 这段要执行的代码称为临界段代码 2 设置临界段的目的 保护共享资源 例如 全局变量 公共函数 不可重入函数 函数里面使用 了一些静态全局变量 malloc 等 保护外设的实时性
  • 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之系统配置

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

    我使用的是带有 5 4 版 FreeRTOS 的 MSP430f5438 我有一个有趣的问题 我无法弄清楚 基本上 当我将 configTICK RATE HZ 设置为不同的值时 LED 闪烁得更快或更慢 它应该保持相同的速率 我将 con
  • 如何更改 FreeRTOS 中任务的最大可用堆大小?

    我通过以下方式在任务中创建元素列表 l dllist pvPortMalloc sizeof dllist dlllist 有 32 字节大 我的嵌入式系统有 60kB SRAM 所以我希望系统可以轻松处理我的 200 个元素列表 我发现在
  • 防止GCC LTO删除函数

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

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

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free
  • 有关 CMake 错误的问题:没有为目标提供源

    我正在尝试使用 cmake 和 eclipse 将 FreeRtos 添加到我的项目中 但出现错误 我运行的是 debian 10 我的 cmake 版本是 3 13 4 cmake 的文件可以在以下位置找到这个 git 仓库 https

随机推荐