FreeRTOS学习七(事件标志组)

2023-05-16

        RTOS中可以通过信号量来完成同步,但是信号量只能与单个的事件或任务进行同步。有时某个任务可能会需要与多个事件或任务进行同步,此时信号量就无法满足要求了。事件标志组就排上了用场。

事件位(事件标志)

        事件位用来表明某个事件是否发生,事件位通常用于事件标志。比如有个事件需要处理,则将某个标志位置1。没有事件要处理,则置0.

事件组

        一个事件组就是一组的事件位,事件组中的事件位通过位编号来访问。比如事件标志组的Bit0表示任务0需要处理,bit1表示任务1需要处理,bit2表示任务2需要处理。

        事件标志组的事件标志位类型为EventBits。

typedef TickType_t EventBits_t;

#if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffff
#else

typedef uint32_t TickType_t;
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do
not need to be guarded with a critical section. */
#define portTICK_TYPE_IS_ATOMIC 1
#endif

        可以看到EventBits的类型是TickType,而TickType的类型根据configUSE_16_BIT_TICKS标志来,该标志位1时,TickType类型为uint16_t 。该标志位0时,TickType类型为uint32_t。EventBits的变量可以存储24个事件位另外高8位有其他用。事件位0存放在变量的bit0上,变量的Bit1就是事件位1,以此类推。

1.xEventGroupCreate()创建事件标志组(动态内存)

此函数用于创建一个事件标志组,所需要的内存通过动态内存管理方法分配。

函数原型:

EventGroupHandle_t xEventGroupCreate( void )

参数:无

返回值:

NULL:创建失败

其他值:创建成功的事件标志组句柄

实例:

EventGroupHandle_t xCreatedEventGroup;

xCreatedEventGroup = xEventGroupCreate();

2.xEventGroupCreateStatic() 创建事件标志组(静态内存)

函数原型:

EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) 

参数:

pxEventGroupBuffer :参数指向一个StaticEventGroup_t类型的变量,用来保存事件标志组结构体

返回值:

NULL:失败

其他值:成功的时间标志组句柄

实例:

StaticEventGroup_t xEventGroupBuffer;xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );

3.xEventGroupSetBits()将指定事件位置1

函数原型:

EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION;

参数:

xEventGroup:要操作的事件标志组

uxBitsToSet :指定要置1的事件位,比如要将Bit3置1的话,就设置为0x08。可以同时将多个bit置1.

返回值:

任何值:在将指定事件置1后的事件组值

实例:

EventBits_t uxBits;

uxBits = xEventGroupSetBits(

    xEventGroup, // The event group being updated.

    BIT_0 | BIT_4 );// The bits being set.

4.xEventGroupSetBitsFromISR()中断中将指定事件位置1

函数原型:

BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;

参数:

xEventGroup:要操作的事件标志组

uxBitsToSet :指定要置1的事件位,比如要将Bit3置1的话,就设置为0x08。可以同时将多个bit置1.

pxHigherPriorityTaskWoken:标记退出此函数后是否进行任务切换。当设置为pdTRUE时,退出中断服务函数之前一定会进行一次任务切换。

返回值:

pdPASS:成功

pdFALSE:失败

实例:

xHigherPriorityTaskWoken = pdFALSE;

xResult = xEventGroupSetBitsFromISR(

    xEventGroup, // The event group being updated.

    BIT_0 | BIT_4   // The bits being set.

    &xHigherPriorityTaskWoken );

5.xEventGroupClearBits()清除指定事件位

函数原型:

EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;

参数:

xEventGroup:要操作的时间标志组的句柄

uxBitsToClear :要清零的事件位。可以同时清除多个Bit

返回值:

任何值:将指定事件位清零之前的事件组值

实例:

EventBits_t uxBits;

uxBits = xEventGroupClearBits(

    xEventGroup, // The event group being updated.

    BIT_0 | BIT_4 );// The bits being cleared.

6.xEventGroupClearBitsFromISR()中断中清除指定事件位

函数原型:

BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION;

参数:

xEventGroup:要操作的时间标志组的句柄

uxBitsToClear :要清零的事件位。可以同时清除多个Bit

返回值:

pdPASS:成功

pdFAIL:失败

实例:

xResult = xEventGroupClearBitsFromISR(

xEventGroup,  // The event group being updated.

BIT_0 | BIT_4 ); // The bits being set.

7.xEventGroupGetBits()获取当前事件标志组值

