【09】FreeRTOS的时间片调度
目录
- 1.时间片调度简介
- 2.时间片调度实验
- 2.1删除不相关程序
- 2.2使能两个宏
- 2.3修改滴答定时器中断频率
- 2.4完成程序内容
1.时间片调度简介
同等优先级任务轮流地享有相同的 CPU 时间(可设置), 叫时间片,在FreeRTOS中,一个时间片就等于SysTick 中断周期。在源码中,SysTick中断服务函数1ms中断一次,一个时间片就是1ms,滴答定时器SysTick的中断周期可以自己设置。
时间片调度运行举例:
运行条件:
1、创建三个任务:Task1、Task2、Task3
2、Task1、Task2、Task3的优先级均为1;即3个任务同等优先级
运行过程如下:
1、首先Task1运行完一个时间片后,切换至Task2运行(不管Task1是否运行完成,只运行一个时间片的Task1)
2、Task2运行完一个时间片后,切换至Task3运行
3、Task3运行过程中(还不到一个时间片),Task3阻塞了(系统延时或等待信号量等,下次轮到Task3时还是只允许一个时间片,上次阻塞剩余的时间片,不会再被补回来),此时直接切换到下一个任务Task1
4、Task1运行完一个时间片后,切换至Task2运行
总结:
1、同等优先级任务,轮流执行,时间片流转;
2、一个时间片大小,取决为滴答定时器中断频率;
3、注意没有用完的时间片不会再使用,下次任务Task3得到执行还是按照一个时间片的时钟节拍运行。
2.时间片调度实验
1、实验目的:学会对FreeRTOS 时间片调度使用
2、实验设计:将设计三个任务:start_task、task1、task2,其中task1和task2优先级相同均为2。为了使现象明显,将滴答定时器的中断频率设置为50ms中断一次,即一个时间片50ms
三个任务的功能如下:
start_task:用来创建其他的2个任务
task1:通过串口打印task1的运行次数
task2:通过串口打印task2的运行次数
注意:使用时间片调度需把宏configUSE_TIME_SLICING 和 configUSE_PREEMPTION 置1。
本次实验基于本系列文章中链接:【07】FreeRTOS的列表和列表项工程文件实现。
2.1删除不相关程序
删除列表和列表项相关程序内容,编译程序无报错。
#include "freertos_demo.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"
#include "delay.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO 1
#define START_TASK_STACK_SIZE 128
TaskHandle_t start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO 2
#define TASK1_STACK_SIZE 128
TaskHandle_t task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO 3
#define TASK2_STACK_SIZE 128
TaskHandle_t task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************//*** @brief FreeRTOS例程入口函数* @param 无* @retval 无*/
void freertos_demo(void)
{ xTaskCreate((TaskFunction_t ) start_task,(char * ) "start_task",(configSTACK_DEPTH_TYPE ) START_TASK_STACK_SIZE,(void * ) NULL,(UBaseType_t ) START_TASK_PRIO,(TaskHandle_t * ) &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL(); /*进入临界区*/xTaskCreate((TaskFunction_t ) task1,(char * ) "task1",(configSTACK_DEPTH_TYPE ) TASK1_STACK_SIZE,(void * ) NULL,(UBaseType_t ) TASK1_PRIO,(TaskHandle_t * ) &task1_handler );xTaskCreate((TaskFunction_t ) task2,(char * ) "task2",(configSTACK_DEPTH_TYPE ) TASK2_STACK_SIZE,(void * ) NULL,(UBaseType_t ) TASK2_PRIO,(TaskHandle_t * ) &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL(); /*退出临界区*/
}/* 任务1,实现LED0每500ms闪烁一次,用来提示系统正在运行 */
void task1( void * pvParameters )
{while(1){LED0=~LED0;vTaskDelay(500);}
}
/* 任务2,调用列表和列表项相关API函数,并且通过串口输出相应的信息,进行观察 */
void task2( void * pvParameters )
{while(1){vTaskDelay(500);}
}
2.2使能两个宏
宏时间片调度configUSE_TIME_SLICING 和宏抢占式调度 configUSE_PREEMPTION在FreeRTOSCofig.h中默认是都为1的,默认支持时间片调度。
#define configUSE_PREEMPTION 1 /* 1: 抢占式调度器, 0: 协程式调度器, 无默认需定义 */
#define configUSE_TIME_SLICING 1 /* 1: 使能时间片调度, 默认: 1 */
2.3修改滴答定时器中断频率
在FreeRTOSConfig.h中宏configTICK_RATE_HZ 定义为1000Hz时对应1ms,此时想增大至50ms,时间乘以50倍,对应频率缩小50倍,所以设置宏configTICK_RATE_HZ 为20。
#define configTICK_RATE_HZ 20 /* 定义系统时钟节拍频率, 单位: Hz, 无默认需定义 */
2.4完成程序内容
函数TaskDelay()
可以引起任务调度,会将当前正在运行的任务挂载到阻塞列表,和章节1中时间片调度举例类似,如果任务3被阻塞会直接更换运行的任务,去运行Task1,并不能提现到一个时间片为50ms的作用(这里是为了得到Task1一个时间片中的运行次数),所以使用自己写的死延时函数delay_ms()
。Task1任务函数中,死延时了10ms,理论上是应该运行Task1任务函数5次,但是函数printf()
也会消耗一部分时间,整个运行时间大于10ms,所以运行次数应该是小于5次的(运行4~5次)。最后,将Task1和Task2的任务优先级都设置为2,设置为同等优先级即可。假设在50ms时,Task1运行至函数printf()
,此时还没打印完就转向运行Task2,串口打印信息会乱掉,所以需要在printf()
函数前后加上开启临界区和关闭临界区,也就是关闭任务调度。由于进入临界区会影响实时性,所以需要在进入和退出临界区之间的代码运行时间尽可能短。
#include "freertos_demo.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"
#include "delay.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO 1
#define START_TASK_STACK_SIZE 128
TaskHandle_t start_task_handler;
void start_task( void * pvParameters );/* TASK1 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK1_PRIO 2
#define TASK1_STACK_SIZE 128
TaskHandle_t task1_handler;
void task1( void * pvParameters );/* TASK2 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define TASK2_PRIO 2
#define TASK2_STACK_SIZE 128
TaskHandle_t task2_handler;
void task2( void * pvParameters );
/******************************************************************************************************//*** @brief FreeRTOS例程入口函数* @param 无* @retval 无*/
void freertos_demo(void)
{ xTaskCreate((TaskFunction_t ) start_task,(char * ) "start_task",(configSTACK_DEPTH_TYPE ) START_TASK_STACK_SIZE,(void * ) NULL,(UBaseType_t ) START_TASK_PRIO,(TaskHandle_t * ) &start_task_handler );vTaskStartScheduler();
}void start_task( void * pvParameters )
{taskENTER_CRITICAL(); /*进入临界区*/xTaskCreate((TaskFunction_t ) task1,(char * ) "task1",(configSTACK_DEPTH_TYPE ) TASK1_STACK_SIZE,(void * ) NULL,(UBaseType_t ) TASK1_PRIO,(TaskHandle_t * ) &task1_handler );xTaskCreate((TaskFunction_t ) task2,(char * ) "task2",(configSTACK_DEPTH_TYPE ) TASK2_STACK_SIZE,(void * ) NULL,(UBaseType_t ) TASK2_PRIO,(TaskHandle_t * ) &task2_handler );vTaskDelete(NULL);taskEXIT_CRITICAL(); /*退出临界区*/
}/* 任务1,实现LED0每500ms闪烁一次,用来提示系统正在运行 */
void task1( void * pvParameters )
{uint32_t task1_num=0;while(1){taskENTER_CRITICAL(); /*进入临界区*/printf("task1运行次数:%d\r\n",++task1_num);taskEXIT_CRITICAL(); /*退出临界区*/delay_ms(10);}
}
/* 任务2,调用列表和列表项相关API函数,并且通过串口输出相应的信息,进行观察 */
void task2( void * pvParameters )
{uint32_t task2_num=0;while(1){taskENTER_CRITICAL(); /*进入临界区*/printf("task2运行次数:%d\r\n",++task2_num);taskEXIT_CRITICAL(); /*退出临界区*/delay_ms(10);}
}
实验现象:
首先会运行4次Task1,然后运行4次Task2,如此循环。在运行过程中可能会运行5次,是大于1ms但是并没有大多少,执行第5次时可能只执行了一部分,下次继续执行,即可完成运行5次。如果将Task2的任务优先级设置为3,则Task2会一直存在于运行列表,并不会让Task1执行,因为程序中使用的是死延时并不能使Task2挂载到阻塞列表,启动任务调度器。
【09】FreeRTOS的时间片调度相关推荐
- FreeRTOS实时操作系统(七)时间片调度及RTOS的滴答定时器
系列文章目录 FreeRTOS实时操作系统(一)RTOS的基本概念 FreeRTOS实时操作系统(二)任务创建与任务删除(HAL库) FreeRTOS实时操作系统(三)任务挂起与恢复 FreeRTOS ...
- RTOS学习笔记--时间片调度
RTOS学习笔记–时间片调度 本文基于正点原子RTOS开发指南,笔记自用,获取详细信息请关注正点原子官方账号 介绍:在RTOS中,除了按优先级调度之外,还可以按照时间片调度,也就是给每个任务分配一个时 ...
- 11_FreeRTOS时间片调度实验
目录 时间片调度简介 时间片调度实验 时间片调度简介 同等优先级任务轮流地享有相同的CPU时间(可设置),叫时间片,在FreeRTOS中,一个时间片就等于SysTick中断周期 运行条件: 1.创建三 ...
- ucos 时钟节拍_uC/OS-III 时钟节拍,时间管理,时间片调度
时钟节拍 时钟节拍可谓是 uC/OS 操作系统的心脏,它若不跳动,整个系统都将会瘫痪. 时钟节拍就是操作系统的时基,操作系统要实现时间上的管理,必须依赖于时基. 时钟节拍就是系统以固定的频率产生中断( ...
- 正点原子FreeRTOS(上)
更多干货推荐可以去牛客网看看,他们现在的IT题库内容很丰富,属于国内做的很好的了,而且是课程+刷题+面经+求职+讨论区分享,一站式求职学习网站,最最最重要的里面的资源全部免费!!!点击进入------ ...
- FreeRTOS内核实现07(完):支持时间片
目录 1. 时间片概念与测试 1.1 时间片概念 1.2 时间片实现原理 1.2.1 taskSELECT_HIGHEST_PRIORITY_TASK宏 1.2.2 taskRESET_READY_P ...
- freeRTOSConfig.h文件对FreeRTOS进行系统配置
FreeRTOS内核是高度可定制的,使用配置文件FreeRTOSConfig.h进行定制.每个FreeRTOS应用都必须包含这个头文件,用户根据实际应用来裁剪定制FreeRTOS内核.这个配置文件是针 ...
- FreeRTOS 任务优先级分配方案
任务优先级说明 下面对 FreeRTOS 优先级相关的几个重要知识点进行下说明,这些知识点在以后的使用中务必要掌握牢固. FreeRTOS 中任务的最高优先级是通过 FreeRTOSConfig. ...
- FreeRtos学习笔记(11)查找就绪任务中优先级最高任务原理刨析
FreeRtos学习笔记(11)查找就绪任务中优先级最高任务原理刨析 怎么查找就绪任务中优先级最高的? tasks.c中声明了一个全局变量 uxTopReadyPriority,任务从其他状态进入就绪 ...
最新文章
- 管理员账户遇到“操作需要管理员权限”解决方法
- Java程序员该如何学习才能成长为一名优秀的架构师
- 跑代码时出错:tensorflow.python.framework.errors_impl.UnknownError: 2 root error(s) found. (0) Unknown……
- 雅虎借道阿里巴巴意在控股淘宝
- php重写mysql类_如何成功重写旧的mysql-php代码与已弃用的mysql_ *函数?
- CMS并发清理阶段为什么是安全的
- Exp9 Web安全基础 20164302 王一帆
- 【视频】2017,50个令人屏息的科技瞬间
- JKS 密钥库使用专用格式。建议使用 “xxx“ 迁移到行业标准格式 PKCS12
- OpenCV切割大图(边界扩充,全黑图剔除)
- Matlab plotyy画2个纵坐标不同的图
- 大数据管理平台(一)概述
- 维天运通冲刺港股:9个月经调整利润降56% 蚂蚁集团是股东
- 游戏小程序源码 一起来找茬
- win10任务栏透明_电脑任务栏美化amp;状态监测软件,在任务栏实时显示网速/CPU/内存/温度等信息...
- SharePoint Silverlight Clock 时钟
- autojs某音霓虹特效
- Altium Designer 总体设计流程
- 晶闸管有很多种,最开始发明的是可控硅整流管
- Python基于密度的聚类
热门文章
- Java数据类型问题
- 【中序、后序遍历序列】【前序、中序遍历序列】构造二叉树
- 聆思CSK6开发工具使用详解(支持Zephyr开发)
- PyTorch搭建卷积神经网络(CNN)进行视频行为识别(附源码和数据集)
- PostgreSQL 30天 培训视频(SQL基础,备份恢复,HA,服务端编程,大数据,内核,应用案例)
- 《Microduino实战》——2.3 Microduino STM32核心系列
- 微信小程序五(创建轮播图)
- VS中报错C4996 怎么办?
- Android使用VideoView播放网络视频
- python乱码系列1