FreeRTOS——信号量知识点总结及二值信号量实战

1信号量概念信号量

1)信号量的计数值都有限制:限定最大值。
如果最大值被限定为1,那么它就是二值信号量;
如果最大值不是1,它就是计数型信号量。
2)当计数值大于0,代表有信号量资源
当释放信号量,信号量计数值(资源数)加一
当获取信号量,信号量计数值(资源数)减一
3)信号量用于传递状态

2 队列与信号量对比

在这里插入图片描述

3 二值信号量概念

二值信号量的本质是一个队列长度为 1 的队列 ,该队列就只有空和满两种情况
合用于任务同步,即按序列访问。
在这里插入图片描述

4 二值信号量API函数

使用二值信号量的过程:创建二值信号量 ->释放二值信号量 -> 获取二值信号量
在这里插入图片描述
1)创建信号量
#define xSemaphoreCreateBinary( )
xQueueGenericCreate( 1 ,
semSEMAPHORE_QUEUE_ITEM_LENGTH ,
queueQUEUE_TYPE_BINARY_SEMAPHORE )
返回值 : NULL 创建失败
其他值 创建成功,返回二值信号量句柄
2)释放信号量
#define xSemaphoreGive ( xSemaphore )
xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ) ,
NULL ,
semGIVE_BLOCK_TIME ,
queueSEND_TO_BACK )

形参: xSemaphore 要释放信号量句柄
返回值:pdPASS 释放成功
errQUEUE_FULL 释放失败
3)获取信号量
BaseType_t xSemaphoreTake( xSemaphore, xBlockTime )
形参: xSemaphore 要获取信号量句柄
xBlockTime 阻塞时间
返回值:pdPASS 获取成功
errQUEUE_FULL 获取失败

5 二值信号量实战

在这里插入图片描述

5.1 freertos_demo.c

#include "freertos_demo.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

//FreeRTOS配置
//1.任务配置
//1.1 START_TASK 任务 配置

#define START_TASK_PRIO 1                   /* 任务优先级 */
#define START_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            StartTask_Handler;  /* 任务句柄 */
void start_task(void *pvParameters);        /* 任务函数 */

//1.2 TASK1 任务 配置

#define TASK1_PRIO      2                   /* 任务优先级 */
#define TASK1_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            Task1Task_Handler;  /* 任务句柄 */
void task1(void *pvParameters);             /* 任务函数 */

//1.2 TASK2 任务 配置

#define TASK2_PRIO      3                   /* 任务优先级 */
#define TASK2_STK_SIZE  128                 /* 任务堆栈大小 */
TaskHandle_t            Task2Task_Handler;  /* 任务句柄 */
void task2(void *pvParameters);             /* 任务函数 */

//1.3 二值信号量句柄定义
SemaphoreHandle_t        binarySemaphore;  

//2.在freertos_demo函数中创建start_task任务
void freertos_demo(void)
{

    xTaskCreate((TaskFunction_t )start_task,            /* 任务函数 */
                (const char*    )"start_task",          /* 任务名称 */
                (uint16_t       )START_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )START_TASK_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&StartTask_Handler);   /* 任务句柄 */
    vTaskStartScheduler();
}

//3.在start_task函数中创建task1、task2任务
void start_task(void *pvParameters)
{
    
    //进入临界区
    taskENTER_CRITICAL();
    //创建二值信号量
     binarySemaphore = xSemaphoreCreateBinary(); 
    if(binarySemaphore != NULL)
    {
        printf("二值信号量创建成功!!!\r\n");
    }
    
    //创建任务1
      xTaskCreate((TaskFunction_t )task1,            /* 任务函数 */
                (const char*    )"task1",          /* 任务名称 */
                (uint16_t       )TASK1_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK1_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&Task1Task_Handler);   /* 任务句柄 */
     //创建任务2          
     xTaskCreate((TaskFunction_t )task2,            /* 任务函数 */
                (const char*    )"task2",          /* 任务名称 */
                (uint16_t       )TASK2_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )TASK2_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&Task1Task_Handler);   /* 任务句柄*/
                
      //删除开始任务        
      vTaskDelete(StartTask_Handler);   
                
     //退出临界区
     taskEXIT_CRITICAL();
}