函数原型:

#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 )

参数:

xEventGroup :要获取的事件标志组的句柄

返回值:

当前标志组的值

实例:

EventBits_t xResult

xResult  = xEventGroupGetBits(xEventGroup)

8.xEventGroupGetBitsFromISR()中断中获取当前事件标志组值

函数原型:

EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION;

参数:

xEventGroup :要获取的事件标志组的句柄

返回值:

当前标志组的值

实例:

EventBits_t xResult

xResult  = xEventGroupGetBitsFromISR(xEventGroup)

9.xEventGroupWaitBits()等待时间标志位

        某个任务可能需要与多个事件进行同步,那么这个任务就需要等待并判断多个事件位(标志)。调用该函数后如果任务要等待的事件位还没有准备好(置1或清零)的话,任务就会进入阻塞状态,直到阻塞时间到达或者所等待的时间位准备好

函数原型:

EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION;

参数:

xEventGroup:指定要等待的事件标志组

uxBitsToWaitFor:指定要等待的事件位。比如要等待bit0和(或)bit1,此参数为0x03

xClearOnExit:在退出此函数之前由参数uxBitsToWaitFor所设置的这些事件位是否清零。pdTRUE清零。pdFALSE不清零。

xWaitForAllBits:此参数为pdTRUE时,当uxBitsToWaitFor所设置的这些事件位都置1,或者指定的阻塞时间到的时候,才会返回。当为pdFALSE,只要uxBitsToWaitFor所设置的这些事件位其中的任意一个置1,或者指定的阻塞时间到,才返回。

xTicksToWait:设置阻塞时间

返回值:

        返回当所等待的事件位置1以后的时间标志组的值,或阻塞时间到。根据这个值就知道哪些时间位置1了。如果函数因为阻塞时间到而返回的话,该返回值不代表任何含义。

实例:

EventBits_t uxBits;
uxBits = xEventGroupWaitBits(
    xEventGroup, // The event group being tested.
    BIT_0 | BIT_4, // The bits within the event group to wait for.
    pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
    pdFALSE, // Don't wait for both bits, either bit will do.
    xTicksToWait ); // Wait a maximum of 100ms for either bit to be set.

if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
{
// bit0和bit4都被检测到
}
else if( ( uxBits & BIT_0 ) != 0 )
{
// bit0被检测到
}
else if( ( uxBits & BIT_4 ) != 0 )
{
// bit4被检测到
}
else
{
// 超时
}

代码验证:

        创建3个任务,任务1创建一个1秒的周期定时器,在定时器回调中设置标志位bit0。任务2以1.5秒周期置标志位Bit1。任务3以1秒周期置标志位Bit2。任务1中等待标志位。等待到之后自动清除标志位。

任务1

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

EventGroupHandle_t xCreatedEventGroup;
void vTimerCallback( TimerHandle_t pxTimer )
{
    configASSERT( pxTimer );
    static uint32_t time_cnt = 0;
    time_cnt++;
    int32_t lArrayIndex = 0;
    lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer );
    LOG_I(common,"[DEBUG]:timer name:%stimer id:%d",pcTimerGetName(pxTimer),lArrayIndex);
    if(lArrayIndex = timer_id)
    {
        LOG_I(common,"[DEBUG]:time cnt:%d",time_cnt);
        LOG_I(common,"[TIMER]:BIT0 set");
        xEventGroupSetBits(xCreatedEventGroup,BIT_0);
    }
}

