
ESP32 FreeRTOS-基础篇
文章平均质量分 88
杜绝碎片化,系统化学习 RTOS 编程。
基于 ESP32 学习双核 FreeRTOS 的使用。
包含任务管理、任务间同步与通信、中断、驱动与系统编程。大纲请参考 https://blog.csdn.net/wangyx1234/article/details/127201095
感谢订阅支持。
物联网老王
从事嵌入式、物联网开发工作。熟悉单片机、RTOS、Linux、物联网云平台、各种物联网通信协议。致力于成为全栈工程师、开源技术推广者。
欢迎打扰,欢迎订阅我的专栏。
展开
-
物联网应用选择 RTOS 还是 Linux?
Linux VS RTOS,我该选哪个?1)关于物联网应用选择 Linux(通用操作系统 GPOS) 还是 RTOS(实时操作系统 RTOS),首先是简单的答案:如果您有实时需求,您应该使用(顾名思义)RTOS。2)除此之外,一切都取决于您的实际要求(成本、功能)。这也实际上取决于开发人员习惯了什么。配置 Linux 可能非常具有挑战性,有时简单的 RTOS 会更容易。原创 2023-03-08 14:10:30 · 3404 阅读 · 0 评论 -
RTOS 系统篇-看门狗 WatchDog[不喂狗就咬你]
1)本节讲述了 RTOS 中的看门狗(Watchdog)机制。看门狗本质上是一个需要定时复位的定时器,用于确保部分任务\中断能正常得到执行。2)看门狗有中断看门狗、任务看门狗两种,他们的原理和机制类似,只是一个用于监控task 层面的CPU使用情况,一个是用于监控中断层面的 CPU 使用情况。3)默认情况下,负责任务切换的 SyStick 中断通常被加入到中断看门狗,idle task会被加入到任务看门狗。其他中断、任务也可以加入到看门狗,加入后需要及时喂狗(重置定时器)防止触发看门狗。原创 2023-02-14 21:02:58 · 1658 阅读 · 0 评论 -
RTOS 时间管理篇-软定时器 xTimer 处理周期性定时事件
1)FreeRTOS 提供的软件定时器支持单次模式和周期模式,周期模式的定时事件每隔一断时间就触发一次一段代码的执行。2)周期定时事件适合完成 状态定时再查询,定时状态切换的功能。3)软定时器 xTimer 精度与 系统时间节拍的精度、定时器任务的优先级、定时器回调函数的设计、创建的软定时器的数量相关。合理调整这些因素可以改善 xTimer 精度。原创 2022-12-19 20:49:47 · 442 阅读 · 0 评论 -
RTOS共享资源保护-通过临界区实现 RTOS 中任务之间共享资源的保护
1)临界区是为了避免并行访问共享资源导致非期望或者错误行为而保护对应资源的一种上锁-去锁机制。2)实现临界区的方法有很多,在大部分 RTOS 系统,通过关闭全局中断来实现临界区机制,ESP32 中也是如此。3)ESP32 是双核系统,因此对临界区的 API 添加了一个参数 mutex 来保证双核下的临界区工作正常。4)临界区可以保证临界区内的代码不被中断、任务打断。5)临界区有副作用,因此临界区内的代码应该尽可能短,并且不能包含任何延时或在阻塞。我们将在下节讲述影响更小的共享资源保护方法。原创 2022-11-09 08:00:00 · 1625 阅读 · 0 评论 -
RTOS 中 Task 之间资源共享示例
1)能够同时被两个以上的**并发程序(包括任务和中断)**使用的全局变量、外设、内存块等,称为共享资源。识别哪些部分是共享资源是很重要的,这是下述章节的起点。2)共享资源需要添加必要的措施保证其准确性、完整性。3)共享资源需要添加保护的底层原因是对共享资源的操作实际是分步骤完成的,并且 RTOS 支持中断、高优先级的任务抢占内核后优先运行。4)共享资源添加保护的核心思想是尽可能影响小的情况下,实现资源在一定时间的独占。原创 2022-11-06 19:23:36 · 3153 阅读 · 0 评论 -
FreeRTOS 任务间通信与同步总结
本章以 ESP32 为例子,主要介绍了 RTOS 系统中任务间通信与同步(数据传递)的机制。根据数据传递的目的,可以分为同步、消息通信两种。其中同步是指,消息通信是指。通信组件的演变是随着功能进行改善的。不管是同步、还是消息通信,我们总是以全局变量说起,依次介绍 RTOS 中如何根据不同的场景选择不同的通信组件。原创 2022-11-06 13:46:21 · 5006 阅读 · 2 评论 -
使用队列集进行传递数据或信号同步
1)允许将队列、信号量、ringbuf加入到队列集,通过队列集实现同时从多个通信组件接收信号或数据的目的。原创 2022-11-05 22:30:06 · 931 阅读 · 0 评论 -
使用 Ring Buffer 完成数据传递
1)Ring Buffer 提供了管理数据溢出的机制,当 Ring Buffer 的缓存区足够大时,数据写到缓冲区尾部后将自动从头部开始继续写。当 Ring Buffer 的缓冲区不够大时,即便存在数据溢出风险,但应用本身允许新数据覆盖旧数据的情况下使用 Ring Buffer 也非常合适。2)ESP-IDF 对 rIngbuf 的三种分类:No-Split buffers、Allow split buffers、Byte buffer。原创 2022-11-03 22:57:44 · 2895 阅读 · 0 评论 -
使用 message buffer 传递数据
1)队列 queue 处理固定大小的消息,通常是一个结构,但它也可以是一个包含指针的基类型。StreamBuffer 流缓冲区将消息作为字节流进行处理。消息将作为一个单元放入队列中,并且没有任何固定大小(只是它应该适合缓冲区的最大值),并且在取出时,可以以任意长度检索获取存入的数据。消息缓冲区保存具有固定大小的离散消息,但每条消息不必具有相同的大小,并且在取出时,消息的形式与存入时完全一致。2)MessageBuffer 与 StreamBuffer 一样,适用于 一个发送者、一个接收者的数据通信场景。原创 2022-11-03 08:00:00 · 1533 阅读 · 0 评论 -
使用 stream buffer 传递数据
Streambuffer 的中文含意是“流式缓冲区”,其特点可以概述如下:1)发送消息的一方(发送方)与获取消息的一方(接收方)之间可以按任意长度的字节流的方式进行数据传递。2)可以设置触发唤醒通知的字节数,仅在缓冲区中的数据达到一定长度时,才唤醒接收方接收数据。3)适用于仅有一个发送方、一个接收方的场景。如果有多个发送方、接收方,则需要在发送、接收处添加互斥保护,特别地,多个接收方时应将接收阻塞时间设置为0。原创 2022-11-02 22:24:59 · 1675 阅读 · 0 评论 -
使用消息队列 queue 实现数据通信
1)队列兼具数据传输,同步的两种功能。2)队列适合每次传输的数据长度固定的情况,并且可以应用在数据传输中有多个发送方、多个接收方的的场景。3)队列的不足之处是要求每次发送的条目的长度是一样的,并且没有实现自动完成多次发送触发单次接收的机制。4)大部分情况下,复杂的数控类型,队列传递的往往是指针类型。原创 2022-11-02 21:43:28 · 1652 阅读 · 0 评论 -
使用全局变量实现数据通信(传递)
1)本节主要引出 RTOS 任务间数据传递的议题,并指出全局变量在数据传递中的不足,在后续章节将介绍更多组件的特性。原创 2022-10-30 22:53:03 · 1354 阅读 · 0 评论 -
任务同步总结及环状同步造成的死锁
1)任务之间可以通信,通信的目的可以是同步执行流程或者传递数据。关于同步,可以通过全局变量、二值信号量、计数信号量、事件组、消息队列这些实现同步,它们的特点不同,在选择时应充分考虑同步的需求进行选择。2)任务同步可能因环路同步发生死锁。为避免死锁发生,可以通过在设计时进行充分分析进行避免,或者设计检测和恢复机制来处理这种可能的异常。原创 2022-10-30 21:52:12 · 621 阅读 · 0 评论 -
使用信号量实现简单双向同步
1)通过“双向同步”,可以协调生产者和消费者的供销关系来建立一个平衡的状态,避免同步信号丢失和被覆盖的情况。2)信号量只提供单向同步的功能,若需双向同步,可借助两个信号量来完成。3)信号量、事件组、队列均可以实现这种双向同步。其中,队列可以实现同步时附带数据、事件组可以实现多事件的双向同步。原创 2022-10-30 11:08:41 · 1136 阅读 · 0 评论 -
用邮箱实现多事件的单向同步
1)相比信号量、事件组。队列可以用于多任务的同步,并提供一定的消息缓存、说明消息详细信息的能力。2)队列的基本操作是:创建、发送(send)、接收(接收)。其中发送可以选择发送到队列后(正常排队),或者发送到队列前(直接成为下一个要被接收的消息)。3)队列读取通常采用的是先进先出(FIFO)模式,会先读取先存储在队列中的数据。也支持后进先出(LIFO)模式,那么读取的时候就会读取到后进队列的数据。4)队列提供的等待-通知机制,在同步多任务出现时,依据任务优先级、等待时间进行裁决分配。原创 2022-10-27 23:01:17 · 1670 阅读 · 0 评论 -
用事件组实现多事件的单向同步
1)事件组(EventGroup)提供了管理一组事件的能力,并且可以处理这些事件的逻辑关系。2)事件组可以用于多任务的同步,但没有提供对事件的计数和更多数据信息的能力。3)件组的操作主要是创建、设置bits、等待bits。原创 2022-10-26 22:56:20 · 1073 阅读 · 0 评论 -
使用计数信号量实现任务间单向同步
1)计数信号量是二值信号量的增强版,在计数范围上,由二值信号量的{0,1}范围,变为{0,非负数}。2)计数信号量适用于消费者(即接收信号量)的一方虽然不能保证下一次信号到来之前处理完本次信号对应的内容,但是总体上可以响应所有的信号而不会错过某次信号的场景,具备一定的处理信号积压的能力。3)计数信号量可以完成一对一、多对一、一对多的任务同步功能,还可以用于代表某种共享资源。原创 2022-10-25 21:44:31 · 1335 阅读 · 2 评论 -
使用二值信号量实现任务间单向同步
1)信号量看以看作功能更加高级的共享计数变量。其计数值代表发送的通知计数;并提供无通知时暂停任务运行,有通知时恢复任务运行的功能。2)信号量有三种操作:初始化、take操作、give操作。原创 2022-10-24 22:08:08 · 1741 阅读 · 0 评论 -
ESP32 RTOS 任务间同步与通信篇概述
ESP32 任务间通信与同步、消息传递概述1)RTOS 中提供了很多用于任务与任务之间、任务与中断之间交互信息的组件。通常更新数据的一方称为生产者、使用数据的一方称为消费者。2)交互信息的目的可以是同步、或者传递数据。2)全局变量(包括全局的 int 变量、数组、结构体、内存块)可以实现简单的信息交互,但没有实现超时检测、更新通知的机制。原创 2022-10-23 22:18:02 · 2497 阅读 · 0 评论 -
RTOS任务状态总结及查看 RTOS 任务的状态
1)任务可以分为几种状态:运行态、非运行态(包括就绪、阻塞(等待延时结束的阻塞和等待事件到来的阻塞)、挂起、删除)。,。作为入门,当前对 RTOS 中任务的相关介绍先写到这里,后续待介绍完更多的基础知识,将通过 任务-高级篇 介绍更多 RTOS 任务使用的知识和方法。原创 2022-10-18 23:44:17 · 3532 阅读 · 0 评论 -
获取 FreeRTOS 栈空间大小及其高水位线
1)通过和可以评估任务自创建以来的最小剩余栈空间的大小,其返回值以字节为单位。2)在任务创建时合理的分配栈空间大小对节省RAM 空间、保证任务运行的稳定性非常重要。3)系统自动创建的任务中,也要注意栈空间大小的限制,在系统 task 中的回调函数中不能添加过多代码,不要添加任何阻塞操作,慎用延时。4) 占用空间较大的变量,尽可能通过 malloc/calloc 等动态申请释放,以提高栈空间利用率。原创 2022-10-18 23:30:06 · 3729 阅读 · 0 评论 -
FreeRTOS 任务通知浅析
1)FreeRTOS 提供了任务间传递信息的机制。任务可以等待一个通知信息进入阻塞状态,并在通知信息到来时自动解除阻塞,进入运行的状态。2)任务通知是实现任务之间消息传递的机制之一,每个任务在创建时都自动地包含一个用来记录当前通知值的 uint32_t 类型的 NotifiedValue,以及一个 记录当前任务通知状态的 uint8_t 类型的 NotifyState。任务之间可以通过更改、查询 NotifiedValue 传递消息。原创 2022-10-16 21:55:05 · 1698 阅读 · 0 评论 -
浅析 FreeRTOS SysTick 和任务延时
FreeRTOS 提供的最小时间单元为一个 SysTick,举例:假设配置 RTOS 的 SysTick 为 100Hz,则 RTOS 能提供的最小时间单位为 1/100 s,即 10ms. 即一个 RTOS 的系统始终为 10ms.上述示例计算code()共消耗了多少个 SysTick,假设当前的 SysTick 为 上述的 100Hz,当前消耗了 10个 SysTick,则实际消耗时间为 10* 10ms = 100ms.将 10 SysTick 转为 ms 单位,使用即可。原创 2022-10-14 00:00:51 · 6070 阅读 · 1 评论 -
FreeRTOS 删除任务
1)任务删除主要是两种情况:自删除、强制删除。2)删除任务后若要立即分配资源,应当稍作延时,给予 idle task 一些回收资源的时间。否则可能不能更好的分配资源,也可能加重资源碎片的风险。3)删除任务需要考虑资源回收、共享资源、消息通信相关的处理问题。4)ESP32 是双核系统,应避免对当前正在另一个内核上运行的任务调用vTaskDelete()。原创 2022-10-12 23:06:36 · 7171 阅读 · 0 评论 -
RTOS 暂停任务-任务挂起与恢复
1)当对一个任务调用 vTaskSuspend()后,该任务将从执行处暂停执行。除非对该任务调用vTaskResume()否则该任务无法恢复执行。2)对一个任务多次调用vTaskSuspend()暂停,仅需要在一处调用vTaskResume()即可恢复该任务。3)任务暂停后,调度器将不会赋予该任务CPU使用权,任务恢复后,调度器将根据该任务的优先级决定任务是否可以使用CPU而得到执行。4)任务恢复后,任务从暂停处继续向下执行。原创 2022-10-11 22:31:39 · 4360 阅读 · 0 评论 -
RTOS 中的任务调度与三种任务模型
1)任务调度器是 FreeRTOS 系统已经实现的任务管理组件,用于分配 CPU 的使用权,获取到 CPU 使用权的任务将得到执行。2)任务调度器有两个调度策略:高优先级在 SysTick 到达时可抢占 CPU 使用权,同优先级可以共享一个 SysTick 之间的 CPU 使用权(称为时间片轮转)。3)任务根据其运行情况,可以分为单次运行、周期运行、事件驱动运行三种模型,其中事件驱动模型可以最大限度提高 CPU 的使用效率,并且实时性好。原创 2022-10-10 22:14:14 · 6735 阅读 · 0 评论 -
FreeRTOS 创建任务的 Static 版本
1)xTaskCreateStatic() 是 xTaskCreate() 的 static 版本。相比 xTaskCreate() ,xTaskCreateStatic() 提供了StackBuffer、TaskBuffer 两个参数来指定堆栈空间的存储区域、task 控制块的存储区域。原创 2022-10-09 22:35:03 · 969 阅读 · 0 评论 -
FreeRTOS 创建第一个任务
1)ESP32 启动后将自动启用 FreeRTOS,并运行 void app_main(void) 中的代码2)创建任务使用 xTaskCreate()、xTaskCreatePinnedToCore(),任务被创建后将自动被 FreeRTSO 管理,自动加载运行任务中的 TaskCode.3)任务中的延时使用 vTaskDelay(),延时 1000ms 的示例为 vTaskDelay(pdMS_TO_TICKS(1000));原创 2022-10-08 22:11:19 · 1981 阅读 · 0 评论 -
RTOS 和裸机系统的异同-基于 ESP32 学习双核 FreeRTOS 的使用
基于 ESP32 学习 FreeRTOS 的使用. 裸机编程 VS FreeRTOS 系统编程。包括:任务的创建与使用。任务间通信与同步。任务与中断的通信与同步。任务、中断之间共享资源的保护与互斥。时间管理,定时器、看门狗、内存块的使用。系统、驱动编程示例。原创 2022-10-07 23:51:25 · 6580 阅读 · 0 评论 -
FreeRTOS任务状态切换(就绪、挂起、运行、删除、恢复、延时、阻塞)-小结
1. 任务的状态切换FreeRTOS中任务的状态可分为:未创建态、就绪态、运行态、挂起态、延时态五种状态。下图总结了一个任务可能出现的任务转换流程:a: 调用xTaskCreate()函数将新建一个任务,新建的任务会加入到就绪列表,若新建的任务的优先级足够高,调度器会立即将CPU资源分配给他,使它进入运行态。b: 调度器检查就绪列表中优先级高的任务,并将CPU资源分配给它,使他进入运行态。c: 运行态的任务可能创建/恢复了新的更高优先级的任务,或者因其操作了某事件(如发送了一个更高优原创 2020-07-26 17:40:20 · 9756 阅读 · 4 评论