四,FreeRTOS之——任务调度

FreeRTOS任务调度

在这里插入图片描述
在freeRTOS中任务分为四种状态,就绪态,运行态,阻塞态,停止态。

转:FreeRTOS任务几种状态

转:FreeRTOS任务几种状态

我的理解:
运行态:当前正在运行的任务
就绪态:正在排队的任务
阻塞态:睡觉的任务
停止态:离线的任务

任务的删除

把任务看成一个人,这个人可以去杀人,可以自杀,也可能被别人杀。
换做任务,我们可以自杀杀别人,被别人杀

实验一:

创建三个任务函数,这是最高优先级的任务,我们放了vTaskDelay函数,低优先级的任务可以执行,在这个任务中计数,计数到一定时间来删除自己,在这个实验中,我加大了轮转调度的时间,可以把串口的数据打印完整

在这里插入图片描述
逻辑分析仪中可以看到任务1运行一段时间后就把自己删除了
在这里插入图片描述
这里的仿真来看,在调用任务删除函数后,就不能执行该任务了,只有剩下来的两个任务参与cpu调度
在这里插入图片描述
串口打印显示临死前说了一句话
在这里插入图片描述

实验二:

这个实验为同优先级下三个任务,
任务二三正常执行,看看任务1,任务一运行了一段时间之后就开始删除task2任务,删除了task任务后就自杀了
在这里插入图片描述
逻辑分析仪中表示为在执行某一段时间之后,任务一删除了任务二,任务二,任务二不再运行,再自杀,任务一也不再运行,最后只剩下最后一个任务独享cpu资源,体现为Task3一直处于高平

在这里插入图片描述

串口:开始杀人后接着自杀,就只剩下任务3运行了
在这里插入图片描述
对于任务一来说,他是在杀别人任务,对于任务二来说,他是被别的任务杀了(ε=(´ο`*)))唉,真可怜)

突然想到一种,低优先级能杀高优先级么,说干就干

实验三:

任务1,2,3的优先级分别为232,任务1杀了任务2之后自杀
实验结果逻辑分析仪中如下:结论,低优先级可以杀高优先级

在这里插入图片描述

任务的挂起与恢复

实验四:

同优先级下的三个任务,第一个任务反复挂起和恢复任务三
在这里插入图片描述

以上实验可以看出,任务三在被不断的挂起与恢复
在这里插入图片描述

任务删除总结总结:一个任务可以自杀,杀别人,被别人杀,任务的删除可以调用自己的任务句柄,也可以传输参数NULL(仅限自杀,自杀可以多一种选择,哈哈),低优先级的任务可以杀高优先级的任务

任务的挂起与恢复总结:任务的挂起与恢复,任务挂起同任务删除一样,任务可以挂起自己,也可以挂起别人,也可以被别人挂起,任务的恢复只能由别人来恢复,被挂起的任务不参与调度

上一节知识点扩充

同优先级下为什么是后创建的任务先运行,我们来看看三个同优先级的任务运行情况
在上一节的实验一中,串口会先打印LED2……来看一下这是为什么
在这里插入图片描述

实验五:

我创建了三个任务,但是根据时间片轮转的大小不同,运行的先后顺序也不同,这能有什么关系???任务运行的先后顺序到底是由什么来决定??

这个不同会影响运行先后顺序,有待验证
在这里插入图片描述
查阅资料验证如下:
在 FreeRTOS 中,如果有多个同优先级的任务,它们的运行顺序是不确定的,由系统的任务调度器决定。但是,在实际应用中,我们可能需要确保某些任务先于其他任务执行,或者让任务按照一定的顺序依次执行。这时,可以通过任务通知(task notification)或者信号量(Semaphore)等机制来实现

以任务通知为例,可以在任务中使用 ulTaskNotifyTake() 函数等待通知事件,然后使用 xTaskNotify() 函数向其他任务发送通知。在创建任务时,可以使用 xTaskCreate() 函数的 pvTaskCode 参数指定任务函数,然后在任务函数中使用任务通知来实现任务之间的同步和协作。

假设我们要创建三个同优先级的任务 A、B、C,按照顺序依次执行,可以按照以下步骤进行设置:
实现如下

在任务创建时,使用 xTaskCreate() 函数设置任务优先级和任务函数,例如:
xTaskCreate(TaskA, "TaskA", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
xTaskCreate(TaskB, "TaskB", configMINIMAL_STACK_SIZE, NULL, 2, NULL);
xTaskCreate(TaskC, "TaskC", configMINIMAL_STACK_SIZE, NULL, 2, NULL);

其中,优先级设置为 2,表示这三个任务具有相同的优先级。

在任务函数中使用任务通知来实现任务之间的同步和协作。例如,任务 A 在执行完任务内容后
向任务 B 发送通知,任务 B 在接收到通知后再向任务 C 发送通知,以此类推。

void TaskA(void *pvParameters)
{
    // 执行任务 A 的代码

    // 向任务 B 发送通知
    xTaskNotifyGive(TaskB);
    vTaskSuspend(NULL); // 挂起任务 A
}

void TaskB(void *pvParameters)
{
    // 等待任务 A 的通知
    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

    // 执行任务 B 的代码

    // 向任务 C 发送通知
    xTaskNotifyGive(TaskC);
    vTaskSuspend(NULL); // 挂起任务 B
}

void TaskC(void *pvParameters)
{
    // 等待任务 B 的通知
    ulTaskNotifyTake(pdTRUE, portMAX_DELAY);

    // 执行任务 C 的代码

    vTaskSuspend(NULL); // 挂起任务 C
}

在上面的代码中,任务 A 在执行完任务内容后向任务 B 发送通知,然后挂起自己等待任务 B 的通知;
任务 B 在接收到任务 A 的通知后执行自己的任务内容,然后向任务 C 发送通知,挂起自己等待任务 C 的通知;
任务 C 在接收到任务 B 的通知后执行自己的任务内容,然后挂起自己。这样,任务 A、B、C 就可以按照顺序依次执行

git仓库源码地址:https://gitee.com/he-dejiang/free-rtos.git

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值