freeRTOS中文实用教程1

freeRTOS中⽂实⽤教程1
1.前⾔
FreeRTOS是⼩型多任务嵌⼊式操作系统,硬实时性。本章主要讲述任务相关特性及调度相关的知识。
2. 任务的总体特点
任务的状态
(1)任务有两个状态,运⾏态和⾮运⾏态
(2)任务由⾮运⾏态转⼊运⾏态为切⼊,相反为切出
设置优先级
(1)最⾼优先级在FreeRTOSConfig.h 中 设 定 的 编 译 时 配 置 常 量configMAX_PRIORITIES中进⾏设置。
注:FreeRTOS 本⾝并没有限定这个常量的最⼤值,但这个值越⼤,则内核花销的内存空间就越多。建议将此常量设为能够⽤到的最⼩值
(2)任意数量的任务可以共享同⼀个优先级也可以为每个任务唯⼀指定⼀个优先级
(3)低优先级号表⽰任务的优先级低
(4)有效的优先级号范围从 0 到(configMAX_PRIORITES – 1)
(5)调度器保证总是在所有可运⾏的任务中选择具有最⾼优先级的任务,并使其进⼊运⾏态
(6)如果被选中的优先级上具有不⽌⼀个任务,调度器会让这些任务轮流执⾏
(7)调度器总是选择所有能够进⼊运⾏态的任务中具有最⾼优先级的任务
改变任务优先级
可以通过vTaskPrioritySet() 来改变任务的优先级
任务时间
(1)两个任务被创建在同⼀个优先级上,并且⼀直是可运⾏的。所以每个任务都执⾏⼀个”时间⽚”,任务在时间⽚起始时刻进⼊运⾏态,在时间⽚结束时刻⼜退出运⾏态
(2)调度器需要在每个时间⽚结束时能够调度⾃⼰, tick中断可以完成此⽬的
(3)tick中断频率可以通过FreeRTOSConfig.h 中的编译时配置常量configTICK_RATE_HZ 进⾏配置,如设为100HZ,则时间⽚长度为10ms
3.任务状态机
3.1 任务状态机
图 完整的任务状态机
阻塞态(blocked)
(1)如果⼀个任务正在等待某个事件,则称这个任务处于”阻塞态(blocked)”。阻塞态是⾮运⾏态的⼀个⼦状态。
(2)任务进⼊阻塞态⼀般等待以下两种事件:定时事件和同步事件
(3)任务可以在进⼊阻塞态等待同步事件时指定⼀个等待超时时间,这样可以有效地实现阻塞状态下同时等待两种类型的事件,
⽐如说,某个任务可以等待队列中有数据到来,但最多只等10ms。如果10ms 内有数据到来,或是10ms 过去了还没有数据到来,这两种情况下该任务都将退出阻塞态。
挂起状态(suspended)
(1)处于挂起状态的任务对调度器⽽⾔是不可见的
(2)让⼀个任务进⼊挂起状态的唯⼀办法就是调⽤vTaskSuspend() API 函数
(3)把⼀个挂起状态的任务唤醒的唯⼀途径就是调⽤vTaskResume() 或TaskResumeFromISR() API 函数
(4)⼤多数应⽤程序中都不会⽤到挂起状态
土钻就绪状态(ready)
(1)如果任务处于⾮运⾏状态,但既没有阻塞也没有挂起,则这个任务处于就绪(ready,准备或就绪)状态
(2)处于就绪态的任务能够被运⾏,但只是”准备(ready)”运⾏,⽽当前尚未运⾏海量数据查询
3.2.利⽤阻塞态实现延迟
1 void vTaskDelay( portTickType xTicksToDelay );
调⽤上⾯的函数的任务会进⼊阻塞态,xTicksToDelay表⽰delay的tick周期数,portTICK_RATE_MS代表每毫秒有多少个tick周期
4. 空闲任务
zigbee组网空闲任务的特点
(1)在调度器启动的时候vTaskStartScheduler会⾃动创建⼀个空闲任务
(2)空闲任务具有最低的优先级0,保证不会影响其它更⾼优先级的任务进⼊就绪态
(3)运⾏在最低优先级可以保证⼀旦有更⾼优先级的任务进⼊就绪态,空闲任务就会⽴即切出运⾏态
(4)空间任务可以获得的执⾏时间量,是系统处理能⼒裕量的⼀个度量指
空闲任务钩⼦函数
(1)通过空闲任务钩⼦函数(或称回调,hook, or call-back),可以直接在空闲任务中添加应⽤程序相关的功能,空闲任务钩⼦函数会被空闲任务每循环⼀次就⾃动调⽤⼀次
离心制丸机(2)空闲任务钩⼦函数被⽤于:
—执⾏低优先级,后台或需要不停处理的功能代码。
—测试系统处理裕量
—将处理器配置到低功耗模式——提供⼀种⾃动省电⽅法,使得在没有任何应⽤功能需要处理的时候,系统⾃动进⼊省电模式。
空闲任务钩⼦函数必须遵从以下规则
(1)绝不能阻塞或挂起。
空闲任务只会在其它任务都不运⾏时才会被执⾏(除⾮有应⽤任务共享空闲任务优先级)。
以任何⽅式阻塞空闲任务都可能导致没有任务能够进⼊运⾏态!
(2)如果应⽤程序⽤到了vTaskDelete() 函数,则空闲钩⼦函数必须能够尽快返回。
因为在任务被删除后,空闲任务负责回收内核资源。如果空闲任务⼀直运⾏在钩⼦函数中,则⽆法进⾏回收⼯作。
早泄宁5.任务的调度
优先级抢占式调度
每个任务都被赋予了⼀个优先级,这个优先级不能被内核本⾝改变(只能被任务修改)。
”抢占式”是指当任务进⼊就绪态或是优先级被改变时,如果处于运⾏态的任务优先级更⾼,则该任务总是抢占当前运⾏的任务
单调速率调度
单调速率调度(Rate Monotonic Scheduling, RMS)是⼀种常⽤的优先级分配技术。其根据任务周期性执⾏的速率来分配⼀个唯⼀的优先级。
具有最⾼周期执⾏频率的任务赋予⾼最优先级;具有最低周期执⾏频率的任务赋予最低优先级。这种优先级分配⽅式被证明了可以最⼤化整个应⽤程序的可调度性(schedulability),但是运⾏时间不定以及并⾮所有任务都具有周期性,会使得对这种⽅式的全⾯计算变得相当复杂
协作式调度
只可能在运⾏态任务进⼊阻塞态或是运⾏态任务显式调⽤ taskYIELD()时,才会进⾏上下⽂切换。
任务永远不会被抢占,⽽具有相同优先级的任务也不会⾃动共享处理器时间。协作式调度的这作⼯作⽅式虽然⽐较简单,但可能会导致系统响应不够快
混合调度
这需要在中断服务例程中显式地进⾏上下⽂切换,从⽽允许同步事件产⽣抢占⾏为,但时间事件却不⾏。
这样做的结果是得到了⼀个没有时间⽚机制的抢占式系统。或许这正是所期望的,因为获得了效率,并且这也是⼀种常⽤的调度器配置
6.任务调度举例
两个优先级相同的任务时间⽚执⾏图如下:
图 优先级相同的两个任务的时间⽚执⾏序列
加⼊了tick中断及tick中断调度器调度下个任务图⽰如下:
图 对执⾏流程进⾏扩展以显⽰tick中断的执⾏
由于task2⽐task1优先级⾼,因此task1永远得不到执⾏:
图 Task2⽐Task1优先级⾼时的任务运⾏序列
⽤vTaskDelay()代替空循环后的执⾏流程,task1得到了执⾏,如下图:
图 ⽤vTaskDelay()代替空循环后的执⾏流程
continuous 1与continuous 2具有优先级1,periodic具有优先级2,periodic使⽤vTaskDelayUntil,调度图如下(注意⼼跳中断在t5时刻实际是时间⽚到时调度器执⾏):
开始任务1具有最⾼优先级,任务1结束前将任务2设为最⾼优先级,任务2在结束时将⾃⾝设为最低优先级,执⾏序列如下:
idle在任务1进⼊阻塞态后,会执⾏对任务2的内存清除⼯作
三个任务(事件唤醒)的抢占执⾏过程
6. ⼀些重要的API
API 含义 重要参数说明 返回值
void ATaskFunction( void *pvParameters ); 任务的原型 参数必须是void * 返回值必须是void
portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode,
  const signed portCHAR * const pcName,
  unsigned portSHORT usStackDepth,
  void *pvParameters,
  unsigned portBASE_TYPE uxPriority,
  xTaskHandle *pxCreatedTask );
