FreeRTOS【15】事件组使用

1.开发背景

        基于以上的章节,了解了 FreeRTOS 多线程间的信号量、队列的使用,已经满足了日常使用场景。其中信号量可以实现线程同步,对标的是裸机的 Flag 标识,但是在裸机中经常使用的不止一个标识,如果用二值信号量去实现无疑是增加了系统内存开销,申请多个信号量,实现本质是队列,消耗比较大并且带有迟滞性,所以 FreeRTOS 针对这种情况设计了事件组。

        事件组是按 bit 操作的,每一个位都可以触发事件,需要注意的是时钟的配置会影响可用的位配置,源码解释如果设置 configUSE_16_BIT_TICKS 系统时钟 16 位,只能用 0~7bit,否则可以使用 0~23 bit。

2.开发需求

设计实验1:位事件设置和等待

        1)创建 2 个线程,设置位事件线程和等待位事件线程

        2)设置位事件线程分别设置 bit0、bit0 和 bit4、bit4

        3)等待位事件线程等待信号并输出对应日志

设计试验2:位事件同步

        1)创建 2 个线程,同步线程1 控制 bit0, 同步线程2 控制 bit1

        2)同步线程1 每 1s 同步一次,同步线程 2 每 2s 同步一次

        3)观察线程同步的实时性。

3.开发环境

        window10 + MDK + STM32F429 + FreeRTOS10.3.1

4.实现步骤

4.1 位事件设置和等待

4.1.1 实现编码

重点关注 xEventGroupWaitBits 的参数

uxBitsToWaitFor:        等待关注的事件(bit)

xClearOnExit:             是否清空,一般设置为是,清空不会反复触发

xWaitForAllBits:          是否等待所有位都满足条件才触发,看需求

#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 "stream_buffer.h"
#include "event_groups.h"

#include "appLog.h"

typedef struct
{
    /* 事件组 */
    EventGroupHandle_t event;
    
    /* 任务线程 */
    TaskHandle_t taskEventWait; // 接收线程
    TaskHandle_t taskEventSet;  // 发送线程
    
}Ctrl_t;

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

#define BIT_0   ( 1 << 0 )
#define BIT_1   ( 1 << 1 )
#define BIT_2   ( 1 << 2 )
#define BIT_3   ( 1 << 3 )
#define BIT_4   ( 1 << 4 )

#define ALL_SYNC_BITS ( BIT_0 | BIT_4 )

/* 接收线程 */
static void TaskEventWait(void *pvParameters)
{
    vTaskDelay(100);
   
    for ( ; ; )
    {
        EventBits_t uxBits = xEventGroupWaitBits(p->event, ALL_SYNC_BITS, pdTRUE, pdFALSE, portMAX_DELAY);
        
        switch (uxBits)
        {
            case ALL_SYNC_BITS:
                Log_Debug("%s 触发 bit0 和 bit4\r\n", __func__);
                break;
            
            case BIT_0:
                Log_Debug("%s 触发 bit0\r\n", __func__);
                break;
            
            case BIT_4:
                Log_Debug("%s 触发 bit4\r\n", __func__);
                break;
            
            default:
                break;
        }
        
        vTaskDelay(100);
    }
}

/* 发送线程 */
static void TaskEventSet(void *pvParameters)
{
    vTaskDelay(1000);
    EventBits_t uxBits = 0;
    
    /* 设置 bit0 */
    uxBits &= 0x00000000;
    uxBits |= BIT_0;
    xEventGroupSetBits(p->event, uxBits);
    vTaskDelay(100);
    
    /* 设置 bit0 和 bit4 */
    uxBits &= 0x00000000;
    uxBits |= BIT_0 | BIT_4;
    xEventGroupSetBits(p->event, uxBits);
    vTaskDelay(100);
    
    /* 设置 bit4 */
    uxBits &= 0x00000000;
    uxBits |= BIT_4;
    xEventGroupSetBits(p->event, uxBits);
    vTaskDelay(100);
    
    for ( ; ; )
    {
        vTaskDelay(1000);
    }
}

/* 测试初始化 */
void aTest_Init(void)
{
    /* 创建事件组 */
    p->event = xEventGroupCreate();
    
    /* 创建动态任务 */
    xTaskCreate(TaskEventWait, "TaskEventWait", 500, NULL, 5, &p->taskEventWait);
    xTaskCreate(TaskEventSet,  "TaskEventSet",  500, NULL, 5, &p->taskEventSet);
}

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

4.2 位事件同步

        位事件同步主要实现多线程同步执行,相互等待,调用 xEventGroupSync,会先设置位在阻塞等待位,相当与 xEventGroupSetBits() + xEventGroupWaitBits();

4.2.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 "stream_buffer.h"
#include "event_groups.h"

#include "appLog.h"

