FreeRTOS队列消息发送全解析:从任务到中断的API实战

【FreeRTOS】详细讲解FreeRTOS中消息队列并通过示例讲述其用法 本文详细地讲解了FreeRTOS消息队列的相关函数及其用法,使用用示例讲解各个函数实际用法以及实际使用过程中碰到的问题。 阅读详情

1. 队列消息发送:FreeRTOS的“邮局”系统

如果你刚开始接触FreeRTOS,可能会觉得“队列”这个概念有点抽象。别急,我给你打个比方。想象一下,你正在一个嵌入式项目里写代码,一个任务负责读取传感器数据,另一个任务负责处理这些数据并把结果显示出来。这两个任务就像公司里两个不同部门的同事,一个负责生产数据,一个负责消费数据。他们之间怎么高效、安全地传递信息呢?总不能每次都扯着嗓子喊,或者把数据写在公共的小黑板上吧?那样太容易出错,也容易混乱。

这时候,FreeRTOS的队列(Queue)就派上用场了。你可以把它理解成一个内部邮局或者一个有格子的快递柜。发送方(任务或中断)把“包裹”(消息)投递到柜子里,接收方按照顺序从柜子里取走包裹。这个“柜子”由FreeRTOS内核管理,它保证了即使多个任务同时想存取包裹,也不会发生混乱,数据绝对不会被破坏。这就是队列的核心价值:安全、可靠的任务间通信(IPC)。

今天我们不聊怎么建这个“邮局”(创建队列),也不聊怎么取包裹(接收消息),我们专门深挖一下怎么“寄快递”——也就是向队列发送消息。这听起来简单,但里面的门道可不少。比如,你在普通的任务代码里寄快递,和在时间紧迫的中断服务程序(ISR)里寄快递,用的“快递单”(API函数)是完全不同的,流程和注意事项也天差地别。用错了,轻则效率低下,重则系统卡死、数据丢失。

我刚开始用FreeRTOS那会儿,就在这上面栽过跟头。当时我在一个任务里调用了只能在中断里用的发送函数,编译倒是通过了,但程序一跑起来就各种诡异现象,查了半天才找到这个低级错误。所以,搞清楚FreeRTOS提供的这一整套发送API,知道什么时候该用哪个,以及它们背后是怎么运作的,是写出稳定、高效嵌入式系统的基本功。这篇文章,我就结合我这些年踩过的坑和实战经验,带你把这套“寄快递”的流程彻底搞明白。

2. 任务级发送API:常规流程下的选择

在FreeRTOS的世界里,运行在任务上下文(也就是你写的普通void vTaskFunction(void *pvParameters)这种函数)中的代码,时间要求相对宽松,可以等待(阻塞)。因此,FreeRTOS为任务准备了一套功能丰富、允许等待的发送函数。它们名字不同,但归根结底,核心逻辑都差不多。

2.1 基础三兄弟:Send, SendToBack, SendToFront

首先登场的是最常用的三个函数(实际上是宏):xQueueSend(), xQueueSendToBack(), 和 xQueueSendToFront()。我刚开始学的时候也挺困惑,为啥要三个?用哪个?

一句话总结:xQueueSend() 就是 xQueueSendToBack(),它俩完全一样,都是“后入队”;而 xQueueSendToFront() 是“前入队”。

这就像你在排队买奶茶。xQueueSendToBack() 是老老实实排到队伍最后面,这是默认的、最常用的方式,保证了先来的消息先被处理(FIFO,先进先出)。而 xQueueSendToFront() 就像是VIP插队,直接把新消息塞到队伍的最前面,下次有人来取消息时,会先拿到这个最新插队的消息(LIFO,后进先出)。这个功能在某些特定场景下很有用,比如需要优先处理最新的控制命令。

它们的函数原型长这样:

BaseType_t xQueueSend( QueueHandle_t xQueue,
                       const void * pvItemToQueue,
                       TickType_t xTicksToWait );

BaseType_t xQueueSendToBack( QueueHandle_t xQueue,
                             const void * pvItemToQueue,
                             TickType_t xTicksToWait );

BaseType_t xQueueSendToFront( QueueHandle_t xQueue,
                              const void * pvItemToQueue,
                              TickType_t xTicksToWait );

参数很好理解:

  • xQueue:你之前创建好的那个“快递柜”的句柄。
  • pvItemToQueue:指向你要发送的数据的指针。注意是const void *,意味着函数内部不会修改你的数据,只是拷贝走。
  • xTicksToWait:这是任务级API的精髓。如果“快递柜”满了,你要等多久?你可以设置一个具体的时钟节拍数(比如pdMS_TO_TICKS(100)表示等100毫秒),或者用portMAX_DELAY一直等到天荒地老(前提是配置了INCLUDE_vTaskSuspend为1),也可以用0表示不等,立刻返回。

返回值有两种:

  • pdPASS:发送成功。要么是柜子有空位直接存进去了,要么是等了一会儿后有空位存进去了。
  • errQUEUE_FULL:发送失败(对于xTicksToWait=0的情况),或者等待超时了柜子还是满的。

这里有个大坑我踩过:这个“等待”行为,会让调用它的任务进入阻塞态。任务会从就绪列表里被移走,挂到队列的“等待发送”列表上,同时内核会进行一次任务调度,让其他就绪的任务运行。直到柜子有空位(有任务取走了消息)或者等待超时,这个发送任务才会重新变回就绪态。所以,千万别在中断里用这些函数,中断里不允许阻塞!

2.2 霸道总裁:xQueueOverwrite

接下来这位比较特殊:xQueueOverwrite()。看名字就知道它很“霸道”——覆写。

它的原型是:

BaseType_t xQueueOverwrite( QueueHandle_t xQueue,
                            const void * pvItemToQueue );

注意,它没有xTicksToWait参数!因为它根本不需要等待。它的逻辑是:如果队列满了,我就把最旧的那个数据(对于后入队队列,就是队首的数据)踢出去,然后把我的新数据塞进去。如果队列没满,那行为就和xQueueSendToBack()一样。

这适合什么场景呢?最适合长度只有1的队列。这种队列常被用作“最新状态”的邮箱。比如,一个传感器数据采集任务,以100Hz的频率更新当前温度值。处理任务可能不需要知道每一个历史温度,只需要知道最新的温度是多少。这时候用一个长度为1的队列,发送方一直用xQueueOverwrite()去更新,接收方用xQueueReceive()去取,取到的永远是最新值,旧值被自动丢弃,完美。

如果你在一个长度大于1的队列上用xQueueOverwrite(),逻辑上它只会覆写一个位置(后入队模式下是队尾的上一个位置?这里容易混淆,实际实现是覆写队尾),这可能会破坏FIFO的顺序,通常不是你想要的,所以不推荐。

2.3 幕后大佬:xQueueGenericSend

前面提到的所有任务级发送函数,xQueueSendToBack, xQueueSendToFront, xQueueOverwrite,最后都调用了同一个幕后大佬:xQueueGenericSend()。这个函数在queue.c文件里,是真正处理所有复杂逻辑的地方。

理解这个函数,你就能彻底明白任务级发送的完整流程。我们来捋一下它的核心逻辑(基于源码的简化分析):

  1. 检查队列状态:首先看队列是不是满的。如果没满,或者调用模式是queueOVERWRITE(覆写),那就太好了,直接进入“快速路径”。
  2. 拷贝数据:调用一个内部函数prvCopyDataToQueue(),把用户要发送的数据,按照指定的方式(后入队、前入队、覆写)拷贝到队列的存储区。同时更新队列的写指针和消息计数。
  3. 唤醒等待者:数据放进去了,得看看有没有人正等着取数据呢?检查队列的xTasksWaitingToReceive列表。如果有任务挂在这个列表上(说明它之前调用xQueueReceive时队列是空的,它等睡着了),就把它从等待列表移除,加到就绪列表。如果被唤醒的任务优先级比当前正在运行的任务优先级还高,还会标记一下“需要任务切换”。
  4. 处理快速路径成功:如果需要切换,就触发一次调度;最后返回pdPASS。

如果队列是满的呢? 这才是体现FreeRTOS设计精巧的地方。

  1. 判断是否等待:如果调用者设置的xTicksToWait是0,那没啥好说的,直接返回errQUEUE_FULL。
  2. 准备等待:如果等待时间大于0,内核会记录一个“超时结构体”,保存当前的时间戳。
  3. 锁定与挂起:接着,内核会暂时锁定任务调度器,防止其他任务干扰。然后给队列上一把锁(操作内部链表时需要)。
  4. 再次检查与挂起:在锁的保护下,再次检查队列是否还是满的,并且等待时间是否超时。如果依然满且未超时,那么当前这个发送任务就会被:
    • 挂到队列的xTasksWaitingToSend列表(这样当队列有空位时能知道要唤醒谁)。
    • 同时挂到延时列表(用来实现超时)。
    • 从就绪列表移除。
  5. 解锁与调度:完成挂起操作后,解锁队列,恢复任务调度器。这时,当前任务已经“睡着”了,CPU会去执行其他就绪的任务。
  6. 被唤醒或超时:未来某个时刻,要么有任务从队列取走了数据(队列空出一个位置),内核会检查xTasksWaitingToSend列表并唤醒优先级最高的等待发送任务;要么就是等待时间到了。这个被唤醒的任务会重新执行,并再次尝试发送数据。

这一套“等待-挂起-唤醒”的机制,是FreeRTOS多任务协调工作的基石。它让任务可以高效地“睡眠”等待资源,而不是傻傻地循环查询(忙等待),极大地节省了CPU资源。

3. 中断级发送API:快进快出的艺术

中断服务程序(ISR)是嵌入式系统的“急诊室”,要求执行时间极短,快进快出。在ISR里,绝对不允许进行任何可能导致阻塞的操作,比如等待一个队列空出位置。因此,FreeRTOS为中断准备了一套专用的发送API,它们都以FromISR结尾。

3.1 中断三剑客与覆写版

和任务级对应,中断级也有四个核心函数:

  • xQueueSendFromISR() / xQueueSendToBackFromISR():中断里的后入队。
  • xQueueSendToFrontFromISR():中断里的前入队。
  • xQueueOverwriteFromISR():中断里的霸道覆写。

它们的原型特点是没有xTicksToWait参数(因为不能等待),但多了一个非常重要的参数pxHigherPriorityTaskWoken。

BaseType_t xQueueSendFromISR( QueueHandle_t xQueue,
                              const void *pvItemToQueue,
                              BaseType_t *pxHigherPriorityTaskWoken );

这个pxHigherPriorityTaskWoken是一个指向BaseType_t的指针,你需要传入一个变量的地址。它的作用是:告诉内核,本次发送操作是否唤醒了一个优先级比当前被中断任务更高的任务。

为什么这么设计?因为中断发生是异步的,它可能唤醒了一个高优先级的任务。但中断处理过程中不能立刻进行任务切换,必须等中断函数全部执行完,退出前再由内核决定是否切换。这个参数就是传递这个信息的“信使”。

实战中的经典用法:

void vAnInterruptHandler(void) {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    uint32_t ulDataToSend = 0xABCD;

    // 在中断里向队列发送数据
    if (xQueueSendFromISR(xQueueHandle, &ulDataToSend, &xHigherPriorityTaskWoken) == pdPASS) {
        // 发送成功
    }

    // 中断退出前,根据标志进行任务切换
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

记住这个模式:定义变量 -> 传入指针 -> 检查变量 -> 决定是否切换。如果你不关心是否切换,或者确定不会唤醒更高优先级任务,可以传入NULL,但养成传入的习惯更安全。

3.2 中断核心引擎:xQueueGenericSendFromISR

和任务级一样,所有中断级发送函数都汇聚到xQueueGenericSendFromISR()这个核心函数。它的逻辑比任务级版本要“直爽”很多,因为少了很多关于阻塞和超时的复杂判断。

我们来拆解一下它的关键步骤:

  1. 检查与拷贝:首先,同样检查队列是否满(除非是覆写模式)。如果条件允许,立刻调用prvCopyDataToQueue把数据拷贝进去。
  2. 检查等待接收的任务:数据放进队列后,立刻检查xTasksWaitingToReceive列表。注意,这里和任务级有一个关键区别:中断里操作这个列表时,队列可能是“上锁”状态(比如正好有一个任务级发送函数正在操作队列的内部链表)。
  3. 延迟处理与锁计数:如果队列是上锁的(通过检查cRxLock或cTxLock),中断函数不会直接去移除和唤醒等待的任务。为什么呢?因为操作链表不是原子的,中断可能会打断任务级函数对链表的操作,导致链表损坏。所以,FreeRTOS采用了一种巧妙的“延迟处理”机制:
    • 如果队列已锁,中断只是简单地将队列的cTxLock或cRxLock计数器加1。这个计数器记录了在队列被锁期间,有多少次发送或接收操作发生。
    • 等到那个正在操作队列的任务级函数(比如xQueueGenericSend)完成它的工作、准备解锁队列时,它会检查这些锁计数器。如果发现cRxLock大于0(表示有中断发送了数据),它就会代替中断,去执行唤醒xTasksWaitingToReceive列表中任务的操作。同样,如果cTxLock大于0(表示有中断取走了数据),它会去唤醒xTasksWaitingToSend列表中的任务。
  4. 设置唤醒标志:如果队列没锁,中断可以直接安全地移除等待接收的任务。如果被移除的任务优先级高于当前被中断的任务,就将*pxHigherPriorityTaskWoken设置为pdTRUE。
  5. 返回:最后返回pdPASS或errQUEUE_FULL。

这个“锁计数+延迟处理”的机制,是FreeRTOS实现任务与中断安全通信的关键,它避免了在中断中执行复杂操作,也保护了内核数据结构的完整性。

4. 实战场景与避坑指南

理论说了一大堆,到底怎么用?这里我结合几个真实的场景,告诉你该怎么选API,以及我踩过的那些坑。

4.1 场景一:任务间传递传感器数据(经典生产者-消费者)

这是最经典的场景。一个任务(生产者)读取ADC,另一个任务(消费者)进行滤波和显示。

如何选择?

  • 发送方(任务):使用 xQueueSend() (即 xQueueSendToBack())。因为我们需要按顺序处理每一个采样点,保证数据的时序性。阻塞时间可以设置为portMAX_DELAY,让发送任务在队列满时安心等待,直到处理任务取走数据。这能很好地平衡生产者和消费者的速度差异。
  • 队列长度设置:这是个学问。设得太短,生产者容易阻塞,可能丢失实时数据;设得太长,占用内存多,且数据延迟可能变大。我通常根据采样率和处理速度来估算。比如生产者100Hz(10ms一次),消费者处理一次需要5ms,那么队列长度设为3或4就能提供一个缓冲,避免因偶尔的处理波动导致阻塞。

避坑点:

  • 数据拷贝:队列传递的是数据的拷贝,不是指针(除非你传递的就是指针变量本身)。这意味着如果你发送一个大的结构体,会有内存拷贝开销。对于大块数据,更常见的做法是传递指向数据的指针。但这里有个巨坑:你必须确保指针指向的内存区域是有效的,并且要考虑内存的生命周期。通常的解决方案是使用内存池或者静态分配的内存块。千万别发送一个局部变量的地址,然后任务切换了,那个局部变量失效了,接收方拿到的就是个野指针。

4.2 场景二:中断通知任务(事件触发)

按键中断、定时器中断、通信接口接收中断等,都需要快速通知一个任务去做后续处理。

如何选择?

  • 发送方(中断):必须使用 xQueueSendFromISR()。因为中断里不能等。
  • 队列设计:这里传递的往往不是大量数据,而是一个“事件”或“命令”。比如,一个uint32_t变量,用不同的位或值表示不同的事件(按键按下、定时时间到、收到一帧数据)。队列长度通常设为1就够了,因为中断通知是“即发即弃”的,如果任务还没处理完上一个通知,新的通知覆盖掉旧的也无妨。这种情况下,甚至可以考虑用 xQueueOverwriteFromISR(),确保任务拿到的是最新的事件。
  • 接收方(任务):任务在 xQueueReceive() 时,阻塞时间设为 portMAX_DELAY,这样任务就会安静地等待事件到来,不消耗CPU时间。一旦中断发送了消息,任务立刻被唤醒执行。

避坑点:

  • 别忘了 portYIELD_FROM_ISR():这是新手最容易忘的一步!在中断函数末尾,一定要检查 xHigherPriorityTaskWoken 并决定是否触发一次任务切换。如果中断唤醒了一个更高优先级的任务,而你忘了调用 portYIELD_FROM_ISR(),那么高优先级任务就必须等到当前任务时间片用完或主动放弃CPU才能运行,实时性就得不到保证。
  • 中断中不要做复杂计算:中断里只做最必要的操作:读取状态、清除标志、发送队列通知。把耗时的处理留给任务。我曾经在UART接收中断里做数据解析,结果解析时间过长,导致中断频繁被抢占,丢失了后续字节。

4.3 场景三:传递最新状态值

比如系统状态机、当前错误码、实时更新的设定值等。任何任务或中断都可能更新它,任何其他任务都可能需要读取它。

如何选择?

  • 发送方:无论是任务还是中断,都使用 xQueueOverwrite() 或 xQueueOverwriteFromISR()。
  • 队列设计:队列长度必须为1。这实际上把它变成了一个“邮箱”或“共享变量”,但比直接使用共享变量安全,因为FreeRTOS保证了操作的原子性。
  • 接收方:使用 xQueueReceive(),但阻塞时间设为0。因为接收方只是想获取当前的最新值,如果没有新值(实际上队列创建后初始为空),它也不需要等待,可以直接去做其他事情。或者,也可以使用 xQueuePeek() 来“窥视”队列头部的数据而不取走它,这样多个任务都能读到同一个状态值。

避坑点:

  • 长度必须为1:这是使用覆写API的前提。如果你创建了一个长度为5的队列然后使用覆写,它的行为可能不符合你的直觉(它只覆写一个位置),逻辑会变得混乱。
  • 理解“最新”的含义:对于覆写队列,发送方永远成功,接收方每次取到的都是最后一次写入的数据。这可能导致某些中间状态被丢弃,如果你的应用需要记录每一个状态变化,就不能用这个模式。

4.4 性能与内存的权衡

  • 关中断时间:xQueueSendFromISR 这类函数在执行时,会临时关闭中断(或提升中断优先级),以保护内部数据操作。虽然时间很短,但在对实时性要求极其苛刻的场合(比如电机控制PWM中断),你需要评估这段关中断时间是否可接受。如果队列操作非常频繁,可能需要考虑更轻量级的通信机制,比如直接使用事件标志组(Event Groups)或任务通知(Task Notifications)。
  • 深拷贝开销:队列是深拷贝。传递一个包含大型数组的结构体会导致可观的拷贝时间。如果数据很大且更新不频繁,可以考虑传递指针,但必须配套好内存管理方案。
  • 动态内存:创建队列时通常使用动态内存分配(xQueueCreate)。在内存紧张的系统中,或者要求确定性的系统中,可以使用 xQueueCreateStatic 静态分配内存,避免运行时分配失败的风险。

说到底,FreeRTOS队列的发送API虽然有好几个,但只要你理解了“任务”和“中断”这两个不同上下文的核心区别,理解了“阻塞等待”与“立即返回”的设计哲学,再结合“FIFO/LIFO/覆写”这三种数据组织方式,就能在实战中游刃有余地做出正确选择。多写代码,多调试,遇到问题回头看看这些API的内部逻辑,印象会深刻得多。

从底层到实战:FreeRTOS队列全解析,4万字爆肝指南让你一次吃透多任务通信核心 你是否在FreeRTOS多任务开发中遇到过这些困惑: - 任务间消息传递总出bug,数据丢包、错乱怎么破? - 中断里发消息总崩溃,普通任务和ISR的队列操作到底有啥区别? - 队列满了该阻塞等待还是直接覆写?静态创建和动态创建哪个更适合你的场景? 阅读详情

相关推荐

FreeRTOS中断中安全发送消息队列详解

消息队列是嵌入式实时系统中任务间通信的基础机制,其核心原理在于通过受控缓冲区实现数据解耦与同步。在FreeRTOS中,队列操作需严格区分任务上下文与中断上下文,因中断服务程序(ISR)必须满足无阻塞、无超时、时间确定性等硬实时约束。为此,系统提供专用的xQueueSendFromISR等中断安全API,依赖原子操作、临界区保护及PendSV异常协同调度器完成上下文切换。该机制显著提升外设响应效率,广泛应用于串口、CAN、ADC等中断驱动场景。本文聚焦FreeRTOS中队列在中断环境下的发送原理、参数语义与典

weixin_34471637的博客 168

FreeRTOS-消息队列详解

本文将详细全方位的讲解FreeRTOS的队列消息,其实在FreeRTOS中队列的重要性也不言而喻,与FreeRTOS任务调度同等重要,因为后面的各种信号量基本都是基于队列的。本文主要围绕(队列的创建、队列的出队、入队函数、队列的环形缓冲区的实现(数据的拷贝、先进先出、以及后进先出的实现)、队列锁、以及队列任务级函数与中断级函数的区别)队列的重要知识,本文都会以源码分析的形式进行解析。!!

k666499436的博客 1万+

给汽车工程师的TSN实战手册:用TSN Box和TSNTools搞定车载以太网时间同步

本文为汽车工程师提供TSN(时间敏感网络)实战指南,详细讲解如何利用TSN Box和TSNTools实现车载以太网时间同步。内容涵盖测试环境搭建、802.1AS协议配置、七种延时测量与故障诊断,以及智能驾驶域控制器的同步调试案例,帮助工程师快速掌握TSN技术并应用于实际项目。

weixin_30613343的博客 209

FreeRTOS消息队列

问题解答 曾经有人问我,FreeRTOS那么多API,到底怎么记住呢? 我想说,其实API不难记,就是有点难找,因为FreeRTOS的API很多都是带参宏,所以跳来跳去的比较麻烦,而且注释也很多,要找还真不是那么容易,不过也没啥,一般都会有API手册的,我就告诉大家一下: FreeRTOS Kernel: Reference Manual FreeRTOS内核:参考手册,大家可以在官网下载,也能在...

杰杰的博客 2万+

什么是 WhatsApp云控 WhatsApp群发,WhatsApp协议,他们有什么区别?

下面我们sensws讲解下什么是WhatsApp云控 WhatsApp群发,WhatsApp协议

sendws的博客 3875

从零到一:手把手教你构建自定义ReaxFF力场参数

本文手把手教你从零构建自定义ReaxFF力场参数,详解反应力场的动态键序机制与参数化逻辑。通过LAMMPS实战演示,涵盖训练数据准备、参数优化算法选择及性能优化技巧,助力研究人员精准模拟化学反应过程。适用于材料科学、催化研究等领域,特别适合已掌握分子动力学基础的进阶用户提升力场开发能力。

weixin_28365523的博客 1060

FreeRTOS基础(十一):消息队列

假设有一个全局变量a = 0,现有两个任务都在对变量a进行自增操作(写操作),如下图所示:对于自增操作它不是原子操作,会经过一系列的步骤,最后才将自增后的结果写入到寄存器,如果任务2的优先级高于任务1,在任务1将自增后的2即将写入到a之前,任务2打断任务1进行自增操作,任务2拿到的是a为1,然后再进行的自增,两个任务执行完后自增其实只进行了一次数据无保护,导致数据不安全,当多个任务同时对该全局变量操作时,数据易受损!!

weixin_47040031的博客 3828

深入解析DDR5 RFM机制:从JESD79-5标准到硬件实现

本文深入解析了DDR5内存标准中的关键机制——RFM(Refresh Management)。文章从JESD79-5标准出发,详细阐述了RFM如何通过RAA计数器实现从被动定时到主动响应的智能刷新管理,并探讨了其硬件实现细节、命令调度挑战及系统级设计考量,为芯片设计工程师优化DDR5内存子系统性能与可靠性提供了实践指导。

fff88的博客 492

FreeRTOS消息队列实战指南:中断与任务间的队列发送技巧

本文详细解析FreeRTOS消息队列的实战应用技巧,重点对比任务级与中断级的队列发送函数差异。通过具体代码示例展示xQueueSend、xQueueSendFromISR等核心API的使用场景,提供队列长度设计、零拷贝优化等高级技巧,帮助开发者实现高效可靠的任务间通信。特别强调中断环境下必须使用xQueueSendFromISR等专用函数的关键要点。

weixin_28331555的博客 616

葵花 Himawari 8/9号数据学习记录-01-数据初识

葵花卫星学习记录,第一章:卫星的来源与卫星数据的波段介绍

weixin_44111909的博客 540

ubuntu 24.04安装ros1 noetic

上面是参考链接给的修改内容。除了上面要修改的地方,我在编译的生活还有一个地方报错,修改成如下形式。因为我已经对文件rosconsole_log4cxx.cpp作了上面的修改,所有是不是188行不太确认了,如果报“log4cxx::spi::LocationInfo”问题,按照下面修改就可以了。我在编译时还报了一个问题,就是我之前安装的是jazzy。所以在编译时会报ros变量名不对,这时对变量名做修改就可以了。具体怎么修改,百度。a、将源文件中所有CMakelist中编译标准改为c++ 17.

yangpan011的博客 3209

FreeRTOS记录(六、FreeRTOS消息队列—Enocean模块串口通讯、RAM空间不足问题分析)

本篇文章记录FreeRTOS消息队列的使用,我不从理论开始介绍,直接用起来,然后从发现的问题分析记录解决。 1、创建消息队列 在CubemX中,操作如下: 创建完毕生成代码,在代码中可以看到: ... osThreadId enoecantaskHandle; osMessageQId EnoceanQueueHandle; ... void MX_FREERTOS_Init(void) { /* USER CODE BEGIN Init */ /* USER CODE END In

不浮夸,不将就,认真对待学知识的我们 4110

优快云专栏限时活动!福利公告必读!

本人优快云付费专栏周排名27名专业博主,每周文章平均阅读量约7w以上!

FJN110的博客 3156

FreeRtos:(六)消息队列

消息队列是任务到任务、任务到中断、中断到任务数据交流的一种机制(进行消息传递)FreeRTOS基于队列, 实现了多种功能,其中包括队列集、互斥信号量、计数型信号量、二值信号量、 递归互斥信号量,因此很有必要深入了解 FreeRTOS 的队列。在消息队列中可以存储数量有限、大小固定的数据,可以将队列理解为一个全局数组。队列中的每一个数据叫做“队列项目”,队列能够存储“队列项目”的最大数量称为队列的长度。简单的说:队列就是任务之间或者任务与中断时间传递消息和数据的的载体。

jitui_chibugou的博客 1758

结构力学本构模型:复合材料模型:复合材料热力学行为技术教程_2024-08-07_06-54-53.Tex

热塑性复合材料是一种由热塑性树脂基体和增强纤维组成的复合材料。与热固性复合材料不同,热塑性复合材料在加热时可以软化,冷却时硬化,这一过程可以重复进行,因此它们具有可回收和可再加工的特性。热塑性树脂,如聚酰胺(尼龙)、聚碳酸酯、聚醚醚酮(PEEK)等,与碳纤维、玻璃纤维等增强材料结合,可以制备出具有高强度、高刚度和良好耐热性的复合材料。热粘弹性理论是研究材料在温度变化和时间依赖性载荷作用下的变形和应力响应。复合材料,由于其独特的微观结构,展现出复杂的热粘弹性行为。

810

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

FreeRTOS任务通知 基于STM32

FreeRTOS任务通知 基于STM32任务通知实验,任务通知代替消息队列,任务通知代替二值信号量,任务通知代替计数信号量

qq_61672347的博客 2万+

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

FreeRTOS进程间通信-消息队列

消息队列是进程间的一种通信机制,实际项目运用很多。 1、什么是消息队列? 2、消息队列API函数 3、在进程间通信使用消息队列 4、在中断中使用消息队列 1.1、消息队列是什么? 消息队列是realtime os 内核提供的服务,任务之间或者是中断中可以将一个消息放到队列中进行传递,freertos可以通过内核API获取到队列中的数据,freertos传递了实际数据。消息可...

a13698709128的博客 7871

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

freertos专题---消息队列

本篇用于描述freertos里【消息队列的使用原因】,【消息队列的使用场景】,【消息队列的API介绍】,【消息队列使用方法(配合实际代码)】,和【消息队列的底层机制】参数:UBaseType_t uxQueueLength:设置消息队列长度;UBaseType_t uxItemSize:设置消息队列中单个消息的大小;函数说明创建函数,实际上使用还是调用函数 xQueueGenericCreate()完成消息队列创建工作。当消息队列创建成功时,返回一个消息队列的控制句柄。

yrx020307的博客 1089

【FreeRTOS】队列API全家桶

FreeRTOS队列API使用要点:1. 创建队列时需检查返回值(NULL表示失败);2. 发送/接收消息要判断状态(pdPASS表示成功);3. 普通任务和中断中需使用对应版本的API;4. 消息传递基于复制,传递指针时需注意内存管理;5. 中断中操作队列不能阻塞,需处理任务切换标记。

2402_83411382的博客 1326

STM32---FreeRTOS消息队列阻塞机制与任务调度实战解析

本文深入解析STM32平台下FreeRTOS消息队列的阻塞机制与任务调度策略。通过实战案例详细讲解队列满/空时的任务阻塞行为、优先级调度规则及中断安全操作,帮助开发者避免死锁问题并优化系统性能。

tgb3456789的博客 1047

FreeRTOS中的消息队列

FreeRTOS消息队列是核心的进程间通信机制,采用环形缓冲区和队列控制块实现任务间安全数据传递。其结构包含读写指针、阻塞任务列表和消息计数等要素,支持值传递和指针传递两种方式。消息队列通过临界区保护确保多任务/ISR访问安全,提供动态/静态创建、发送接收等API接口,并衍生出信号量等同步机制。队列集机制扩展了多队列管理能力,使任务能同时等待多个队列事件。该机制具有高效存取、避免忙等、接口简洁等特点,是嵌入式实时系统数据通信的重要基础。

2301_79695216的博客 1441

FreeRTOS——消息队列

队列:任务与任务、任务与中断之间进行数据交流的一种机制消息传递FreeRTOS基于队列, 实现了多种功能,其中包括队列集、互斥信号量、计数型信号量、二值信号量、 递归互斥信号量队列的核心:关中断(实现互斥)、链表(实现休眠和唤醒)、环形缓冲区(保存数据)Q:队列作用与全局变量作用的区别?答:功能类似于全局变量,但又比全局变量更安全假设全局变量a= 0,现有两个任务都在操作全局变量a,正常情况下,a = 2,然而,在操作系统中:对于简单的变量自增,其中也包含许多步骤。

qq_68719489的博客 1303

FreeRTOS之消息队列

• 队列(Queue)是FreeRTOS中实现的核心机制,用于在任务与任务、中断与任务之间传递数据。•:队列是一个即先发送的消息会被先接收,支持数据项的存储与按顺序读取。•:采用(复制数据本身),而非指针传递,确保数据安全性和独立性。但是,如果是大块数据也可以传地址值。•• 传感器数据采集与处理任务间的数据传输。• 中断服务程序(ISR)向任务传递事件标志。• 队列的关键名词:•:队列中的每一个数据。•:队列能够存储队列项目的最大数量。

luoyanglook的博客 854

FreeRTOS(3)----消息队列

当发送信息的时候,如果队列未满,则会将消息拷贝到队尾,否则,会根据用户指定的阻塞超过时间进行阻塞,如果队列一直不允许入队,任务则一直保持阻塞状态,等待队列允许入队,在这段时间,当别的任务从其他等待队列读入了数据(队列未满),任务将自动从阻塞态变为就绪态,当等待的时间超过阻塞时间,即使队列还不允许入队,任务也会从阻塞态变为就绪态,且发送信息的任务或者中断程序会收到一个错误码。注意:当多个任务阻塞在一个消息队列中,这些阻塞的任务会按照任务的优先级进排序,优先级高的任务将优先获得访问队列的权利。

weixin_63032791的博客 2976
上一篇: 若依框架Spring Security多用户登录实战:巧用JSON扩展UserDetailsService实现PC与APP双端鉴权
下一篇: 从光谱到脑图:fNIRS如何通过神经血管耦合解码认知活动
python9snake
博客等级 码龄1天 0粉丝 1724原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值