【复习笔记】FreeRTOS(五)时间片调度

本文是FreeRTOS复习笔记的第五节,时间片调度。


1.时间片调度简介

FreeRTOS支持多个任务同时拥有一个优先级,这些任务的调度就可以使用时间片来进行调度。在FreeRTOS中允许一个任务允许一个时间片(一个时钟节拍的长度)后让出CPU的使用权,让拥有同优先级的下个任务运行。
同等优先级任务轮流地享有相同的 CPU 时间(可设置), 叫时间片。在FreeRTOS中,一个时间片就等于SysTick 中断周期,这个SysTick中断周期可以自己设置。在SysTick中断服务函数中,一个时间片就是1ms。
在这里插入图片描述

1.1. 运行过程

1、首先Task1运行完一个时间片后,切换至Task2运行,不管Task1是否运行完成,只运行一个时间片(默认1ms)Task1
2、Task2运行完一个时间片后,切换至Task3运行
3、Task3运行过程中(还不到一个时间片),Task3阻塞了(系统延时或等待信号量等,下次轮到Task3时还是只允许一个时间片,上次阻塞剩余的时间片,不会再被补回来),此时直接切换到下一个任务Task1
4、Task1运行完一个时间片后,切换至Task2运行

二、实验设计

实验目的:学会对FreeRTOS 时间片调度使用
实验设计:设计两个任务: task1 task 和 task2 task ,其中 task1 task 和 task2 task的任务优先级相同,都为 2,这两个任务的任务功能如下:

  • task1 task :控制 LED灯闪烁,并且通过串口打印 taskl task 的运行次数
  • task2 task :通过串口打印 task2 task 的运行次数

三、测试例程

主函数 main.c代码如下:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"

//在FreeRTOSConfig.h 把configTICK_RATE_HZ改成20,也就是每50ms切换一次任务
void task1_task(void *p); //任务函数
void task2_task(void *p); //任务函数

int main(void)
{ 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
	delay_init(168);		//初始化延时函数
	uart_init(115200);     	//初始化串口
	LED_Init();		        //初始化LED端口

   
    xTaskCreate(task1_task,"task1_task",128,NULL,2,NULL); //任务1        
    xTaskCreate(task2_task,"task2_task",128,NULL,2,NULL);  //任务2 
				
    vTaskStartScheduler();          //开启任务调度
}
 

//任务1函数 
void task1_task(void *p)
{
	u8 task1_num=0;
	while(1)
	{
		task1_num++;					//任务1执行次数加1 注意task1_num1加到255的时候会清零!!
		LED0=!LED0;
		taskENTER_CRITICAL();           //进入临界区,如果不加临界区,任务执行一半就会跳出
		printf("任务1已经执行:%d次\r\n",task1_num);
		taskEXIT_CRITICAL();            //退出临界区
		delay_xms(10);					//延时10ms,模拟任务运行10ms,此函数不会引起任务调度
	}
}   

//任务2函数 
void task2_task(void *p)
{
	u8 task2_num=0;
	while(1)
	{
		task2_num++;					//任务2执行次数加1 注意task2_num1加到255的时候会清零!!
		taskENTER_CRITICAL();           //进入临界区
		printf("任务2已经执行:%d次\r\n",task2_num);
		taskEXIT_CRITICAL();            //退出临界区
		delay_xms(10);					//延时10ms,模拟任务运行10ms,此函数不会引起任务调度
	}
}

在任务程序的printf函数前后分别添加临界区进入和退出目的是:防止prinf打印到一半字符,就被暂停,切换到了另一个任务。临界区包护可以让prinf执行完再切换任务。

此外,还要在在FreeRTOSConfig.h 把configTICK_RATE_HZ把原来的1000改成20,也就是每50ms切换一次任务。

#define configTICK_RATE_HZ	(20) //时钟节拍频率,这里设置为20,周期就是50ms

调用函数 delay_xms()延时 10ms。在一个时间片内如果任务不主动放弃 CPU 使用权的话那么就会一直运行这一个任务,直到时间片耗尽。在 task1_task 任务中我们通过串口打印字符串的方式提示 task1_task 在运行,但是这个过程对于 CPU 来说执行速度很快,不利于观察,所以这里通过调用函数 delay_xms()来默认任务占用 10ms 的 CPU。函数 delay_xms()不会引起务调度,这样的话相当于 task1 task 的执行周期>10s,基本可以看作等于 10ms,因为其他的函数执行速度还是很快的。一个时间片的长度是50ms,任务执行所需的时间以 10ms 算,理论上在一个时间片内 task1_task 可以执行 5 次,但是事实上很少能执行 5 次,基本上是4次。

四、实验效果

实验效果如下:
在这里插入图片描述
接上串口,会打印任务1和任务2的运行次数。
我们设置任务运行周期是50ms,然后每个任务里面有10ms的延时,由于单片机执行printf打印函数时间会长一些,任务1里还有LED控制的函数,所以,每次执行本任务最多只能打印5次数据。有时执行了4次printf,还没来得及执行第5次,但50ms时间到了就会强制切换到了另一个任务。

本节主要是学习和掌握FreeRTOS的时间片调度。
完整程序放在gitee仓库上:程序下载

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值