typedef struct
{
    /* 事件组 */
    EventGroupHandle_t event;
    
    /* 任务线程 */
    TaskHandle_t taskEventSync1;  // 线程
    TaskHandle_t taskEventSync2;  // 线程
    
}Ctrl_t;

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

#define BIT_0   ( 1 << 0 )
#define BIT_1   ( 1 << 1 )
#define BIT_2   ( 1 << 2 )
#define BIT_3   ( 1 << 3 )
#define BIT_4   ( 1 << 4 )

#define ALL_SYNC_BITS (BIT_0 | BIT_1)

/* 线程 */
static void EventSyncTask1(void *pvParameters)
{
    vTaskDelay(100);
   
    for ( ; ; )
    {
        /* 设置 bit0 */
        Log_Debug("%s Sync Set Bit0\r\n", __func__);
        EventBits_t uxBits = xEventGroupSync(p->event, BIT_0, ALL_SYNC_BITS, portMAX_DELAY);
        Log_Debug("%s Sync OK\r\n", __func__);
        
        vTaskDelay(1000);
    }
}

/* 线程 */
static void EventSyncTask2(void *pvParameters)
{
    vTaskDelay(1000);
    
    for ( ; ; )
    {
        /* 设置 bit1 */
        Log_Debug("%s Sync Set Bit1\r\n", __func__);
        EventBits_t uxBits = xEventGroupSync(p->event, BIT_1, ALL_SYNC_BITS, portMAX_DELAY);
        Log_Debug("%s Sync OK\r\n", __func__);
        
        vTaskDelay(2000);
    }
}

