一、时间片调度简介
- 同等优先级任务轮流的享有相同的CPU时间(可设置),叫时间片,在FreeRTOS中,一个时间片就等于SysTick中断周期,所以说时间片大小取决于滴答定时器中断频率
- 运行完Task1一个时间片后,切换到Task2,Task2运行完一个时间片后,切换到Task3运行
- 假设Task3运行到一半时,Task3被阻塞(系统延时或等待信号量等)了,此时直接切换到Task1
二、时间片调度实验
- 实验设计:三个任务:start_task、task1、task2,其中task1和task2优先级相同均为2。为了使得现象明显,将抵达定时器的中断频率设置为50ms一次,即一个时间片50ms
- 注意辨别FreeRTOS自带延时函数和系统延时函数的区别,使用FreeRTOS延时函数时,会阻塞任务,从而直接运行下一任务,系统延时函数会直接等待结束
#define configUSE_TIME_SLICING 1
#define configUSE_PREEMPTION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTICK_RATE_HZ 20
#define START_TASK_STACK_SIZE 128
#define START_TASK_PRIO 1
TaskHandle_t start_task_handle;
#define TASK1_STACK_SIZE 128
#define TASK1_PRIO 2
TaskHandle_t task1_handle;
#define TASK2_STACK_SIZE 128
#define TASK2_PRIO 2
TaskHandle_t task2_handle;
void task1( void * pvParameters )
{
uint32_t task1_num = 0;
while(1)
{
taskENTER_CRITICAL();
printf("%d\r\n",++task1_num);
delay_ms(10);
taskEXIT_CRITICAL();
}
}
void task2( void * pvParameters )
{
uint32_t task2_num = 0;
while(1)
{
taskENTER_CRITICAL();
printf("%d\r\n",++task2_num);
delay_ms(10);
taskEXIT_CRITICAL();
}
}
void Start_task( void * pvParameters )
{
taskENTER_CRITICAL();
xTaskCreate(task1,
"task1",
TASK1_STACK_SIZE,
NULL,
TASK1_PRIO,
&task1_handle
);
xTaskCreate(task2,
"task2",
TASK2_STACK_SIZE,
NULL,
TASK2_PRIO,
&task2_handle
);
vTaskDelete(start_task_handle);
taskEXIT_CRITICAL();
}
void freertos_demo()
{
xTaskCreate(Start_task,
"Start_task",
START_TASK_STACK_SIZE,
NULL,
START_TASK_PRIO,
&start_task_handle
);
vTaskStartScheduler();
}