| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> freeRTOS任务调度及其通信 -> 正文阅读 |
|
[嵌入式]freeRTOS任务调度及其通信 |
一、FreeRTOS任务 在多数通用操作系统(如Linux、Windows等)中,线程为系统的调度最小单元,进程为独立应用程序的最小运行过程。而在实时操作系统中,多数情况下不区分线程与进程进行独立管理,为了减小系统资占用以及提高实时性,往往将线程与进程合二为一,采用任务作为应用程序的最小调度运行单元,使用TCB(任务控制块)对任务进行管理。FreeRTOS作为常用的RTOS系统中的一员,它的任务调度以及任务之间的通信的设计遵从多数RTOS的设计。FreeRTOS简捷、方便、易用的任务机制,是其近几年成为市场份额最大的RTOS因素之一,本文主要对其任务调度实现以及通信原理进行描述介绍。 二、FreeRTOS任务调度 FreeRTOS的任务被动态创建或者静态创建后,不进行删除,目前具备的任务运行态为Running态、Ready态、Blocked态以及Suspended态四个状态。从FreeRTOS官方给出任务资料以及任务状态示意图可以看出,任务的调度主要分为三大阶段: 阶段一:任务创建与调度器启动阶段(下图蓝色部分) 阶段二:任务运行后,调用任务API或者调度器仲裁切换任务状态阶段(下图绿色部分) 阶段三:任务删除销毁阶段(下图红色部分) 1. 任务创建启动阶段FreeRTOS调用xTaskCreate(动态创建)或者xTaskCreateStatic(静态创建)API进行任务的创建。动态创建任务时,为任务申请任务堆栈、申请任务控制块(TCB)内存、初始化申请到的内存、调用prvInitialiseNewTask函数初始化任务、最后调用prvAddNewTaskToReadyList函数将新建的任务加入就绪任务列表中(如下官方代码)。 创建完成任务后,多数情况下紧随其后调用任务API函数vTaskStartScheduler开启任务的调度。以采用动态创建任务的方式为例,vTaskStartScheduler函数中先是创建空闲任务(idle任务)、若使用软件定时器创建软件定时器、关闭中断、标记调度器开始运行、若配置时间统计开启时间统计功能、调用xPortStartScheduler函数(此函数适配不同的硬件平台,一般用于初始化硬件资源,滴答定时器等;如cortex-m系列用于初始化FPU单元、滴答定时器、PendSV中断等),流程如下图。 2. 任务运行阶段任务在调度器启动后,在创建的任务未被删除销毁之前,任务会在Running(运行)、Ready(就绪)态Blocked(阻塞)以及Suspended(挂起)四个状态中进行切换。 运行态的任务调用系统延时函数(如vTaskDelay函数)、调用ulTaskNotifyTake等待通知、调用xSemaphoreTake等待信号量等行为进入阻塞状态;正在运行的任务死等资源或者调用vTaskSuspend接口可以将自身挂起;正在运行的任务因被中断或者优先级高于或等于(时间片轮转方式使能)的任务打断进入就绪的任务队列中。 阻塞态的任务等到所需的资源或者调用的系统等待时间到点后,会被唤醒重新进入就绪任务列表中;此外也可以通过使用xSemaphoreTake接口将阻塞的任务挂起。 挂起态的任务只能通过调用系统API接口vTaskResume函数恢复到就绪的队列中,挂起态任务只能切换到就绪态。 就绪态的任务在调度器仲裁获取到CPU的执行权后,直接进入运行态,并且可以通过使用vTaskSuspend接口将其挂起。 FreeRTOS的运行态与就绪态之间的切换主要依赖调度器进行仲裁,仲裁算法同时支持优先级抢占式以及时间片调度方式(使能configUSE_PORT_OPTIMISED_TASK_SELECTION=1)。 第一种为优先级抢占的方式:FreeRTOS使用vTaskSwitchContext系统API函数进行任务之间切换,调用taskSELECT_HIGHEST_PRIORITY_TASK()函数仲裁,根据任务优先级获取下一个运行的任务,vTaskSwitchContext函数原型如下: 第二种为时间片轮转的调度方式:FreeRTOS使能时间片轮转的方式后,FreeRTOS提供系统API接口xTaskIncrementTick函数进行同个优先级的任务进行时间片轮转调度,每个时间片大小一般为滴答定时器的中断周期。多数情况下会在滴答定时器的中断回调中调用xTaskIncrementTick函数判断是否进行同个优先级任务的轮询切换(若任务在某一个滴答时钟周期内执行完毕,会强制调用portYIELD接口进行任务切换,放弃剩余的时间片时间)。如下图所示,TaskA的优先级等于TaskB,滴答定时器周期为1ms。 3.?任务删除销毁阶段就绪、阻塞、挂起的任务都可以调用vTaskDelete系统API接口将其进行删除销毁,被销毁的任务的任务控制块(TCB)以及任务堆栈会在进入idle任务后,在idle任务中进行删除以及释放。 三、任务通信 FreeRTOS具有一般操作系统都具备的几种任务之间的通信方式,提供给用户的常用的通信方式有:消息队列、信号量、互斥锁(互斥信号量)、事件标志组以及任务通知等。 FreeRTOS的任务通知具有32位的消息通知值,只有一个任务接收任务通知,可以减少RAM的使用,运行效率比二值信号量快45%(官方给出的数据)。 事件标志组与信号量的在于:时间标志组主要用与某个任务与多个事件进行同步,或者某个任务与多个任务进行同步。 1.?信号量FreeRTOS的信号量主要用于某个任务与单个事件或任务进行同步,FreeRTOS常用的信号量为以下几种: a. 二值信号量 b. 计数型信号量 c. 互斥信号量 d. 递归互斥型号量 以下为官方提供的二值信号量Gif图演示信号量的基本工作原理: 2.?消息队列FreeRTOS的消息队列主要用于任务中传递大量的消息,以下为官方提供的消息队列Gif图演示消息队列的基本工作原理: 四、小结?FreeRTOS的不同优先级的任务采用强抢占式调度(高优先抢占)保持其作为RTOS特有实时性,同级优先级的任务采用时间片轮转的方式兼顾同级平等的得到调度运行。任务与任务之间,提供信号量、消息队列、通知、事件标志组等方式进行通信,确保中断事件与任务、任务与任务之间可以有效、高效地进行通信。又因其特有免费开源的特性,使其在RTOS的市场占有份额越来越高。 参考文献 FreeRTOS官方文档:https://www.freertos.org/features.html FreeRTOS官方代码:https://www.freertos.org/a00104.html 长按关注 内核工匠微信 Linux 内核黑科技 | 技术文章 | 精选教程 |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 2:51:13- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |