Bootstrap

FreeRTOS实时操作系统(十七)流缓冲区、消息缓冲区、钩子函数

系列文章

FreeRTOS实时操作系统(一)RTOS的基本概念

FreeRTOS实时操作系统(二)任务创建与任务删除(HAL库)

FreeRTOS实时操作系统(三)任务挂起与恢复

FreeRTOS实时操作系统(四)中断任务管理

FreeRTOS实时操作系统(五)进入临界区、任务调度器挂起与恢复

FreeRTOS实时操作系统(六)列表与列表项

FreeRTOS实时操作系统(七)时间片调度及RTOS的滴答定时器

FreeRTOS实时操作系统(八)任务状态查询及时间统计函数

FreeRTOS实时操作系统(九)时间延时函数及消息队列

FreeRTOS实时操作系统(十)信号量

FreeRTOS实时操作系统(十一)队列集

FreeRTOS实时操作系统(十二)事件标志组

FreeRTOS实时操作系统(十三)任务通知

FreeRTOS实时操作系统(十四)软件定时器

FreeRTOS实时操作系统(十五)Tickless低功耗模式

FreeRTOS实时操作系统(十六)内存管理



简介

流缓冲区是任务到任务、中断到任务、双核之间数据传递的通信原语。
数据通过复制传递,数据由发送方复制到缓冲区中, 并通过读取从缓冲区中复制出来。

流缓冲区传递连续的字节流,消息缓冲区传递大小可变但离散的消息,消息缓冲区使用流缓冲区进行数据传输。

某一时刻只能有一个对象读或写,所以需要加临界区保护如果有多个在读写。

流缓冲区

字节流可以是任意长度, 且并不一定具有开头或结尾。
可以一次写入任意数量的字节, 也可以一次读取任意数量的字节。
数据通过拷贝传递,发送方将数据复制到缓冲区中, 读取方将数据复制出缓冲区。
通过将 FreeRTOS/source/stream_buffer.c 源文件包含在项目中来启用流缓冲区功能。

采用的方式像任务通知一样,流缓冲区的API函数将调用的任务置于“阻塞”状态

在这里插入图片描述
在cubemx里面没有相关设置,即使FreeRTOSconfig.h也没有相关的宏,只需要包含该stream_buffer.h文件就行
在这里插入图片描述

读取流缓冲区

xStreamBufferReceive() 用于读取 来自 RTOS 任务的流缓冲区的数据。
允许指定阻塞时间,流缓冲区为空时,会阻塞,直到有指定数量的数据,或者阻塞时间到期
阻塞时间即使到了,该任务下次还可以继续用来接收

触发级别决定了数据长度(单位字节)
如果任务在读取触发级别为 10 的空流缓冲区时被阻塞, 则在流缓冲区至少包含 10 个字节或任务的阻塞时间到期之前, 该任务将不会被解除阻塞。
不可将触发级别指定为大于 流缓冲区的大小,设置为0无效,将默认为1

xStreamBufferReceiveFromISR()) 用于从中断服务程序 (ISR) 的流缓冲区中读出数据。

写入流缓冲区

xStreamBufferSend()) 用于 将数据从 RTOS 任务发送到流缓冲区。 xStreamBufferSendFromISR()) 用于 将数据从中断服务程序 (ISR) 发送到流缓冲区。

如果任务使用 xStreamBufferSend() 写入恰好已满的流缓冲区时,如果指定了非零阻塞时间,则该任务将进入阻塞状态,直到流缓冲区中出现可用空间,或者阻塞时间到期。

消息缓冲区

消息缓冲区允许长度可变的离散消息从中断服务程序传递至一个任务,或从一个任务传递至另一个任务。 例如,长度为 10、20 和 123 字节的消息都可以在同一个消息缓冲区写入或读取。 与使用流缓冲区不同, 长度为 10 个字节的数据只能10 个字节读取。 消息缓冲区构建在流缓冲区之上。

通过将 FreeRTOS/source/stream_buffer.c 源文件包含在构建中 来启用消息缓冲区功能。
同理于流缓冲区,多个读写要加临界区