//4.在task1函数中释放二值信号量
void task1(void *pvParameters)
{
    uint8_t key = 0;
    BaseType_t err = 0;
    
    while (1)
    {
        //按键KEY0控制二值信号释放
        key = key_scan(0);
        switch (key)
        {
            case KEY0_PRES:
            {
                //如果二值信号量创建成功
                if(binarySemaphore != NULL)
                {
                     err = xSemaphoreGive(binarySemaphore);                //二值释放信号量
                    if(err == pdPASS)
                    {
                       printf("binarySemaphore释放成功\r\n");
                    }
                    else
                    {
                        printf("binarySemaphore释放失败\r\n");
                    }
               
                }
                 break;
               
            }
            default:
            {
                break;
            }
        }
        vTaskDelay(10);
    }
}

//5.在task2函数中获取二值信号量
void task2(void *pvParameters)
{
    BaseType_t err = 0;
    while(1)
    {
         err = xSemaphoreTake(binarySemaphore,portMAX_DELAY);
        if(err == pdPASS)
        {
            printf("binarySemaphore获取成功\r\n");
        }
        else printf("binarySemaphore获取失败\r\n");
    
    }
   
}


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

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

相关文章

模型融合之模型堆叠

一、理论 模型堆叠(Model Stacking)是一种集成学习的方法,其本质是将多个基学习器(Individual Learner)的预测结果作为新的特征,再训练一个元学习器(Meta Learner)来进行最终的预测。…

探索 Vue 实例方法的魅力:提升 Vue 开发技能(上)

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

Green Sock | GSAP 动画库

1.什么是“GSAP”? GreenSock Animation Platform(GSAP) 是一个业界知名的动画工具套件,在超过1100万个网站上使用,其中包括大量获奖网站! 您可以使用GSAP在任何框架中制作几乎任何JavaScript可以触及的动…

迅腾文化传播:触动每个移动消费者心灵的品牌故事缔造者

迅腾文化传播:触动每个移动消费者心灵的品牌故事缔造者 在这个高速发展的移动互联网时代,信息如同浩渺星海中的流星,瞬息万变。每个人的手机、平板、智能手表等移动设备,都成为了他们与世界连接的窗口。品牌,作为这个…

谷歌推出创新SynCLR技术:借助AI生成的数据实现高效图像建模,开启自我训练新纪元!

谷歌推出了一种创新性的合成图像框架,这一框架独特之处在于它完全不依赖真实数据。这个框架首先从合成的图像标题开始,然后基于这些标题生成相应的图像。接下来,通过对比学习的技术进行深度学习,从而训练出能够精准识别和理解这些…

STM32 学习(三)OLED 调试工具

目录 一、简介 二、使用方法 2.1 接线图 2.2 配置引脚 2.3 编写代码 三、Keil 工具调试 一、简介 在进行单片机开发时,有很多调试方法,如下图: 其中 OLED 就是一种比较好用的调试工具: OLED 硬件电路如下&#xff0c…

使用Redis进行搜索

文章目录 构建反向索引 构建反向索引 在Begin-End区域编写 tokenize(content) 函数,实现文本标记化的功能,具体参数与要求如下: 方法参数 content 为待标记化的文本; 文本标记的实现:使用正则表达式提取全小写化后的…

【竞技宝】DOTA2:Mad Kings官宣新阵容 南美新星Jimpark加盟!