创建任务
uxPriority
表⽰任务的优先级,最好设置成实际任务需要的最⼩值,以避免浪费
void vTaskStartScheduler( void )
开始调度⼀个任务执⾏,第⼀次调度时会⾃动创建⼀个空闲任务
void vTaskDelete( TaskHandle_t xTaskToDelete )
删除⼀个任务
xTaskToDelete
要删除任务的句柄
void vTaskDelay( const TickType_t xTicksToDelay )
让当前任务进⼊阻塞态,并保持多少个tick
xTicksToDelay
⽤来指定任务在调⽤vTaskDelay()到切出阻塞态整个过程包含多少个tick
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime,
const TickType_t xTimeIncrement )
⽤于实现⼀个固定执⾏周期的需求求(当你需要让你的任务以固定频率周期性执⾏的时候)
激光发射器pxPreviousWakeTime
保存了任务上⼀次离开阻塞态(被唤醒)的时刻这个时刻被⽤作⼀个参考点来计算该任务下⼀次离开阻塞态的时刻。pxPreviousWakeTime 指向的变量值会在API 函数vTaskDelayUntil()调⽤过程中⾃动更新,应⽤程序除了该变量第⼀次初始化外(通过调⽤xTaskGetTickCount()初始化),通常都不要修改它的值
xTimeIncrement
此参数命名时同样是假定vTaskDelayUntil()⽤于实现某个任务以固定频率周期性执⾏ —— 这个频率就是由xTimeIncrement 指定的。xTimeIncrement 的单位是⼼跳周期, 可以使⽤常量
portTICK_RATE_MS 将毫秒转换为⼼跳周期。
void vApplicationIdleHook( void )
空闲钩⼦函数
void vTaskPrioritySet( xTaskHandle pxTask,
    unsigned portBASE_TYPE uxNewPriority )
