0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

重点讲解如何结合RTOS进行处理数据

454398 来源:面包板社区 作者:小小毛 2021-02-09 09:15 次阅读

我们巧妙的利用了RTSO自带的消息队列,我们可以把每一个接收的数据看做一个消息元素。
先回顾一下知识点:

FreeRTOS消息队列

基于 FreeRTOS 的应用程序由一组独立的任务构成——每个任务都是具有独立权限的程序。这些独立的任务之间的通讯与同步一般都是基于操作系统提供的IPC通讯机制,而FreeRTOS 中所有的通信与同步机制都是基于队列实现的。
消息队列是一种常用于任务间通信的数据结构,队列可以在任务与任务间、中断和任务间传送信息,实现了任务接收来自其他任务或中断的不固定长度的消息。任务能够从队列里面读取消息,当队列中的消息是空时,挂起读取任务,用户还可以指定挂起的任务时间;当队列中有新消息时,挂起的读取任务被唤醒并处理新消息,消息队列是一种异步的通信方式。

队列特性

1.数据存储

队列可以保存有限个具有确定长度的数据单元。队列可以保存的最大单元数目被称为队列的“深度”。在队列创建时需要设定其深度和每个单元的大小。
通常情况下,队列被作为 FIFO(先进先出)缓冲区使用,即数据由队列尾写入,从队列首读出。当然,由队列首写入也是可能的。
往队列写入数据是通过字节拷贝把数据复制存储到队列中;从队列读出数据使得把队列中的数据拷贝删除。

2.读阻塞

当某个任务试图读一个队列时,其可以指定一个阻塞超时时间。在这段时间中,如果队列为空,该任务将保持阻塞状态以等待队列数据有效。当其它任务或中断服务例程往其等待的队列中写入了数据,该任务将自动由阻塞态转移为就绪态。当等待的时间超过了指定的阻塞时间,即使队列中尚无有效数据,任务也会自动从阻塞态转移为就绪态。
由于队列可以被多个任务读取,所以对单个队列而言,也可能有多个任务处于阻塞状态以等待队列数据有效。这种情况下,一旦队列数据有效,只会有一个任务会被解除阻塞,这个任务就是所有等待任务中优先级最高的任务。而如果所有等待任务的优先级相同,那么被解除阻塞的任务将是等待最久的任务。

说些题外话,ucos中是具有广播消息的,当有多个任务阻塞在队列上,当发送消息的时候可以选择广播消息,那么这些阻塞的任务都能被解除阻塞。

3.写阻塞

与读阻塞想反,任务也可以在写队列时指定一个阻塞超时时间。这个时间是当被写队列已满时,任务进入阻塞态以等待队列空间有效的最长时间。
由于队列可以被多个任务写入,所以对单个队列而言,也可能有多个任务处于阻塞状态以等待队列空间有效。这种情况下,一旦队列空间有效,只会有一个任务会被解除阻塞,这个任务就是所有等待任务中优先级最高的任务。而如果所有等待任务的优先级相同,那么被解除阻塞的任务将是等待最久的任务。

消息队列的工作流程1.发送消息

任务或者中断服务程序都可以给消息队列发送消息,当发送消息时,如果队列未满或者允许覆盖入队, FreeRTOS 会将消息拷贝到消息队列队尾,否则,会根据用户指定的阻塞超时时间进行阻塞,在这段时间中,如果队列一直不允许入队,该任务将保持阻塞状态以等待队列允许入队。当其它任务从其等待的队列中读取入了数据(队列未满),该任务将自动由阻塞态转为就绪态。当任务等待的时间超过了指定的阻塞时间,即使队列中还不允许入队,任务也会自动从阻塞态转移为就绪态,此时发送消息的任务或者中断程序会收到一个错误码 errQUEUE_FULL。
发送紧急消息的过程与发送消息几乎一样,唯一的不同是,当发送紧急消息时,发送的位置是消息队列队头而非队尾,这样,接收者就能够优先接收到紧急消息,从而及时进行消息处理。
下面是消息队列的发送API接口,函数中有FromISR则表明在中断中使用的。

o4YBAGAP0tyAcqp2AABD05nzisM612.png

消息队列读取

o4YBAGAP0uqABC4FAAAxVSVZBSc338.png


