FreeRTOS_信号量_学习笔记

news2025/1/6 4:14:55

信号量的特性

消息队列用于传输多个数据,但是有时候我们只需要传递状态,这个状态值需要用一个数值表示。套用队列笔记中的流水线例子,可以理解为流水线上工件的数量。
信号:起通知作用
量:还可以用来表示资源的数量
当"量"没有限制时,它就是"计数型信号量"(Counting Semaphores)
当"量"只有0、1两个取值时,它就是"二进制信号量"(Binary Semaphores)
支持的动作:"give"给出资源,计数值加1;"take"获得资源,计数值减1。
在这里插入图片描述

队列信号量
数据存储可容纳多个数据。创建时要分配队列结构体和存储数据的空间只有计数值。创建时只需要分配信号量结构体
生产者没有空间存入时可以阻塞不阻塞,计数值最大时返回失败
消费者没有数据时可阻塞计数值最小时可阻塞

信号量分为二进制信号量和计数型信号量。二进制信号量初始值为0,计数型信号量的最大值不是1。

信号量函数

创建

 // 动态创建二进制信号量
SemaphoreHandle_t xSemaphoreCreateBinary( void );
 // 静态创建二进制信号量
SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer );

//动态创建计数型信号量
SemaphoreHandle_t xSemaphoreCreateCounting(UBaseType_t uxMaxCount, UBaseType_t uxInitialCount);
//静态创建计数型信号量
SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, 
                                                 UBaseType_t uxInitialCount, 
                                                 StaticSemaphore_t *pxSemaphoreBuffer );

删除

void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );

存取

/*在任务中使用*/
BaseType_t xSemaphoreGive( SemaphoreHandle_t xSemaphore );
/*在中断中使用*/
BaseType_t xSemaphoreGiveFromISR(
                        SemaphoreHandle_t xSemaphore,
                        BaseType_t *pxHigherPriorityTaskWoken
                    );

xSemaphore:信号量句柄
*pxHigherPriorityTaskWoken:如果在信号量操作中唤醒了一个更高优先级的任务,会被设置为 pdTRUE,否则为pdFALSE

/*在任务中使用*/
BaseType_t xSemaphoreTake(
                   SemaphoreHandle_t xSemaphore,
                   TickType_t xTicksToWait
               );
/*在中断中使用*/
BaseType_t xSemaphoreTakeFromISR(
                        SemaphoreHandle_t xSemaphore,
                        BaseType_t *pxHigherPriorityTaskWoken
                    );

xTicksToWait:阻塞的时间

信号量实验

模拟车辆进站,假设车辆要有票才能同行,用一个信号量来模拟总共有多少票。当有票的时候,车拿走一张并开出,当其到达终点,就把票放回票仓,下一辆车再开出。

static SemaphoreHandle_t g_xSemTicks; 
static uint32_t g_xres, g_yres, g_bpp;
static uint8_t *g_framebuffer;
// 定义汽车结构体,包括位置和控制键
struct car {
	int x;
	int y;
	int control_key;
};
// 定义三辆汽车的初始位置和控制键
struct car g_cars[3] = {
	{0, 0, IR_KEY_1},
	{0, 17, IR_KEY_2},
	{0, 34, IR_KEY_3},
};
// 汽车图片的二进制数据
static const byte carImg[] = {
	0x40,0xF8,0xEC,0x2C,0x2C,0x38,0xF0,0x10,0xD0,0x30,0xE8,0x4C,0x4C,0x9C,0xF0,
	0x02,0x1F,0x37,0x34,0x34,0x1C,0x0F,0x08,0x0B,0x0C,0x17,0x32,0x32,0x39,0x0F,
};
// 清除区域的图像数据,用于隐藏汽车
static const byte clearImg[30] = {0};
// 显示汽车
static void ShowCar(struct car *pcar)
{
	draw_bitmap(pcar->x, pcar->y, carImg, 15, 16, false, 0);
	draw_flushArea(pcar->x, pcar->y, 15, 16);
}
// 隐藏汽车
static void HideCar(struct car *pcar)
{
	draw_bitmap(pcar->x, pcar->y, clearImg, 15, 16, false, 0);
	draw_flushArea(pcar->x, pcar->y, 15, 16);
}

