高优先级任务是如何立即抢占低优先级任务的?不要用GPT水,最好有代码讲解
高优先级任务抢占低优先级任务的时间片是要通过os的task调度来实现的,也不是严格的立即,被切换的低优先级任务还是要有个保存现场的过程的。每次调度时,os 调度器就会选择当前最高优先级的任务运行,相当于抢占了低优先级任务的时间。
函数uxTaskGetStackHighWaterMark (TaskHandle_t xTask)
,可返回自任务运行以来剩余可用堆栈空间的最小值,即任务运行过程中堆栈最大使用量时还剩余多少空间
#define INCLUDE_uxTaskGetStackHighWaterMark 1
你好,你的这个需求是可以设计实验来观察到,任务代码如下:
#include "test_task.h"
#include "main.h"
osThreadId TaskAHandle;
osThreadId TaskBHandle;
void StartTaskA(void const * argument)
{
while (1) {
printf("TaskA is running\r\n");
vTaskDelay(1000 / portTICK_PERIOD_MS); // 延迟1s
}
}
void StartTaskB(void const * argument)
{
while (1) {
printf("TaskB is running\r\n");
vTaskDelay(2000 / portTICK_PERIOD_MS); // 延迟2s
}
}
void InitTestTask(void)
{
osThreadDef(TaskA, StartTaskA, osPriorityAboveNormal, 0, 128); // 任务A 稍低的优先级
TaskAHandle = osThreadCreate(osThread(TaskA), NULL);
osThreadDef(TaskB, StartTaskB, osPriorityHigh, 0, 128); // 任务B 稍高的优先级
TaskBHandle = osThreadCreate(osThread(TaskB), NULL);
}
每当任务A打印2条信息后,任务B就会打印1条信息,然后再回到任务A。这说明任务A被任务B打断了。从而验证了高优先级任务可以立即抢占低优先级任务
以下回答参考GPT,并由JoseKe整理完成,希望您能采纳:c
void vTask1(void *pvParameters)
{
char *pcTaskName = "Task 1 is running
";
volatile uint32_t ul;
for( ;; )
{
/* 模拟任务1在执行 */
for(ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
{
/* 用来进行延时 */
}
/* 任务1是高优先级任务,每次打印前必须先确认是否抢占了任务2 */
if(!eTaskGetState(xTask2))
{
vTaskSuspend(xTask2); /* 挂起任务2 */
printf("Task 1 is running, and has preempted Task 2
");
}
/* 执行任务1的操作 */
printf(pcTaskName);
/* 任务1执行结束,如果任务2被挂起了,必须先唤醒任务2才能结束挂起 */
if(eTaskGetState(xTask2) == eSuspended)
{
vTaskResume(xTask2);
}
}
}
void vTask2(void *pvParameters)
{
char *pcTaskName = "Task 2 is running
";
volatile uint32_t ul;
for( ;; )
{
/* 模拟任务2在执行 */
for(ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ )
{
/* 用来进行延时 */
}
/* 任务2是低优先级任务 */
printf(pcTaskName);
}
}
int main()
{
xTaskCreate( vTask1, "Task 1", 240, NULL, 3, &xTask1 );
xTaskCreate( vTask2, "Task 2", 240, NULL, 2, &xTask2 );
vTaskStartScheduler();
return 0;
}
```c
freertos是事件片调度的,整个程序运行的时间被切割成许多很小的时间片,所以你说的立刻并不准确,
只是在下一个事件片中,低优先级任务被高优先级任务抢占,而一个时间片很短,感觉像是立刻。
关于事件片,你可以理解为时基单元,程序是一个时基跟着一个时基运行,
每一个事件片的开始调度器会进行任务调度,选择当前就绪的任务中优先级最高的任务;
想要最简单的了解时间片,可以再freertos配置中开启同优先级任务交替运行的宏,
然后创建两个优先级相同的任务,通过打印或其他形式观察两任务的运行机制
两任务会在在时间片1运行任务1,时间片2运行任务2,时间片3运行任务1,以此往复
```