FreeRTOS【12】队列集使用

news2025/4/8 22:47:13

1.开发背景

        基于以上的章节,了解了 FreeRTOS 多线程间的信号量、队列的使用,已经满足了日常使用场景。这个篇章要介绍的是队列集,实际上队列的升级版,存储信号量和队列等的触发事件。

        队列集在实际的开发项目中应用相对比较少,事件存储在队列中,在一定程度上影响了系统的实时性,优点就是一个线程处理多种事件,减少了线程的个数,适合资源使用比较少的场景。

2.开发需求

        设计实验:

        1)创建 2 个线程,控制线程和接收线程

        2)控制线程发送不同的信号量和队列

        3)接收线程接收队列集后再获取对应的信息

3.开发环境

        window10 + MDK + STM32F429 + FreeRTOS10.3.1

4.实现步骤

4.1 实现编码

#include "appTest.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "mspDwt.h"
#include "mspGpio.h"
#include "mspExti.h"

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

#include "appLog.h"

/* #define configUSE_QUEUE_SETS                    1  */

typedef struct
{
    /* 信号量 */
    SemaphoreHandle_t signalBinary;
    SemaphoreHandle_t signalCount;
    
    /* 队列 */
    QueueHandle_t queue;
    
    /* 队列集 */
    QueueSetHandle_t queueSet;
    
    /* 创建任务 */
    TaskHandle_t taskCtrl;
    TaskHandle_t taskRx;      
    
}Ctrl_t;

/* 文件指针 */
static Ctrl_t s_ctrl = {0};
static Ctrl_t *p = &s_ctrl;
static void TaskCtrl(void *pvParameters);
static void TaskRx(void *pvParameters);

static void TaskCtrl(void *pvParameters)
{
    /* 发送信号量 */
    xSemaphoreGive(p->signalCount);     // 1
    xSemaphoreGive(p->signalBinary);    // 2
    xSemaphoreGive(p->signalCount);     // 3
    
    /* 发送队列 */
    for (int i = 0; i < 3; i++)
    {
        xQueueSend(p->queue, &i, 100);  // 4,5,6
    }
    
    /* 发送信号量 */
    xSemaphoreGive(p->signalCount);     // 7
    xSemaphoreGive(p->signalCount);     // 8
    
    for ( ; ; )
    {
        vTaskDelay(1000);
    }
}

/* 接收线程 */
static void TaskRx(void *pvParameters)
{
    vTaskDelay(100);
    QueueSetMemberHandle_t member = 0;
    
    for ( ; ; )
    {
        /* 等待队列组触发 */
        member = xQueueSelectFromSet(p->queueSet, portMAX_DELAY);
        
        /* 解析成员句柄并提取对应的数据 */
        if (member == p->signalBinary)
        {
            /* 接收到二值信号量 */
            xSemaphoreTake(p->signalBinary, 0);
            Log_Debug("%s 接收到二值信号量\r\n", __func__);
        }
        else if (member == p->signalCount)
        {
            /* 接收到计数信号量 */
            xSemaphoreTake(p->signalCount, 0);
            Log_Debug("%s 接收到计数信号量\r\n", __func__);
        }
        else if (member == p->queue)
        {
            /* 接收到队列 */
            static unsigned int queueRx = 0;
            xQueueReceive(p->queue, &queueRx, 0);
            Log_Debug("%s 接收到队列, queueRx = %d\r\n", __func__, queueRx);
            
        }
        else
        {
            Log_Error("%s 异常 else\r\n", __func__);
        }
    }
}

/* 测试初始化 */
void aTest_Init(void)
{
    /* 创建二值信号量 */
    p->signalBinary = xSemaphoreCreateBinary();
    
    /* 创建计数信号量 */
    UBaseType_t uxMaxCount = 5;
    p->signalCount = xSemaphoreCreateCounting(uxMaxCount, 0);
    
    /* 创建队列 */
    UBaseType_t uxQueueLength = 10;
    UBaseType_t uxItemSize = sizeof(unsigned int);
    p->queue  = xQueueCreate(uxQueueLength, uxItemSize);
    
    /* 创建队列集 二值信号量=1,计数信号量=最大计数值 队列=队长 */
    UBaseType_t uxEventQueueLength = 1 + uxMaxCount + uxQueueLength;
    p->queueSet = xQueueCreateSet(uxEventQueueLength);
    
    /* 添加成员到队列集 */
    xQueueAddToSet(p->signalBinary, p->queueSet);
    xQueueAddToSet(p->signalCount, p->queueSet);
    xQueueAddToSet(p->queue, p->queueSet);
    
    /* 创建动态任务 */
    xTaskCreate(TaskCtrl, "TaskCtrl",  500, NULL, 4, &p->taskCtrl);
    xTaskCreate(TaskRx,   "TaskRx",    500, NULL, 4, &p->taskRx);
}