/* 测试初始化 */
void aTest_Init(void)
{
    /* 创建事件组 */
    p->event = xEventGroupCreate();
    
    /* 创建动态任务 */
    xTaskCreate(EventSyncTask1, "EventSyncTask1", 500, NULL, 5, &p->taskEventSync1);
    xTaskCreate(EventSyncTask2, "EventSyncTask2", 500, NULL, 5, &p->taskEventSync2);
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式Linux内核调试之使用模块参数详解

基本要求 环境: 处理器架构:arm64 内核源码:linux-6.6.29 ubuntu版本:20.04.1 代码阅读工具:vim+ctags+cscope 本文主要介绍内核开发中常用的模块传参手段,通过模块参数传递可以通过用户态来获取内核的一些信息,也可以通过用户态写入一些值来控制内核相关行为。一般内核…

PDF软件PDF Extra Premium + Ultimate 9.30.56026

PDF Extra Premium是一个适用于Windows的程序,它提供了所有功能,***在一个地方处理PDF文件的需要。使用此程序,您可以: 扫描和识别文本。您可以轻松地将纸质文档扫描并数字化为可编辑的PDF文件。您可以使用手机的摄像头扫描任何类型的纸质文档:支票、合同、票据、票据、证…

Gitlab---添加描述模版

0 Preface/Foreword Gitlab是代码托管平台&#xff0c;DevOps。因其免费&#xff0c;被广泛使用。GitLab不但可以管理代码&#xff0c;也可以管理issue&#xff0c;创建milestone等等。针对issue管理&#xff0c;支持描述模版功能&#xff0c;即对于新建的issue&#xff0c;可…

Golang | Leetcode Golang题解之第130题被围绕的区域

题目&#xff1a; 题解&#xff1a; var (dx [4]int{1, -1, 0, 0}dy [4]int{0, 0, 1, -1} ) func solve(board [][]byte) {if len(board) 0 || len(board[0]) 0 {return}n, m : len(board), len(board[0])queue : [][]int{}for i : 0; i < n; i {if board[i][0] O {q…

软件测试、测试模型、测试用例

软件开发的五个模型 瀑布模型&#xff08;Waterfall Model&#xff09; 瀑布模型是所有其他模型的基础框架&#xff0c;瀑布模型的每个阶段都只执行一次&#xff0c;因此是线性顺序进行的开发模式优点&#xff1a;强调开发的阶段性&#xff1b; 强调早期计划及需求调查&#…

重新ysyx

一、克隆仓库 1.创建ssh key ssh-keygen -t rsa cd ~/.ssh ls 查看里面是否有id_rsa id_rsa.pub ssh-keygen -t rsa -C "xiantong15834753336outlook.com" cat id_rsa.pub***********查看里面的内容&#xff0c;复制到下图中绿色的按钮 git init ssh -T g…

【活动通知 — 线上 Meetup】:ES|QL 及 B 站 Elasticsearch 平台实践 - 6 月 19 日

会议时间 2024年6月19日 19:00 — 21:00 参与方式 线上直播&#xff1a;Elastic 中国社区官方博客&#xff0c;elasticstack B 站号。链接请参考下面的报名地址。 活动议程 19:00-19:50 主题演讲&#xff1a;Elasticsearch 简单而高效的管道查询语言 - ES|QL 讲师&#xff…

【Linux-Makefile,编译】

Linux-Makefile&#xff0c;编译 ■ linux 编译生成bin文件■■■ ■ linux 编译生成bin文件 这个bin文件&#xff0c;pc指针指定这个位置就能运行bin文件代码。 ■ ■ ■

HCL模拟器下做M-LAG测试(以及和华为配置对比)-二层架构

1.简单二层架构 1.1 拓扑图 1.2 配置 1.2.1 Leaf1配置 system-mac必须配置&#xff0c;否则会有一个node处于unknown状态&#xff0c;即使配置主节点的mac&#xff0c;主节点也需要配置system-mac为自己的mac ## M-LAG配置[Leaf1] m-lag system-mac 0001-0001-0001 # 手动设…

线性代数|机器学习-P5特征值和特征向量

文章目录 1. 特征值和特征向量1.1 特征向量1.2 向量分解 2. 矩阵相似2.1 特征值求解法-相似2.2 特殊特征值2.3 反对称矩阵 3.对称矩阵 1. 特征值和特征向量 1.1 特征向量 假设有一个n行n列的方阵A&#xff0c;有 n 个不相同的特征值为 λ \lambda λ,特征向量为 x 1 , x 2 , …

Llama.cpp大模型量化简明手册

大型语言模型 (LLM)&#xff0c;尤其是像 Mixtral 8x7b&#xff08;467 亿个参数&#xff09;这样的大型模型&#xff0c;对内存的要求非常高。当你尝试降低推理成本、提高推理速度或在边缘设备上进行推理时&#xff0c;这种内存需求就会变得明显。解决此问题的一个潜在方法是量…

一款小众清新的Typecho主题

源码介绍 DearLicy主题&#xff0c;一款小众化小清新风格的博客主题 主题支持Typecho所支持的所有版本PHP 简约、小众、优雅 源码截图 安装教程 将主题上传至/usr/themes/文件夹下解压后台进行启用访问前台查看效果 源码下载 https://www.qqmu.com/3378.html

网络编程(八)

网络编程&#xff08;八&#xff09; 数据库数据库的分类基于嵌入式的数据库什么是SQLite?为什么使用SQLite?sqlite3数据库的安装 sqlite3中的点命令.open 数据库文件名字.tables [数据库文件名].schema 表名.database.quit.head on.mode column SQLite数据库中的数据类型SQL…

JAVA设计模式-策略模式及在Springboot2.X中写法

JAVA设计模式-策略模式及在Springboot2.X中写法 一、经典的策略模式写法二、Springboot2.X中策略模式写法 策略模式的定义&#xff1a;策略模式是一种行为型设计模式,定义了一系列算法,并将每个算法封装起来,使它们可以互相替换 策略模式&#xff1a;在策略模式&#xff08;Str…

【已解决】记录Vue2.x中npm install下载依赖报错:python2 Error: not found: python2问题(具体操作步骤)

项目场景&#xff1a; 项目场景&#xff1a;在项目开发中&#xff0c;升级了本地node版本后&#xff0c;重新npm install下载依赖报错找不到python环境 not found: python2 npm ERR! gyp verb check python checking for Python executable “python2” in the PATH 在尝试了各…

k8s——pod集群调度及相关操作

一、集群调度概念 1.1 调度约束&#xff08;List-Watch&#xff09; Kubernetes是通过List-Watch的机制进行每个组件的协作&#xff0c;保持数据同步的&#xff0c;每个组件之间的设计实现了解耦。 用户是通过kubectl根据配置文件&#xff0c;向APIServer发送命令&#xff0c;在…

进入mysql报错:bash:/bin/mysql:没有那个文件或目录

问题分析&#xff1a; 有可能把/bin下面的mysql文件删除 解决方案&#xff1a; 卸载已安装MySQL&#xff0c;重新安装一遍 卸载步骤&#xff1a; 在CentOS系统中卸载MySQL可以通过以下步骤进行&#xff1a; 1、停止MySQL服务&#xff1a; sudo systemctl stop mysqld 2…

QT 音乐播放器【二】 歌词同步+滚动+特效

文章目录 效果图概述代码解析歌词歌词同步歌词特效 总结 效果图 概述 先整体说明一下这个效果的实现&#xff0c;你所看到的歌词都是QGraphicsObject&#xff0c;在QGraphicsView上绘制(paint)出来的。也就是说每一句歌词都是一个图元(item)。 为什么用QGraphicsView框架&…

【JS实战02】轮播图

一&#xff1a;HTML页面结构 1 整体外观 2 HTML结构以及CSS样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

HTML静态网页成品作业(HTML+CSS)—— 美食湘菜介绍网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…