北京时间2024年1月3日,随着本月DOTA2ESL吉隆坡站的比赛结束,下一个值得关注的大赛梦幻联赛S22举办的时间要等到今年的二月份了。虽然休赛期的转会狂潮已经过去,但目前还是有很多队伍依然在调整新赛季的阵容。 近日,南美战队Mad Kings在社交平台上官宣了发文,原阵容的所有选手(一…

LeetCode 每日一题 Day 28293031 ||三则模拟||找循环节(hard)

1185. 一周中的第几天 给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。 输入为三个整数:day、month 和 year,分别表示日、月、年。 您返回的结果必须是这几个值中的一个 {“Sunday”, “Monday”, “Tuesday”, “Wednesday…

创建Qt项目

项目工程名称一般不要有特殊符号,不要有中文 项目工程保存路径可修改的,但路径不要带中文 构建系统,有3种,这里使用qmake qmake和cmake区别 构建过程不同,项目管理不同。 1、构建过程,qmake是Qt框架自带的…

完善 Golang Gin 框架的静态中间件:Gin-Static

Gin 是 Golang 生态中目前最受用户欢迎和关注的 Web 框架,但是生态中的 Static 中间件使用起来却一直很不顺手。 所以,我顺手改了它,然后把这个改良版开源了。 写在前面 Gin-static 的改良版,我开源在了 soulteary/gin-static&a…

Twincat中PLC编程的ST语言

在Twincat中,PLC编程使用的是Structured Text(ST)语言。ST语言是一种类似于Pascal的高级编程语言,专为工业自动化领域的程序开发而设计。它提供了结构化的控制流和数据操作,使得PLC编程更加高效和可靠。 https://kunal…

数字信号处理期末复习——计算大题(一)

个人名片: 🦁作者简介:一名喜欢分享和记录学习的在校大学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:V…

一文讲清数据资产入表实操

《中共中央 国务院关于构建数据基础制度更好发挥数据要素作用的意见》已发布一年,数据资产化和入表已成为2023年的热门话题,随着2023年底国家数据局吹风《"数据要素x"三年行动计划(2024-2026年)》即将发布,这…

JRT控制打印机

本次测试打印机控制和纸张方向控制。 打印机状态 选择打印机 控制纸张 定义纸张 旋转纸张 不旋转纸张 A4

提高工作效率的Postman环境变量使用方法

在 Postman 中,用 Environments 来管理环境变量。我们在开发的过程中,往往会用到多个环境:开发环境,测试环境,UAT 环境,生产环境等。我们要调用不同环境的 API 时,只需切换 Postman 的 Environm…

Vuex(vue2中的状态机)

目录 Vuex state属性 getters属性 mutations属性 actions属性 modules属性 辅助函数 Vuex 状态管理模式 维护公共状态 公共数据 使用状态机模块维护状态 A组件中分发工作(发起异步请求)--->获取数据--->提交突变(将数据提交给突变 ) 通过突变修改状态…

Win32 基本程序设计原理总结

目录 1. Windows系统 基本原理 2. 需要什么函数库(.LIB) 2.1 C Runtimes: 2.2 Windows API 3. 需要什么头文件(.H) 4. Windows 程序运行的本质 5. 窗口类的注册与窗口的诞生 6.消息 6.1 消息分类:…

【每天五道题,轻松公务员】Day1:图形推理

目录 专栏了解 ☞欢迎订阅☜ ★专栏亮点★ ◇专栏作者◇ 图形推理 题目一 题目二 题目三 题目四 题目五 答案 详细讲解 讲解一 讲解二 讲解三 讲解四 讲解五 专栏了解 ☞欢迎订阅☜ 欢迎订阅此专栏:考公务员,必订!https://…

科研学习|论文解读——信息行为和社会控制:了解家庭慢性病管理中的冲突信息行为

摘要 信息与控制的关系引起了社会科学家的兴趣。然而,许多先前的工作都集中在组织而不是家庭上。交互式信息行为的研究也侧重于组织和协作,而不是冲突。因此,在有慢性疾病的家庭中,我们调查了健康相关社会控制背景下的信息行为以及…