/* Key2 PC13   Key0 PH3 Key1 PH2 */
void Exti13_TriggerInterrupt(void)
{
    mspExti_Close(13);
    
    if (mspGpio_GetInput("PC13") == 0)
    {
        
    }
}

在使用 uxEventQueueLength 的时候需要特别注意,

    /* 创建二值信号量 */
    p->signalBinary = xSemaphoreCreateBinary();
    
    /* 创建计数信号量 */
    UBaseType_t uxMaxCount = 5;
    p->signalCount = xSemaphoreCreateCounting(uxMaxCount, 0);
    
    /* 创建队列 */
    UBaseType_t uxQueueLength = 10;
    UBaseType_t uxItemSize = sizeof(unsigned int);
    p->queue  = xQueueCreate(uxQueueLength, uxItemSize);
    
    /* 创建队列集 二值信号量=1,计数信号量=最大计数值 队列=队长 */
    UBaseType_t uxEventQueueLength = 1 + uxMaxCount + uxQueueLength;
    p->queueSet = xQueueCreateSet(uxEventQueueLength);
    
    /* 添加成员到队列集 */
    xQueueAddToSet(p->signalBinary, p->queueSet);
    xQueueAddToSet(p->signalCount, p->queueSet);
    xQueueAddToSet(p->queue, p->queueSet);

4.2 结果显示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1717778.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux同步搭建多台服务器

前言&#xff1a; 如果在安装服务器的过程中&#xff0c;需要安装多台服务器&#xff0c;同样的配置&#xff0c;同样的步骤就可以使用此方法&#xff0c;搭建集群同步安装 1.配置网卡 想要两台机器进行同步的话&#xff0c;必须网段是同样的&#xff0c;保持在同一网段并且能…

科技智慧园区解决方案

随着科技创新的推动和城市化进程的加速&#xff0c;城市面临着诸多挑战和机遇。如何提升城市的竞争力和可持续性&#xff0c;是一个亟待解决的问题。在这个背景下&#xff0c;科技智慧园区作为一种新型的城市发展模式&#xff0c;引起了越来越多的关注和探索。 什么是科技智慧园…

Jmeter的线程组之间传递参数

使用jemter做接口测试&#xff0c;有时候需要会遇到不同线程组之间调用相同变量的情况&#xff0c;最多见的就是token的传递&#xff0c;网上有很多处理方法&#xff0c;这里只记录setProperty的办法&#xff0c;一招鲜走遍天&#xff01; 首先我有两个线程组&#xff1a; 线程…

Servlet搭建博客系统

现在我们可以使用Servlet来搭建一个动态(前后端可以交互)的博客系统了(使用Hexo只能实现一个纯静态的网页,即只能在后台自己上传博客)。有一种"多年媳妇熬成婆"的感觉。 一、准备工作 首先创建好项目,引入相关依赖。具体过程在"Servlet的创建"中介绍了。…

WiFi蓝牙模块促进传统零售数字化转型:智能零售体验再升级

随着科技的不断发展&#xff0c;数字化转型已经成为了各行各业的必然趋势。在传统零售业中&#xff0c;WiFi蓝牙模块的应用正逐渐推动着行业的数字化转型&#xff0c;为消费者带来更加智能化、便捷化的零售体验。本文MesoonRF美迅物联网将从以下几个方面阐述WiFi蓝牙模块在传统…

Claude 3可使用第三方API,实现业务流程自动化

5月31日&#xff0c;著名大模型平台Anthropic宣布&#xff0c;Claude3模型可以使用第三方API和工具。 这也就是说&#xff0c;用户通过文本提问的方式就能让Claude自动执行多种任务&#xff0c;例如&#xff0c;从发票中自动提取姓名、日期、金额等&#xff0c;该功能对于开发…

GCN 代码解析(一) for pytorch

Graph Convolutional Networks 代码详解 前言一、数据集介绍二、文件整体架构三、GCN代码详解3.1 utils 模块3.2 layers 模块3.3 models 模块3.4 模型的训练代码 总结 前言 在前文中&#xff0c;已经对图卷积神经网络&#xff08;Graph Convolutional Neural Networks, GCN&am…

linux nohup命令详解:持久运行命令,无视终端退出

nohup &#xff08;全称为 “no hang up”&#xff09;&#xff0c;用于运行一个命令&#xff0c;使其在你退出 shell 或终端会话后继续运行。 基本语法 nohup command [arg1 ...] [&> output_file] &command 是你想要运行的命令。[arg1 ...] 是该命令的参数。&am…

STM32-14-FSMC_LCD