任务调用接收函数收取队列消息, 函数首先判断当前队列是否有未读消息, 如果没有, 则会判断参数 xTicksToWait, 决定直接返回函数还是阻塞等待。
如果队列中有消息未读, 首先会把待读的消息复制到传进来的指针所指内, 然后判断函数参数 xJustPeeking == pdFALSE的时候, 符合的话, 说明这个函数读取了数据, 需要把被读取的数据做出队处理, 如果不是, 则只是查看一下(peek),只是返回数据,但是不会把数据清除。
对于正常读取数据的操作, 清除数据后队列会空出空位, 所以查看队列中的等待列表中是否有任务等发送数据而被挂起, 有的话恢复一个任务就绪, 并根据优先级判断是否需要出进行任务切换。
对于只是查看数据的, 由于没有清除数据, 所以没有空间新空出,不需要检查发送等待链表, 但是会检查接收等待链表, 如果有任务挂起会切换其到就绪并判断是否需要切换。

接下来,我们可以从中断再到任务这样一个流程去编写代码:

如下的框图来说明一下 FreeRTOS 消息队列的实现,让大家有一个形象的认识。

o4YBAGAP0viAbhHtAACALIk2QMw805.png

1. 中断如何处理:

///

void LpUart0_IRQHandler(void)

{

BaseType_t xHigherPriorityTaskWoken = pdFALSE;

uint8_t res=0;

// if(LPUart_GetStatus(M0P_LPUART0, LPUartPE))/*奇偶检验错误*/

// {

// LPUart_ClrStatus(M0P_LPUART0, LPUartPE);

// }

if(LPUart_GetStatus(M0P_LPUART0, LPUartRC)) ///接收数据中断

{

LPUart_ClrStatus(M0P_LPUART0, LPUartRC); ///<清接收中断请求        

res =LPUart_ReceiveData(M0P_LPUART0);

xQueueSendFromISR(usart_Queue,(void *) &res,&xHigherPriorityTaskWoken);

portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

}

}

任务中接收信号,这里并不是每一条消息都接收吗,因为没有空闲中断,而是做了100ms绝对延时,确保一帧数据接收完成。

/**

***********************************************************************

** \brief 2400波特率:'100ms = 24bytes'

**

**

** \param 1 :void

** \retval void

***********************************************************************/

void APP_LocalCOM_ReadData(void)