static void vTestTask1_H(void *pvParameters)
{
    xCreatedEventGroup = xEventGroupCreate();   //创建事件组
    xTimer_test = xTimerCreate("Test timer",       /* Just a text name, not used by the kernel. */
                                    (1000 / portTICK_PERIOD_MS),    /* The timer period in ticks. */
                                     pdTRUE,        /* The timers will auto-reload themselves when they expire. */
                                     (void *)timer_id,   /* Assign each timer a unique id equal to its array index. */
                                     vTimerCallback /* Each timer calls the same callback when it expires. */
                                    );
    if(xTimer_test == NULL)   
    {
        LOG_I(common,"[TASK1]:Timer create fail");  //失败
    }
    else
    {
        LOG_I(common,"[TASK1]:Timer create sucess");  //成功
        if( xTimerStart( xTimer_test, 0 ) != pdPASS )
        {
          LOG_I(common,"[TASK1]:Timer start fail");  //失败
        }
    }
    EventBits_t uxBits;
    while(1)
    {
        LOG_I(common,"[TASK1]:wait event group");
        uxBits = xEventGroupWaitBits(
                xCreatedEventGroup, // The event group being tested.
                BIT_0 | BIT_1 | BIT_2 | BIT_3, // The bits within the event group to wait for.
                pdTRUE, // BIT_0 and BIT_4 should be cleared before returning.
                pdFALSE, // Don't wait for both bits, either bit will do.
                portMAX_DELAY ); // Wait a maximum of 100ms for either bit to be set.

        LOG_I(common,"[DEBUG]:event group,rst:%d",xEventGroupGetBits(xCreatedEventGroup));
        if(uxBits & BIT_0)
        {
            LOG_I(common,"[DEBUG]:event group BIT0 get");
        }
        if(uxBits & BIT_1)
        {
            LOG_I(common,"[DEBUG]:event group BIT1 get");
        }
        if(uxBits & BIT_2)
        {
            LOG_I(common,"[DEBUG]:event group BIT2 get");
        }
        if(uxBits & BIT_3)
        {
            LOG_I(common,"[DEBUG]:event group BIT3 get");
        }
}

任务2

static void vTestTask2_M(void *pvParameters)
{
    while(1)
    {
        LOG_I(common,"[TASK2]:BIT1 set");
        xEventGroupSetBits(xCreatedEventGroup,BIT_1);
        vTaskDelay(1500);
    }
}

任务3

static void vTestTask3_L(void *pvParameters)
{
    while(1)
    {
        LOG_I(common,"[TASK3]:BIT2 set");
        xEventGroupSetBits(xCreatedEventGroup,BIT_2);
         vTaskDelay(500);
    }
}

结果:

结果分析:

  1. 等待事件组
  2. Bit1置位
  3. 事件组BIT1被检测到。当前事件组为0
  4. 等待事件组
  5. Bit2置位
  6. 事件组BIT2被检测到。当前事件组为0
  7. Bit0置位
  8. 事件组BIT0检测到。当前事件组为0

        从结果可以看到,因为等待事件组的函数设置了返回后清除标志位,所以每次在检测到事件组之后获取事件组,结果都是0.

将等待事件组参数设置为不清除,然后手动清除

LOG_I(common,"[TASK1]:wait event group");

        uxBits = xEventGroupWaitBits(
                    xCreatedEventGroup, // The event group being tested
                    BIT_0 | BIT_1 | BIT_2 | BIT_3, // The bits within the event group to wait for.
                    pdFALSE, // BIT_0 and BIT_4 should be cleared before returning.
                    pdFALSE, // Don't wait for both bits, either bit will do
                    portMAX_DELAY ); // Wait a maximum of 100ms for either bit to be set.
        LOG_I(common,"[DEBUG]:event                             group,rst:%d",xEventGroupGetBits(xCreatedEventGroup));
        if(uxBits & BIT_0)
        {
            LOG_I(common,"[DEBUG]:event group BIT0 get");
            xEventGroupClearBits(xCreatedEventGroup,BIT_0);
            LOG_I(common,"[DEBUG]:event group BIT0         clean,rst:%d",xEventGroupGetBits(xCreatedEventGroup));
        }
        if(uxBits & BIT_1)
        {
            LOG_I(common,"[DEBUG]:event group BIT1 get");
            xEventGroupClearBits(xCreatedEventGroup,BIT_1);
            LOG_I(common,"[DEBUG]:event group BIT1 clean,rst:%d",xEventGroupGetBits(xCreatedEventGroup));
        }
        if(uxBits & BIT_2)
        {
            LOG_I(common,"[DEBUG]:event group BIT2 get");
            xEventGroupClearBits(xCreatedEventGroup,BIT_2);
            LOG_I(common,"[DEBUG]:event group BIT2 clean,rst:%d",xEventGroupGetBits(xCreatedEventGroup));
        }
        if(uxBits & BIT_3)
        {
            LOG_I(common,"[DEBUG]:event group BIT3 get");
            xEventGroupClearBits(xCreatedEventGroup,BIT_3);
            LOG_I(common,"[DEBUG]:event group BIT3 clean,rst:%d",xEventGroupGetBits(xCreatedEventGroup));
        }

}

结果:

