时间片调度简介(熟悉)
在FreeRTOS中,同等优先级的任务会轮流分享相同的CPU时间,这个时间被称为时间片。在这里,一个时间片的长度等同于SysTick中断的周期。
时间片调度实验演示(掌握)实验目标
理解FreeRTOS的时间片调度:
- start_task:用来创建其他的2个任务。
- task1:通过串口打印task1的运行次数,设置任务优先级为2。
- task2:通过串口打印task2的运行次数,设置任务优先级为2。
为了更好观察现象,滴答定时器的中断频率设置为50ms中断一次(一个时间片)。
- FreeRTOSConfig.h代码清单
#define configUSE_TIME_SLICING 1
#define configUSE_PREEMPTION 1
#define configTICK_RATE_HZ ( ( TickType_t ) 20 )
- freertos_demo.c代码清单任务配置
#include "freertos_demo.h"
/* freertos相关的头文件,必须的 */
#include "FreeRTOS.h"
#include "task.h"
/* 需要用到的其他头文件 */
#include "LED.h"
#include "Key.h"
/* 启动任务的配置 */
#define START_TASK_STACK 128
#define START_TASK_PRIORITY 1
TaskHandle_t start_task_handle;
void start_task(void *pvParameters);
/* 任务1的配置 */
#define TASK1_STACK 128
#define TASK1_PRIORITY 2
TaskHandle_t task1_handle;
void task1(void *pvParameters);
/* 任务2的配置 */
#define TASK2_STACK 128
#define TASK2_PRIORITY 2
TaskHandle_t task2_handle;
void task2(void *pvParameters);
/**
* @description: 启动FreeRTOS
* @return {*}
*/
void freertos_start(void)
{
/* 1.创建一个启动任务 */
xTaskCreate((TaskFunction_t)start_task, // 任务函数的地址
(char *)"start_task", // 任务名字符串
(configSTACK_DEPTH_TYPE)START_TASK_STACK, // 任务栈大小,默认最小128,单位4字节
(void *)NULL, // 传递给任务的参数
(UBaseType_t)START_TASK_PRIORITY, // 任务的优先级
(TaskHandle_t *)&start_task_handle); // 任务句柄的地址
/* 2.启动调度器:会自动创建空闲任务 */
vTaskStartScheduler();
}
/**
* @description: 启动任务:用来创建其他Task
* @param {void} *pvParameters
* @return {*}
*/
void start_task(void *pvParameters)
{
/* 进入临界区:保护临界区里的代码不会被打断 */
taskENTER_CRITICAL();
/* 创建3个任务 */
xTaskCreate((TaskFunction_t)task1,
(char *)"task1",
(configSTACK_DEPTH_TYPE)TASK1_STACK,
(void *)NULL,
(UBaseType_t)TASK1_PRIORITY,
(TaskHandle_t *)&task1_handle);
xTaskCreate((TaskFunction_t)task2,
(char *)"task2",
(configSTACK_DEPTH_TYPE)TASK2_STACK,
(void *)NULL,
(UBaseType_t)TASK2_PRIORITY,
(TaskHandle_t *)&task2_handle);
/* 启动任务只需要执行一次即可,用完就删除自己 */
vTaskDelete(NULL);
/* 退出临界区 */
taskEXIT_CRITICAL();
}
/**
* @description: 任务一:实现LED1每500ms闪烁一次
* @param {void} *pvParameters
* @return {*}
*/
void task1(void *pvParameters)
{
uint16_t task1_count = 0;
while (1)
{
taskENTER_CRITICAL();
printf("task1运行[%d]次...\r\n", ++task1_count);
// vTaskDelay(500); //为了观察时间片调度,不使用freertos的延时函数
HAL_Delay(10); // 使用该延时的前提:HAL时钟修改成其他定时器,并且中断优先级较高
taskEXIT_CRITICAL();
}
}
/**
* @description: 任务二:实现LED2每500ms闪烁一次
* @param {void} *pvParameters
* @return {*}
*/
void task2(void *pvParameters)
{
uint16_t task2_count = 0;
while (1)
{
taskENTER_CRITICAL();
printf("task2运行[%d]次...\r\n", ++task2_count);
// vTaskDelay(500); //为了观察时间片调度,不使用freertos的延时函数
HAL_Delay(10); // 使用该延时的前提:HAL时钟修改成其他定时器,并且中断优先级较高
taskEXIT_CRITICAL();
}
}

Comments NOTHING