要使消息缓冲区能够处理可变大小的消息, 在将消息写入消息缓冲区之前,需将每条消息的长度先写入消息缓冲区。 长度由 configMESSAGE_BUFFER_LENGTH_TYPE 变量 (位于 FreeRTOSConfig.h 中)设置。 如果未定义,则默认 configMESSAGE_BUFFER_LENGTH_TYPE 为 size_t 类型。 在 32 位架构上,size_t 通常 为 4 个字节。 因此,将 10 字节长度的消息写入消息缓冲区实际上会消耗 14 字节的缓冲区空间。 多出来的字节其实存储了长度信息

xMessageBufferReceive())用于 从 RTOS 任务的消息缓冲区读取数据。
xMessageBufferReceiveFromISR())用于 从中断服务程序 (ISR) 的消息缓冲区读取数据。 xMessageBufferSend())用于 将数据发送到 RTOS 任务的消息缓冲区。
xMessageBufferSendFromISR())用于 将数据从中断服务程序 (ISR) 发送到消息缓冲区。

钩子函数

空闲任务的钩子函数

空闲任务可以选择性地调用应用程序定义的钩子(回调)函数 。 空闲任务以最低优先级运行, 因此只有在没有能够运行的更高优先级的任务时,这种空闲钩子函数才会被执行。 这使的空闲钩子函数成为使处理器进入低功率状态的理想场所 ,每当没有要执行的处理时提供自动节能。

只有 configUSE_IDLE_HOOK 在 FreeRTOSConfig.h 中设置为 1 时,才会调用空闲钩子。 设置后,应用程序必须为钩子函数提供以下原型 :

void vApplicationIdleHook( void );

只要空闲任务在执行,就会不断调用钩子函数,空闲钩子函数不调用任何可能导致其阻塞的 API 函数

Tick的钩子函数

只有 configUSE_TICK_HOOK 在 FreeRTOSConfig.h 中设置为 1 时,才会调用 tick 钩子。 设置后,应用程序必须为钩子函数提供以下原型 :

void vApplicationTickHook( void );

tick 中断可以选择性地调用应用程序定义的钩子(或回调)函数 。 tick 钩子提供了一个方便的地方来实现定时器功能 。从 ISR 内执行,因此必须非常短,不使用很多堆栈,并且不调用任何不以 “FromISR” 或 “FROM_ISR” 结尾的 API 函数。

Malloc 失败钩子函数

由 heap_1.c、heap_2.c、heap_3.c、heap_4.c 和 heap_5.c 实现的内存分配方案可以选择性地包含 malloc() 失败钩子(或回调)函数,该函数可以配置为在 pvPortMalloc() 返回 NULL 时被调用。
定义 malloc() 失败钩子将有助于识别由堆内存不足引起的问题,特别是当在 API 函数中调用 pvPortMalloc() 失败时 。

只有 configUSE_MALLOC_FAILED_HOOK 在 FreeRTOSConfig.h 中设置为 1 时,才会调用 malloc 失败钩子。 设置后,应用程序必须为钩子函数提供以下原型 :

void vApplicationMallocFailedHook( void );

守护进程任务启动钩子

RTOS 守护进程任务与定时器服务任务相同。 有时它被称为守护进程任务, 因为该任务现在不仅仅用于服务定时器。
如果 configUSE_DAEMON_TASK_STARTUP_HOOK 在 FreeRTOSConfig.h 中设置为 1 , 则守护进程任务首次开始执行时,会调用守护进程任务启动钩子 。 如果应用程序包含会从调度器启动后执行中受益的初始化代码, 这将非常有用,允许 初始化代码利用 RTOS 功能。

如果 configUSE_DAEMON_TASK_STARTUP_HOOK 设置为 1 ,则应用程序编写者必须 提供守护进程任务启动钩子函数的实现,且具有以下名称和原型 :

void vApplicationDaemonTaskStartupHook( void );

堆栈保护的钩子函数

这部分见前一篇文章:FreeRTOS实时操作系统(十六)内存管理与堆栈溢出

;