结果分析:

  1. 等待事件组
  2. BIT1被置位
  3. 事件组被检测到,此时事件组值为0x02.
  4. 检测是到BIT1
  5. 清零事件组值
  6. 重新等待

        从结果可以看,如果等待事件组的函数被设置为不清除,那就需要用户手动调用函数去清除事件组。

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS学习七(事件标志组) 的相关文章

  • 如何搭建node_exporter

    如何搭建node exporter 1 观看条件 1 假设你已经看过上一篇文章 如何搭建普罗米修斯 Prometheus 2 假设你已经会搭建普罗米修斯 xff08 promethus xff09 3 上面两个假设 xff0c 只要满足一个
  • python类中初始化形式:def __init__(self)和def __init__(self, 参数1,参数2,···,参数n)区别

    前言 这两种初始化形式 xff0c 就类似于C 43 43 类中的构造函数 形式1 def init self span class token keyword class span span class token class name
  • Go语言操作grpc详细使用

    Go语言操作grpc详细使用 零 参考链接一 protobuf的详细使用二 grpc与protobuf的go文件的生成1 安装两个插件2 写proto文件3 编译proto文件 xff0c 生成go文件 三 grpc的详细使用1 一元RPC
  • Steghide使用教程及其密码爆破

    Steghide使用教程及其密码爆破 工具介绍 Steghide是一款开源的隐写术软件 xff0c 它可以让你在一张图片或者音频文件中隐藏你的秘密信息 xff0c 而且你不会注意到图片或音频文件发生了任何的改变 而且 xff0c 你的秘密文
  • 一道Gloang并发、锁的面试题,你会吗?

    Gloang并发 锁的面试题 1 题目描述2 问题分析2 1问题一2 2问题二2 3问题三2 4问题四2 5问题五 3 问题解决方法4 代码实现4 1 map前后加锁的方式4 2 sync map解决方式 1 题目描述 源地址 xff1a
  • 阿里云、腾讯云centos7安装mysql

    阿里云 腾讯云centos7安装mysql 1 下载2 解压与准备3 安装4 配置4 1配置数据库4 2查看默认密码4 3启动mysql4 4设置密码 5 开启远程登录5 1开放3306端口5 2开启远程登录6 参考链接 1 下载 镜像网站
  • go语言gin、net/http的优雅关机

    gin net http的优雅关机 什么是优雅关机 xff1f 优雅关机的实现参考链接 什么是优雅关机 xff1f http server运行过程中 xff0c 若进程被关闭 xff0c 那么正在处理的请求可能只被处理了一半就停止了 xff
  • C语言不详细记录

    C记录 1 内存管理2 结构体内存对其规则3 字符串函数4 二维数组5 const 指针6 字符串7 图片记录8 函数指针 1 内存管理 C语言内存讲解 详说内存分布和heap空间 2 结构体内存对其规则 C语言结构体对齐规则 C语言 结构
  • 【web压测】压测常用工具、压测指标到底是什么?

    压测常用工具 压测指标到底是什么 xff1f 一 压测指标 I1 QPS xff0c 每秒查询2 TPS xff0c 每秒事务3 RT xff0c 响应时间 二 压测指标 II三 压测工具1 ab2 go wrk 在window上压测 一
  • C语言结构体字节对其规则简述

    C语言结构体字节对其规则简述 规则描述示例示例一示例二 字节对齐规则 xff0c 一直不是很理解 xff0c 网上的答案也是参差不齐 规则描述 首先 xff0c 预处理指令 pragma pack n 可以改变默认对齐数进行字节对齐 n 取
  • 【STM32学习】SysTick定时器(嘀嗒定时器)

    SysTick定时器 一 参考资料二 时钟源选择与定时时间计算1 时钟源选择2 定时时间计算 三 SysTick Handler中断服务函数 一 参考资料 嘀嗒定时器 xff1a 时钟源 寄存器 二 时钟源选择与定时时间计算 结合正点原子的
  • 【STM32学习】GPIO口的八种工作模式

    GPIO口的八种工作模式 一 参考资料二 GPIO八种模式1 输入模式2 输出模式 三 施密特触发器1 电路2 电路计算 一 参考资料 GPIO原理图详解 强烈建议观看 xff1a GPIO为什么这样设计 xff1f 施密特触发器 原理 施
  • 【STM32学习】WWDG窗口看门狗

    STM32学习 WWDG窗口看门狗 x1f415 1 图展示WWDG原理2 复位 中断条件3 溢出时间计算4 与独立看门狗 x1f415 的对比 1 图展示WWDG原理 2 复位 中断条件 产生复位的情况 xff1a 当递减计数器数值递减到
  • 【STM32学习】时钟配置详解

    STM32学习 时钟配置详解 看懂时钟图结合代码外部高速时钟修改 看懂时钟图 在刚开始学习32的时候 xff0c 并不会在意这些 xff0c 或者即使看了也看的不是很明白 随着学习的深入 xff0c 我们发现看门狗 定时器 ADC很多外设都
  • vnc远程访问ubuntu18.04桌面系统 vncserver开机自启动

    文章目录 一 windows端准备二 ubuntu端准备三 远程连接桌面四 配置vncserver开机自启动 一 windows端准备 下载TightVNC xff1a https www tightvnc com 二 ubuntu端准备
  • 【STM32学习】定时器寄存器配置、功能工作过程详解

    STM32学习 定时器寄存器配置 功能工作过程详解 零 参考一 引言二 功能以及寄存器说明1 最基本的定时功能 xff08 时基单元 xff09 1 1 框图1 2 工作流程1 3 寄存器介绍1 3 1 CR1寄存器1 3 2 CNT PS
  • 【STM32学习】实时时钟 —— RTC

    STM32学习 实时时钟 RTC 零 参考一 工作原理1 RTC介绍2 工作过程 二 相关寄存器三 代码说明1 rtc初始化2 关于中断3 中断配置代码 xff08 仅供参考 xff09 3 1 秒中断 43 普通闹钟功能3 2 待机模式唤
  • 【JLink仿真器】盗版检测、连接故障、检测不到芯片问题

    JLink仿真器 盗版检测 连接故障 检测不到芯片问题 一 问题描述二 解决方法1 降低驱动 xff08 解决非法问题以及连接故障 xff09 2 SWD引脚被锁 xff08 解决检测不到芯片 xff09 三 说明 一 问题描述 盗版检测
  • 【STM32学习】直接存储器访问——DMA

    STM32学习 直接存储器访问 DMA 零 参考一 对DMA的理解二 DMA通道优先级三 DMA通道x传输数量寄存器 DMA CNDTRx 四 DMA缓冲区设计 零 参考 一个严谨的STM32串口DMA发送 amp 接收 xff08 1 5
  • 【STM32学习】模数转换器——ADC

    STM32学习 模数转换器 ADC 零 参考一 ADC转换耗时二 转换模式三 对某些寄存器的理解1 ADC CR22 ADC SQRX 四 库函数注意事项 零 参考 STM32固件库 xff08 标准外设库 xff09 入门学习 第七章 A