// 每辆汽车的任务
static void CarTask(void *params)
{
	struct car *pcar = params;
	
	// 任务开始时等待信号量,以同步启动所有车辆
	xSemaphoreTake(g_xSemTicks, portMAX_DELAY);
	
	while (1)
	{
		if (pcar->x < g_xres - CAR_LENGTH)
		{
			HideCar(pcar);  // 隐藏汽车以更新位置
			
			// 更新汽车位置
			pcar->x += 1;
			
			ShowCar(pcar);  // 显示新位置的汽车
			
			vTaskDelay(50); // 控制更新频率
			
			if (pcar->x == g_xres - CAR_LENGTH)
			{
				xSemaphoreGive(g_xSemTicks); // 到达屏幕边缘时释放信号量并结束任务
				vTaskDelete(NULL);
			}
		}
	}
}
// 主游戏函数,初始化并启动任务
void car_game(void)
{
	g_framebuffer = LCD_GetFrameBuffer(&g_xres, &g_yres, &g_bpp);
	draw_init();
	draw_end();
	
	// 创建信号量,开始计数为2,最大计数为3
	g_xSemTicks = xSemaphoreCreateCounting(3, 2);
	
    // 创建每辆汽车的任务
    xTaskCreate(CarTask, "car1", 128, &g_cars[0], osPriorityNormal, NULL);
    xTaskCreate(CarTask, "car2", 128, &g_cars[1], osPriorityNormal, NULL);
    xTaskCreate(CarTask, "car3", 128, &g_cars[2], osPriorityNormal, NULL);	
}

可以通过改变g_xSemTicks = xSemaphoreCreateCounting(3, 2);的参数,来改变有多少张票。

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

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

相关文章

232转Profinet网关接扫码枪与PLC通讯在物流分拣线上的应用

一、背景 随着生活节奏的加快&#xff0c;网络购物需求非常大&#xff0c;从而造成快递站需要快速提取快递信息已达到快速出站的效果&#xff0c;这就用到了扫码枪&#xff0c;扫码枪作为采集设备&#xff0c;能够迅速准确地读取货物信息。并将数据传输至PLC控制器&#xff0c…

antd design 自定义表头

<template><a-card :bordered"false"><div class"contentWrap"><!-- 查询区域 --><div class"table-page-search-wrapper"><a-form layout"inline" keyup.enter.native"searchQuery">&…

【InternLM实战营第二期笔记】03:“茴香豆“,搭建你的 RAG 智能助理(未完成)

文章目录 笔记-RAG课程结构为什么要用 RAG&#xff1f;定义工作原理向量数据库RAG 工作流程发展历程常见优化RAG vs 微调LLM 优化方法比较RAG的评价总结 笔记-茴香豆什么是茴香豆茴香豆实战 笔记-RAG 课程结构 为什么要用 RAG&#xff1f; 新增知识&#xff0c;尤其是高频变动…

利用开源工具创建WEBGIS应用

在本文中&#xff0c;我们将大致说明利用开源工具如何与服务器交互以构建交互式或动态 Web GIS。 WebGIS 应用程序已成为展示地理数据的重要模式。我们现在拥有允许用户交互的机制&#xff0c;以便用户可以选择数据&#xff0c;甚至修改或添加新数据。 什么是WEBGIS? 通过网络…

三十、openlayers官网示例解析Double click, Drag and Zoom——第二次点击鼠标拖拽缩放地图效果、取消地图双击放大事件

这篇展示了如何在地图上添加第二次按下鼠标移动鼠标实现拖拽缩放地图效果。 官网demo地址&#xff1a; Double click, Drag and Zoom 官网介绍文字的翻译如下&#xff1a; 示例比较简单&#xff0c;直接贴代码&#xff1a; const map new Map({//添加第二次点击拖拽缩放地图i…

Meta 推出新型多模态 AI 模型“变色龙”(Chameleon),挑战 GPT-4o,引领多模态革命

在人工智能领域&#xff0c;Meta 近日发布了一款名为“变色龙”&#xff08;Chameleon&#xff09;的新型多模态 AI 模型&#xff0c;旨在挑战 OpenAI 的 GPT-4o&#xff0c;并刷新了当前的技术标准&#xff08;SOTA&#xff09;。这款拥有 34B 参数的模型通过 10 万亿 token 的…

探索机器人智能设备:开启智慧生活新篇章

机器人智能设备作为科技创新的代表&#xff0c;正以其独特的魅力吸引着越来越多的关注。它们不仅具备高度的智能化和自主化能力&#xff0c;还能在各种场景下发挥出强大的功能。 机器人智能设备的张总说&#xff1a;在智能家居领域&#xff0c;机器人智能设备可以帮助我们实现家…

骨折分类数据集1129张10类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;1129 分类类别数&#xff1a;10 类别名称:["avulsion_fracture",…

鸿蒙ArkUI-X跨语言调用说明:【平台桥接开发指南(Android)BridgePlugin】