STM32-01-认识单片机 STM32-02-基础知识 STM32-03-HAL库 STM32-04-时钟树 STM32-05-SYSTEM文件夹 STM32-06-GPIO STM32-07-外部中断 STM32-08-串口 STM32-09-IWDG和WWDG STM32-10-定时器 STM32-11-电容触摸按键 STM32-12-OLED模块 STM32-13-MPU 文章目录 1. 显示器分类2. LCD简…

【稳定检索/投稿优惠】2024年语言、文化与艺术发展国际会议(LCAD 2024)

2024 International Conference on Language, Culture, and Art Development 2024年语言、文化与艺术发展国际会议 【会议信息】 会议简称&#xff1a;LCAD 2024大会时间&#xff1a;2024-08-10截稿时间&#xff1a;2024-07-27(以官网为准&#xff09;大会地点&#xff1a;中国…

【数学不建模】赛程安排

你所在的年级有5个班&#xff0c;每班一支球队在同一块场地上进行单循环赛, 共要进行10场比赛. 如何安排赛程使对各队来说都尽量公平呢. 下面是随便安排的一个赛程: 记5支球队为A, B, C, D, E&#xff0c;在下表左半部分的右上三角的10个空格中, 随手填上1,2,10, 就得到一个赛程…

新书推荐:9.5堆栈图解析生命周期

本节必须掌握的知识点&#xff1a; 掌握局部变量、全局变量存放在哪 熟练画堆栈图 掌握每个函数从哪开始被调用的&#xff0c;从哪结束的 开始看本节前&#xff0c;请读者思考如下几问题&#xff1a; 局部变量存放在哪里&#xff1f;全局变量存放在哪里&#xff1f;编译器是怎…

FPGA新起点V1开发板(七-语法篇)——程序框架+高级语法(选择性做笔记)

文章目录 一、模块结构二、赋值三、条件语句 一、模块结构 默认是wire类型&#xff0c;assign是定义功能。 上面这两个always都是并行 例化 二、赋值 有两种赋值“”和“<” “”是阻塞赋值&#xff0c;也就是从上到下&#xff0c;依次完成 “”是非阻塞赋值&#xff0c;…

uniapp实现图片上传——支持APP、微信小程序

uniapp实现图片、视频上传 文章目录 uniapp实现图片、视频上传效果图组件templatejs 使用 相关文档&#xff1a; 结合 uView 插件 uni.uploadFile 实现 u-upload uploadfile 效果图 组件 简单封装&#xff0c;还有很多属性…&#xff0c;自定义样式等…根据个人所需调整 te…

element中table的selection-change监听改变的那条数据的下标

<el-table ref"table" :loading"loading" :data"tableData" selection-change"handleSelectionChange"></el-table>当绑定方法selection-change&#xff0c;当选择项发生变化时会触发该事件 // 多选框选中数据handleSele…

App自动化测试_Python+Appium使用手册

一、Appium的介绍 Appium是一款开源的自动化测试工具&#xff0c;支持模拟器和真机上的原生应用、混合应用、Web应用&#xff1b;基于Selenium二次开发&#xff0c;Appium支持Selenium WebDriver支持的所有语言&#xff08;java、 Object-C 、 JavaScript 、p hp、 Python等&am…

链动3+1模式:数字化转型中的创新商业发展路径

在数字化时代&#xff0c;企业为了保持竞争力&#xff0c;不断探索和尝试新的商业模式。链动31模式作为一种创新的商业模式&#xff0c;以其独特的运作机制&#xff0c;为企业和个人带来了全新的发展机遇。本文将对链动31模式进行深入解析&#xff0c;并通过与传统链动模式的对…

Github 如何配置 PNPM 的 CI 环境

最近出于兴趣在写一个前端框架 echox&#xff0c;然后在 Github 上给它配置了最简单的 CI 环境&#xff0c;这里简单记录一下。 特殊目录 首先需要在项目根目录里面创建 Github 仓库中的一个特殊目录&#xff1a;.github/workflows&#xff0c;用于存放 Github Actions 的工作…

vm-bhyve:bhyve虚拟机的管理系统@FreeBSD

先说情况&#xff0c;当前创建虚拟机后网络没有调通....不明白是最近自己点背&#xff0c;还是确实有难度... 缘起&#xff1a; 前段时间学习bhyve虚拟机&#xff0c;发现bvm这个虚拟机管理系统&#xff0c;但是实践下来发现网络方面好像有问题&#xff0c;至少我花了两天时间…

自动化捡洞/打点必备神器

工具介绍 毒液流量转发器Venom-Transponder&#xff1a;自动化捡洞/打点/跳板必备神器&#xff0c;支持联动URL爬虫、各种被动扫描器&#xff1b;该工具支持在mac/windows/linux等系统上使用。 该流量转发器诞生背景&#xff1a; 鉴于平时挖洞打点时用到被动扫描器&#xff0…