freeRTOS中Task学习笔记

下文为学习韦东山老师《FreeRTOS入门与工程实践-基于STM32F103》的课程学习思考,仅纪录自己的阶段性学习成果。

创建任务


首先,假设我们现在要在裸机编程的基础上实现两个任务taskAtaskB并发运行,两个任务功能都是在lcd上显示一些数据,我们知道,为了让两块区域同时显示,调度器会周期性地分配给两个任务各自的运行时间(时间片轮转),那么势必会产生一个问题,切换的时机不是我们期望的时机(如在I2C数据传输过程中),这样会导致数据传输错误。为了解决这个问题,我们先考虑使用简单的全局变量互斥锁,从而实现当一个task跑完,全局变量完成翻转。然而当我们实验时,发现程序卡死在某一个任务,另一个任务一直不会运行,这是因为打印屏幕所需的时间长,任务切换的时间发概率就发生在这个阶段,也就是说全局变量翻转前,这个时候实现了任务切换,从而导致错误。知道这个原因后,我们可以添加一个延时函数,可以提高任务成功切换的概率。

创建任务

对于以上问题,我们提出两个问题:

问题一:怎么防止执行的任务被切换?

开启临界区

问题二:既然使用全局变量会带来这些问题,那么怎么实现任务间互斥的访问?

任务间互斥的访问,使用消息队列信号量

删除任务


当我们丢弃不使用的任务时,可以粗暴的删除任务,这会带来两个问题,

问题一:频繁的创建、删除产生的内存碎片如何解决?

针对这个问题,freeRTOS提供了专门的内存管理策略,一般使用heap.4策略

问题二:当任务删除后,堆栈的清理工作谁来负责完成?

当任务自我删除时,现场的清理工作由空闲函数来实现;当taskA由taskB删除时,那么taskB负责完成taskA的现场清理工作

任务状态


以下是任务状态切换的API函数

任务状态和调度

问题:任务阻塞和暂停的异同点?

首先任务阻塞和暂停都意味着放弃CPU资源,但是恢复方式不同,任务阻塞的恢复方式为被动恢复,需要等待其他事件(如信号量、消息队列等),而暂停是主动的,可由其他任务调用触发。

总结


以上内容比较零散,仅仅作为个人笔记记录,不适合分享交流。

作者

Shi Junduo

发布于

2025-01-06

更新于

2025-01-06

许可协议

评论