{

uint8_ttemp_bytes = 0; /*队列中字节长度new*/

uint8_t cnt;

static uint8_tbuff[QueueSIZE] = {0}; /*暂存接收协议,从0x68开始,用于crc计算*/

static TickType_t StartTick = 0;

static uint8_t ShadowBytes = 0;/*old*/

temp_bytes = uxQueueMessagesWaiting(usart_Queue);//检查消息数

if(temp_bytes == 0)//检查队列的长度

{

ShadowBytes = 0;

}

else

{

if(ShadowBytes != temp_bytes)//有新的数据

{

ShadowBytes = temp_bytes;

StartTick = xTaskGetTickCount();

}

else

{

if(xTaskGetTickCount() - StartTick > 100)

{

for(cnt = 0; cnt

{

xQueueReceive(usart_Queue,(void*)&buff[cnt%QueueSIZE],(TickType_t)100);//接收数据

}

protocol_parse(buff,temp_bytes);

//BSP_UARTx_SendBytes(M0P_UART0,temp_bytes, buff); //test

}

}

}

}
编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据存储
    +关注

    关注

    5

    文章

    986

    浏览量

    51145
  • FreeRTOS
    +关注

    关注

    12

    文章

    484

    浏览量

    62455
  • 队列
    +关注

    关注

    1

    文章

    46

    浏览量

    10932
收藏 人收藏

    评论

    相关推荐

    HPLC通信与云计算的结合 HPLC通信信号处理方法

    HPLC通信与云计算的结合 HPLC通信与云计算的结合是当前电力系统及物联网领域的一个重要发展趋势。以下是关于两者结合的分析: 数据实时传输与分析 : HPLC通信技术具有高速率、低延
    的头像 发表于 12-02 14:13 224次阅读

    ASR与自然语言处理结合

    。以下是对ASR与自然语言处理结合的分析: 一、ASR与NLP的基本概念 ASR(自动语音识别) : 专注于将人类的语音转换为文字。 涉及从声音信号中提取特征,并将这些特征映射到文本。 NLP(自然语言处理) : 涉及理解和解释
    的头像 发表于 11-18 15:19 563次阅读

    全志T113双核异构处理器的使用基于Tina Linux5.0——RTOS简介

    、Preempt Linux系统。 而其中的RISC-V属于超高能效副核心,标配内存管理单元,可运行RTOS或裸机程序。T113的主核运行Linux(Openwrt或者Preempt Linux)进行
    发表于 11-18 09:33

    【驱动教程】iTOP-RK3568开发板进行讲解第十三期,主要讲解输入子系统,共计24 讲

    驱动视频全新升级,并持续更新~更全,思路更科学,入门更简单。 迅为基于iTOP-RK3568开发板进行讲解,本次更新内容为第十三期,主要讲解输入子系统,共计24 讲。 学习链接 本期视频教程已上传至
    发表于 10-11 11:31

    处理器SDK RTOS定制:修改板库以更改UART实例

    电子发烧友网站提供《处理器SDK RTOS定制:修改板库以更改UART实例.pdf》资料免费下载
    发表于 10-11 09:53 0次下载
    <b class='flag-5'>处理</b>器SDK <b class='flag-5'>RTOS</b>定制:修改板库以更改UART实例

    RTOS正在缩小与Linux的差距

    RTOS与Linux的物联网设备操作系统之争已经持续了很多年。Linux以其强大的计算能力和丰富的软件生态,在需要复杂处理和软件支持的物联网设备上占据一席之地;RTOS凭借实时响应和资源节约的特性
    的头像 发表于 09-10 08:07 867次阅读
    <b class='flag-5'>RTOS</b>正在缩小与Linux的差距

    freertos和rtos区别是什么

    RTOS 的主要特点是实时性、多任务处理、资源管理、中断处理等。 FreeRTOS 是一个开源的实时操作系统,由英
    的头像 发表于 09-02 14:18 1632次阅读

    RTOS的特性和类型

    实时操作系统(RTOS)是一种可运行实时计算应用程序的软件平台,用于处理具有明确时间约束的事件和数据。与通用操作系统(GPOS)不同,RTOS必须在有限的硬件资源上调度应用程序之间的
    的头像 发表于 08-20 11:29 751次阅读

    RTOS开发最佳实践

    基于RTOS编写应用程序时,有一些要注意事项。在本节中,您将学习RTOS开发最佳实践,例如POSIX合规性、安全性和功能安全认证。
    的头像 发表于 08-20 11:24 541次阅读

    简单认识RTOS实时操作系统

    RTOS(Real Time Operating System,实时操作系统)是一种专门设计用于在严格时间限制内处理任务的操作系统。它以其高实时性、多任务处理能力和资源管理能力在工业自动化、医疗设备、航空航天、汽车电子等众多领域
    的头像 发表于 08-20 11:20 3362次阅读

    是否可以扩展esp_iot_rtos_sdk以具有api功能来进行云更新?

    是否可以扩展esp_iot_rtos_sdk以具有 api 功能来进行云更新?SDK 编程指南(尽管我认为它不适用于 rtos sdk)表明存在
    发表于 07-15 08:19

    用ESP8266_RTOS_SDK进行代码编译,如何更改tick数据

    我用ESP8266_RTOS_SDK进行代码编译,可以正常工作,但是感觉os的tick太长,默认是10ms调度一次。我尝试修改宏定义configTICK_RATE_HZ,并且重新编译了库文件libfreerots.a,但是程序运行后,tick并没有改变,请问我该怎么做?
    发表于 07-10 08:16

    ESP8266_RTOS3.0串口0传输大量数据丢包的原因?

    传输数据最大1500字节,使用的ESP8266_RTOS3.0,先使用的example示例中的uart_events,结果发现当我向串口0发送长度大约800字节的数据时,重复收到消息队列,数据
    发表于 07-09 06:32

    基于RTOS的应用进程中的典型线程

    RTOS中的关键因素是最小的中断延迟和最小的线程切换延迟。RTOS的价值在于它的响应速度或可预测性,而不是它在给定时间段内可以执行的工作量。
    发表于 03-05 09:32 714次阅读
    基于<b class='flag-5'>RTOS</b>的应用进程中的典型线程

    请问RTOS USBSetuPcb回调函数是在中断还是单独线程中处理的?

    解决这个问题,我需要知道的是:USBsetuPcb 是如何处理的。 - > 在处理 USB Setup 请求时,我的 RTOS AppThread 是否中断(并停止了? 还是在 RTO
    发表于 02-23 06:10