随机推荐

  • 【面试】嵌入式C语言题目整理

    面试 嵌入式C语言题目整理 描述内存四区 内存四区分为 xff1a 代码区 静态区 堆区 栈区 代码区就是用来存放代码的 静态区用来存放全局变量 静态变量 常量 xff08 字符串常量 const修饰的全局变量 xff09 堆区中的内存是由
  • 【总线】IIC学习笔记

    总线 IIC学习笔记 参考链接IIC总线介绍IIC总线时序1 空闲信号2 启动信号与停止信号3 数据的有效性4 应答信号5 七位地址传输 IIC读写过程 xff08 AT24C02举例 xff09 IIC读过程IIC写过程 正点原子IIC驱
  • 树莓派下载及安装PyCharm软件

    运行 PyCharm 需要 Java 环境 xff0c 如果树莓派上还没有安装过 JRE xff0c 可以使用以下命令安装即可 xff1a sudo apt install default jre y PyCharm 有专业版和社区版 专业
  • QT 建立透明背景图像QPixmap

    列将下面背景透明图片1转变成图片2 图1 图2 span class hljs preprocessor include 34 mainwindow h 34 span span class hljs preprocessor includ
  • putty 登录出现Network error: connection time out 解决方案

    今天用putty登录我的linux主机 出现Networkerror connection time out 然后我从linux系统上登录 xff0c 当是没法联网 xff0c pingwww baidu com 则提示 xff1a pin
  • 大端字节序与小端字节序的转换

    逐步加深对字节操作的理解 xff0c 记录一下大端字节序与小端字节序的转换 xff0c 开发环境是vs2010 xff0c 项目类型是控制台输出程序 xff0c 下面是代码实现 xff1a span class token comment
  • c++面试常见问题总结

    近来在面试的过程 xff0c 发现面试官在c 43 43 方面总是喜欢问及的一些相关问题总结 xff0c 当时没怎么答出来 xff0c 或者是答的不怎么全面 xff0c 故而查询相关资料总结下 后面实际工作会进行实时更新信息 lt 一 gt
  • Prometheus(普罗米修斯)架构及原理

    prometheus架构图 xff1a 如上 xff0c prometheus 采集数据的主要方式是 server 通过http请求去 主动拉取 数据 要完成以上需求 xff0c 必须满足以下条件 xff1a server必须知道各种 ex
  • mujoco强化学习模拟环境的安装(windows10)

    最近在学强化学习 xff0c 学长推荐用mujoco来做仿真环境 原本我是想照着教程安装的 结果最近mujoco被DeepMind收购了 xff0c 现在是开源的 xff0c 许多安装步骤都不太一样了 xff0c 所以我就写了这篇安装教程
  • Apple苹果寻物Airtag真实模型拆解及复现stp文件

    Apple苹果寻物Airtag真实模型拆解及复现stp文件 Airtag拆解复现对比 xff1a 欢迎下载stp结构源文件 xff0c 文件可编辑 xff0c 文件下载链接 xff1a https download csdn net dow
  • 使用STM32CubeMX 配置ADC+DAC(DMA)感受

    STM32CubeMX使用感受 开篇先说一下个人使用STM32CubeMX的感受 xff0c 第一点的感受就是STM32CubeMX加速了开发流程 xff0c ST官方的库写的很好 xff0c 在使用之前 xff0c 开发流程一般是打开如正
  • 订单系统设计 —— 重复下单

    一 重复原因 造成重复下单的原因有很多 xff0c 比如用户重复提交 网络超时导致的重试 xff08 网关超时重试 RPC超时重试 xff0c 以及前端超时重试等 xff09 xff0c 下单请求的整个链路都可能造成重复 xff0c 大致可
  • 额温枪查表算法

    目前额温枪这个东西特别火 xff0c 所以大家都在搞这个事情 xff0c 那我也来蹭个热度吧 大概的工作原理 xff1a 热电堆传感器 gt ADC gt MCU gt LCD显示 其实原理很简单 xff0c 那比较麻烦的事情就是温度补偿和
  • ESP32-IDF 使用VSCODE添加自己的头文件后无法找到的问题

    最近在学习esp32 xff0c 使用VSCODE进行开发 今天在添加自己的项目文件 xff0c 编译后 xff0c 系统提示找不到头文件 xff0c 找了很久 xff0c 最终在大佬同事的帮助下才解决 xff0c 这里记录一下 情况一 x
  • VMWARE安装VM TOOLS后依旧无法拖拉文件的解决方法

    utuntu版本 xff0c 18 04 5 安装虚拟机后又安装了vm tools 并且所有能配置的都配置了 但是依旧无法实现文件的拖拽 这些都配置了 xff0c 还是不行 命令安装vmtools时系统提示 open vm tools pa
  • windows bat脚本学习一(基础指令)

    1 pause 暂停批处理的执行并在屏幕上显示 34 请按任意键继续 34 例如 xff1a 改脚本执行结果为 xff1a 2 echo 显示指令 xff0c 会把需要显示的内容展示出来 例如 结果为 xff1a 3 echo off 在此
  • 常见导航坐标系定义

    常见坐标系 在导航系统中有几种常见的坐标系 xff1a 大地坐标系 xff0c 地心惯性参考系 xff0c 地心地固参考系 xff0c 切平面坐标系 xff0c 随体坐标系 其中大地坐标系和地心惯性参考系是非加速参考系 xff0c 不随地球
  • FreeRTOS学习一(简介)

    1 什么是FreeRTOS RTOS从名字上可以分为free和RTOS两部分 free是免费的意思 xff0c RTOS全称是Real Time Operation System xff0c 译为实时操作系统 那FreeRTOS的意思就是
  • FreeRTOS学习五(信号量)

    信号量是操作系统中重要的一部分 xff0c 信号量一般用来进行资源管理和任务同步 信号量分为二值信号量 计数型信号量 互斥信号量 不同信号量的应用场景也不同 xff0c 但是有些应用场景是可以互换着使用的 信号量简介 信号量常常用于控制对共
  • FreeRTOS学习七(事件标志组)

    RTOS中可以通过信号量来完成同步 xff0c 但是信号量只能与单个的事件或任务进行同步 有时某个任务可能会需要与多个事件或任务进行同步 xff0c 此时信号量就无法满足要求了 事件标志组就排上了用场 事件位 xff08 事件标志 xff0