FreeRTOS(7):时间片管理函数

发布时间:2026/8/1 21:01:23
FreeRTOS(7):时间片管理函数 实验现象使用串口助手在串口助手下实现如下图所示笔者的延时函数好像有一点问题现象应该是task1打印4次后切换到task2打印4次如此循环但是笔者task1和2的打印次数都不对但也算勉强体现出了想要结果若有解决方法可以在评论区写出或者私信笔者。创建工程选择上一个实验的Freertos_列表项的插入与删除复制粘贴重命名为Freertos_时间片调度实验打开别的江协科技的项目选择System文件复制其中的Delay.c和Delay.h文件粘贴到Freertos_时间片调度实验的Hardware文件夹中。编写代码进入keil按照下图顺序添加Delay.c和Delay.h文件添加完成后进入Delay.c文件因为江协科技的Delay函数使用了滴答计时器来实现延时与FreeRTOS的冲突了所以我们要更改一下笔者使用的是TIM4定时器如果有别的可以实现该实验功能的方法可以在评论区或者私信笔者下方是我的delay函数的代码#include stm32f10x.h #define TIM_DELAY TIM4 #define TIM_DELAY_CLK 72000000 /* 72MHz */ static uint8_t tim_delay_initialized 0; static void TIM_Delay_Init(void) { if (tim_delay_initialized) return; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); TIM_TimeBaseInitTypeDef TIM_InitStruct; TIM_InitStruct.TIM_Prescaler (TIM_DELAY_CLK / 1000000) - 1; // 1 MHz TIM_InitStruct.TIM_Period 0xFFFF; TIM_InitStruct.TIM_ClockDivision TIM_CKD_DIV1; TIM_InitStruct.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM_DELAY, TIM_InitStruct); TIM_Cmd(TIM_DELAY, ENABLE); tim_delay_initialized 1; } void Delay_us(uint32_t xus) { if (xus 0) return; TIM_Delay_Init(); TIM_SetCounter(TIM_DELAY, 0); while (TIM_GetCounter(TIM_DELAY) xus); } void Delay_ms(uint32_t xms) { while (xms--) { Delay_us(1000); } } void Delay_s(uint32_t xs) { while (xs--) { Delay_ms(1000); } }然后需要将Timer.c 中的中断函数中的内容和函数头上队列句柄删除如不删除会发生报错删除内容如下图所示随后我们要去到FreeRTOSConfig.h文件中将下图所示的宏定义改为20hz既一个时间片的时间为50ms接下来就是修改FreeRTOS_Task函数中的内容首先删除上一个实验与这个实验无关的内容如列表参数task1函数内的内容task2函数内的内容等下方是修改后的FreeRTOS_Task的代码#include stm32f10x.h #include FreeRTOS.h #include task.h #include queue.h #include led.h #include key.h #include serial.h #include timer.h #include delay.h /* 任务参数 */ #define START_TASK_SIZE 128 #define START_TASK_PRIO 1 #define TASK1_SIZE 256 #define TASK1_PRIO 3 #define TASK2_SIZE 256 #define TASK2_PRIO 3 /* 任务句柄 */ TaskHandle_t start_task_handle; TaskHandle_t task1_handle; TaskHandle_t task2_handle; void Start_task(void *pvParameters); void task_1(void *pvParameters); void task_2(void *pvParameters); void FreeRTOS_Task(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); Key_Init(); LED_Init(); Serial_Init(); xTaskCreate((TaskFunction_t)Start_task, Start_task, START_TASK_SIZE, NULL, START_TASK_PRIO, start_task_handle); vTaskStartScheduler(); } void Start_task(void *pvParameters) { taskENTER_CRITICAL(); xTaskCreate((TaskFunction_t)task_1, task_1, TASK1_SIZE, NULL, TASK1_PRIO, task1_handle); xTaskCreate((TaskFunction_t)task_2, task_2, TASK2_SIZE, NULL, TASK2_PRIO, task2_handle); taskEXIT_CRITICAL(); vTaskDelete(NULL); } /* * task_1 在一个时间片内每隔 10ms 打印一次计数连续运行直至被切换 */ void task_1(void *pvParameters) { uint32_t Task1_Num 0; while (1) { taskENTER_CRITICAL(); Task1_Num; Serial_Sendstring(Task1_Num ); Serial_SendNum(Task1_Num, 5); Serial_Sendstring(\r\n); taskEXIT_CRITICAL(); Delay_ms(10); /* 轮询忙等 10ms不释放 CPU */ } } /* * task_2 在一个时间片内每隔 10ms 打印一次计数连续运行直至被切换 */ void task_2(void *pvParameters) { uint32_t Task2_Num 0; while (1) { taskENTER_CRITICAL(); Task2_Num; Serial_Sendstring(Task2_Num ); Serial_SendNum(Task2_Num, 5); Serial_Sendstring(\r\n); taskEXIT_CRITICAL(); Delay_ms(10); /* 轮询忙等 10ms不释放 CPU */ } }随后运行下载代码后就能在串口助手里看见现象了再说一次笔者的延时函数好像有一点问题现象有误若有解决方法可以私信或者在评论区内指出。