1.时间片调度简介
概念:同等优先级任务轮流地享有相同的 CPU 时间(可设置), 叫时间片,在FreeRTOS中,一个时间片就等于SysTick 中断周期
2.时间片调度实战
实验设计:将设计三个任务:start_task、task1、task2,其中task1和task2优先级相同均为2。为了使现象明显,将滴答定时器的中断频率设置为50ms中断一次,即一个时间片50ms。
注意:使用时间片调度需把宏 configUSE_TIME_SLICING 和 configUSE_PREEMPTION 置1,定义时钟节拍configTICK_RATE_HZ置 20
2.1 freertos_demo.h
#ifndef __FREERTOS_DEMO_H
#define __FREERTOS_DEMO_H
void freertos_demo(void);
#endif
2.2 freertos_demo.c
#include "freertos_demo.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/USART/usart.h"
#include "./BSP/LCD/lcd.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
//1.freeRTOS配置(句柄、任务优先级、堆栈大小、任务函数)
//1.1 start_task(句柄、任务优先级、堆栈大小、任务函数)
#define START_TASK_PRIO 1 /* 任务优先级 */
#define START_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t start_task_handler; /* 任务句柄 */
void start_task(void *pvParameters); /* 任务函数 */
//1.2 task1(句柄、任务优先级、堆栈大小、任务函数)
#define TASK1_PRIO 2 /* 任务优先级 */
#define TASK1_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t task1_handler; /* 任务句柄 */
void task1(void *pvParameters); /* 任务函数 */
//1.3 task2(句柄、任务优先级、堆栈大小、任务函数)
#define TASK2_PRIO 2 /* 任务优先级 */
#define TASK2_STK_SIZE 128 /* 任务堆栈大小 */
TaskHandle_t task2_handler; /* 任务句柄 */
void task2(void *pvParameters); /* 任务函数 */
//2 free_demo函数中创建start_task函数
void freertos_demo(void)
{
xTaskCreate((TaskFunction_t )start_task, /* 任务函数 */
(const char* )"start_task", /* 任务名称 */
(uint16_t )TASK1_STK_SIZE, /* 任务堆栈大小 */
(void* )NULL, /* 传入给任务函数的参数 */
(UBaseType_t )START_TASK_PRIO, /* 任务优先级 */
(TaskHandle_t* )&start_task_handler); /* 任务句柄 */
vTaskStartScheduler();
}
//3 start_task函数中创建task1、task2函数
void start_task(void *pvParameters)
{
taskENTER_CRITICAL();
//创建task1
xTaskCreate((TaskFunction_t ) task1, /* 任务函数 */
(const char* ) "task1", /* 任务名称 */
(uint16_t ) TASK1_STK_SIZE, /* 任务堆栈大小 */
(void* ) NULL, /* 传入给任务函数的参数 */
(UBaseType_t ) TASK1_PRIO, /* 任务优先级 */
(TaskHandle_t* ) &task1_handler); /* 任务句柄 */
//创建task2
xTaskCreate((TaskFunction_t ) task2, /* 任务函数 */
(const char* ) "task2", /* 任务名称 */
(uint16_t ) TASK2_STK_SIZE, /* 任务堆栈大小 */
(void* ) NULL, /* 传入给任务函数的参数 */
(UBaseType_t ) TASK2_PRIO, /* 任务优先级 */
(TaskHandle_t* ) &task2_handler); /* 任务句柄 */
vTaskDelete(start_task_handler);
taskEXIT_CRITICAL();
}
//4 task1实现函数task1打印
void task1(void *pvParameters)
{
uint32_t task1_num=0;
while(1)
{
taskENTER_CRITICAL();
printf("task1运行次数:%d\r\n",++task1_num);
taskENTER_CRITICAL();
delay_ms(10);
}
}
//5 task2实现函数task1打印
void task2(void *pvParameters)
{
uint32_t task2_num = 0;
while(1)
{
taskENTER_CRITICAL();
printf("task2运行次数:%d\r\n",++task2_num);
taskENTER_CRITICAL();
delay_ms(10);
}
}