BridgePlugin (平台桥接) 本模块提供ArkUI端和Android平台端消息通信的功能&#xff0c;包括数据传输、方法调用和事件调用。需配套ArkUI端API使用&#xff0c;ArkUI侧具体用法请参考[Bridge API]。 说明&#xff1a; 开发前请熟悉鸿蒙开发指导文档&#xff1a; gitee.com/li-…

微软Copilot+ PC:Phi-Silica

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调重新阅读。而最新科技&#xff08;Mamba&#xff0c;xLSTM,KAN&#xff09;则提供了大模…

webserver服务器从零搭建到上线(九)|⭐️EventLoop类(一)——详解成员变量、简述成员方法

在本节中&#xff0c;我们一起来仔细探讨一下EpollPoller类。该类可以说是muduo库中最最核心的类了&#xff0c;一定要搞懂&#xff01; 文章目录 私有成员using ChannelList std::vector<Channel*>looping_、quit_threadId_pollReturnTime_、poller_wakeup_fd、wakeupC…

机器学习-1-了解机器学习machine learning的基本概念

参考机器学习算法 - 一文搞懂ML(机器学习) 参考机器学习算法 - 一文搞懂SL(监督学习) 参考机器学习算法 - 一文搞懂UL(无监督学习) 1 机器学习 1.1 机器学习的本质 基本思路:无论使用什么样的算法和数据,机器学习的基本思路都可以归结为以下三个核心步骤。 (1)问题…

Nginx的集群负载均衡(nginx构建tomcat集群案例)

一 .Nginx的集群负载均衡 1.nginx 集群负载均衡示意图 2.四层负载均衡和7层负载均衡 LVS 四层负载均衡(常用); Haproxy四层负载均衡;Nginx 四层负载均衡; Haproxy七层负载均衡;Nginx 七层负载均衡(常用); 3.nginx构建tomcat集群 步骤1:安装tomcat 步骤2:nginx配置tom…

图论(五)-最短路

一、Bellman-Ford算法 算法思想&#xff1a;通过 n 次循环&#xff0c;每次循环都遍历每条边&#xff08;共 m 条边&#xff09;&#xff0c;进而更新节点的距离&#xff0c;每次循环至少可以确定一个点的最短路&#xff0c;循环 n 次&#xff0c;求出 n 个点的最短路 时间复杂…

git:Unable to negotiate问题解决

场景说明&#xff1a; 安装了Gitblit(自架的代码仓库服务)发现部分电脑无法推代码&#xff0c;报错误如下&#xff1a; Unable to negotiate with **** port 22: no matching host key type found. Their offer: ssh-rsa 并排队了账户权限问题。 解决方案&#xff1a; 1.打开问…

HttpClient cookie爬虫记录

记录一次java语言使用httpclient爬取网站接口数据的经历 需要用到的依赖&#xff1a; httpclient和httpcore是封装了http请求的工具类 jsoup可以将返回的网页html找到你需要的xml节点&#xff0c;很方便 <dependency><groupId>org.apache.httpcomponents</gr…

Spring系列-01-IOC的依赖查找和依赖注入

IOC基础 IOC发展 初始场景, 不使用IOC如何实现 假定现在有一下需求, 开始使用的数据源是MySQL, 后续数据源变动为Oracle, 那么我们的代码就需要改动 每次切数据源都需要改动, 那么进行优化 静态工厂解决强依赖 在01版本基础上, 使用静态工厂对多个数据源进行了封装, 要哪…

Unity UGUI系统概念分析

文章目录 前言一、UGUI运行原理二、UGUI组件分析1、Canvas组件2、Canvas Scaler3、Graphic Raycaster组件4、EventTrigger组件5、Image 和 RawImage组件5、Mask 和 RectMask2D组件6、Button、Sider、DropDown等组件 三、UGUI源码分析三、UGUI优化四、UI框架设计五、UI适配总结 …

三十一、openlayers官网示例Draw Features解析——在地图上自定义绘制点、线、多边形、圆形并获取图形数据

官网demo地址&#xff1a; Draw Features 先初始化地图&#xff0c;准备一个空的矢量图层&#xff0c;用于显示绘制的图形。 initLayers() {const raster new TileLayer({source: new XYZ({url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/…

快团团帮卖团长怎么对供货大团长进行评分?

都说帮卖“躺赚”&#xff1f; 一旦遇团不淑&#xff0c;惨遭不靠谱团长挖坑&#xff0c;售后拖延、发货慢、产品瑕疵…… 加上顾客夺命连环催&#xff0c;双面夹击&#xff0c;夹缝生存。供货团长靠不靠谱太重要了&#xff01; 快团团供货团长评分系统上线&#xff01; 帮卖团…