改变任务优先级
pxTask
被修改优先级的任务句柄(即⽬标任务)
uxNewPriority
⽬标任务将被设置到哪个优先级上。如果设置的值超过了最⼤可⽤优
先级(configMAX_PRIORITIES – 1),则会被⾃动封顶为最⼤值。常
量 configMAX_PRIORITIES 是在 FreeRTOSConfig.h 头⽂件中设置
的⼀个编译时选项。
unsigned portBASE_TYPE uxTaskPriorityGet( xTaskHandle pxTask );
⽤于查询⼀个任务的优先级
pxTask
被查询任务的句柄(⽬标任务)
返回值 被查询任务的当前优先级
void vTaskDelete( xTaskHandle pxTaskToDelete )
删除任务
pxTaskToDelete
被删除任务的句柄(⽬标任务) 。任务可以通过传⼊ NULL 值来删除⾃⼰
taskYIELD
调⽤此函数的任务转⼊就绪态,同时另⼀个任务转⼊运⾏态
7.参考⽂档
[1] FreeRTOS中⽂实⽤教程

本文发布于:2024-09-22 12:26:54,感谢您对本站的认可!

本文链接:https://www.17tex.com/tex/4/310388.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:vue核心概念
下一篇:vue调用方法
标签:任务   空闲   调度   阻塞   时间   函数   没有
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议