FreeRTOS教程——二值信号量(四)

2023-05-16

二值信号量

信号量简介

目的:共享资源访问、与任务同步

信号量类型:二值信号量、计数型信号量、互斥信号量、递归互斥信号量

本质上是一种只包含一个项数的队列

二值信号量

0 和 1,一种内核机制。 内核同步,资源共享。

极简例子

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

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

//任务优先级
#define LED0_TASK_PRIO		2
//任务堆栈大小	
#define LED0_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED0Task_Handler;
//任务函数
void led0_task(void *pvParameters);

//任务优先级
#define LED1_TASK_PRIO		3
//任务堆栈大小	
#define LED1_STK_SIZE 		50  
//任务句柄
TaskHandle_t LED1Task_Handler;
//任务函数
void led1_task(void *pvParameters);
int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 
	delay_init();	    				//延时函数初始化	  
	uart_init(115200);					//初始化串口
	LED_Init();		  					//初始化LED
	 
	//创建开始任务
    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();          //开启任务调度
}
xSemaphoreHandle Sempore_Bin = NULL;
//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
		// 创建二值信号量
		Sempore_Bin = xSemaphoreCreateBinary();
		if(Sempore_Bin != NULL) printf("创建成功\r\n");
		else printf("创建失败\r\n");

    //创建LED0任务
    xTaskCreate((TaskFunction_t )led0_task,     	
                (const char*    )"led0_task",   	
                (uint16_t       )LED0_STK_SIZE, 
                (void*          )NULL,				
                (UBaseType_t    )LED0_TASK_PRIO,	
                (TaskHandle_t*  )&LED0Task_Handler);   
    //创建LED1任务
    xTaskCreate((TaskFunction_t )led1_task,     
                (const char*    )"led1_task",   
                (uint16_t       )LED1_STK_SIZE, 
                (void*          )NULL,
                (UBaseType_t    )LED1_TASK_PRIO,
                (TaskHandle_t*  )&LED1Task_Handler);         
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}

//LED0任务函数 
void led0_task(void *pvParameters)
{
    u8 key= 0;
		while(1){
			printf("%d\r\n",key);
			key++;
			if(key == 10){
				if(Sempore_Bin!=NULL&&key==10){
				if (xSemaphoreGive(Sempore_Bin)==pdTRUE) 
					printf("释放成功\r\n");
				else
					printf("释放失败\r\n");
				}
			}
			vTaskDelay(1000);
		}
}   

//LED1任务函数
void led1_task(void *pvParameters)
{
		while(1){
			if(xSemaphoreTake(Sempore_Bin, 10)== pdTRUE)
				printf("获取成功\r\n");
			else
				printf("获取失败\r\n");
			vTaskDelay(1000);
		}
}

中断与二值信号量实验

主要函数

if (xSemaphoreGiveFromISR(Sempore_Bin, &xHigherPrioityTaskWoken)==pdTRUE) 
if(xSemaphoreTake(Sempore_Bin, 10)== pdTRUE){}
delay_xms(10);//消抖

主要代码

// exit.c
void EXTIX_Init(void){
 		EXTI_InitTypeDef EXTI_InitStructure;
 		NVIC_InitTypeDef NVIC_InitStructure;
  	KEY_Init();	 //	按键端口初始化
  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能复用功能时钟
    //GPIOA.0	  中断线以及中断初始化配置 上升沿触发 PA0  WK_UP
 	  GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); 
		EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
		EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_InitStructure.EXTI_Line=EXTI_Line0;
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  	EXTI_Init(&EXTI_InitStructure);		//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器


  	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//使能按键WK_UP所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06;	//抢占优先级2, 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;					//子优先级3
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);
}

extern xSemaphoreHandle Sempore_Bin;
//外部中断0服务程序 
void EXTI0_IRQHandler(void)
{
	delay_xms(10);//消抖
	BaseType_t xHigherPrioityTaskWoken;
	if(WK_UP==1)
	{
		printf("按下按键\r\n");
		if(Sempore_Bin!=NULL){
				if (xSemaphoreGiveFromISR(Sempore_Bin, &xHigherPrioityTaskWoken)==pdTRUE) 
					printf("释放成功\r\n");
				else
					printf("释放失败\r\n");
				}
	}
	EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位  
}

//main.c
void led0_task(void *pvParameters)
{
		u8 key_sum= 0;
		while(1){
				if(xSemaphoreTake(Sempore_Bin, 10)== pdTRUE){
					printf("接受成功\r\n");
					key_sum++;
					printf("按键被按下%d次",key_sum);
				}
				else{
					// printf("释放失败\r\n");
				}
				vTaskDelay(10);
	  }
} 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS教程——二值信号量(四) 的相关文章

  • 详解FreeRTOS中的软件定时器

    软件定时器用于让某个任务定时执行 或者周期性执行 比如设定某个时间后执行某个函数 或者每隔一段时间执行某个函数 由软件定时器执行的函数称为软件定时器的回调函数 参考资料 Mastering the FreeRTOS Real Time Ke
  • 基于HAL库的FREERTOS----------二.任务API函数

    任务API函数览概 CUBEMX对 做了API的封装 很多 的函数没有封装到位 可以用原函数调用 任务API函数分别介绍 1 uxTaskPriorityGet 此函数用来获取指定任务的优先级 要使用此函数的话宏 INCLUDE uxTas
  • FreeRTOS内核配置说明---FreeRTOS Kernel V10.2.1

    FreeRTOS内核是高度可定制的 使用配置文件FreeRTOSConfig h进行定制 每个FreeRTOS应用都必须包含这个头文件 用户根据实际应用来裁剪定制FreeRTOS内核 这个配置文件是针对用户程序的 而非内核 因此配置文件一般
  • FreeRTOS软件定时器创建、复位、开始和停止(备忘)

    目录 一 简介 1 1 开发环境 1 2 摘要 二 STM32CubeIDE配置 三 创建定时器 3 1 头文件声明 3 2 工程文件定义 3 3 创建定时器 3 4 开启 复位 和关闭定时器 四 定时器回调函数 一 简介 1 1 开发环境
  • 解决错误“ #error “include FreeRTOS.h“ must appear in source files before “include event_groups.““例子分享

    今天来给大家分享一下 关于之前自己在学习FreeRTOS过程中遇到的一个错误提示 话不多说 我们直接来看 错误分析 首先 我们看一下错误的提示 error 35 error directive include FreeRTOS h must
  • 一文教你学会keil软件仿真

    仿真在我们调试代码中是非常重要的 通过仿真 我们可以快速定位到错误代码 或者错误逻辑的地方 这里我就以上一篇博客为例 教大家如何软件仿真 软件仿真不需要单片机 直接通过keil软件进行代码调试 一 打开工具 二 选择软件仿真 三 开始仿真
  • FreeRTOS学习笔记(3、信号量、互斥量的使用)

    FreeRTOS学习笔记 3 信号量 互斥量的使用 前言 往期学习笔记链接 学习工程 信号量 semaphore 两种信号量的对比 信号量的使用 1 创建信号量 2 give 3 take 4 删除信号量 使用计数型信号量实现同步功能 使用
  • 【FreeRTOS】多任务创建

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • 【FreeRTOS】队列的使用

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • FreeRTOS ------- 任务(task)

    在学习RTOS的时候 个人觉得带着问题去学习 会了解到更多 1 什么是任务 在FreeRTOS中 每个执行线程都被称为 任务 每个任务都是在自己权限范围内的一个小程序 其具有程序入口每个任务都是在自己权限范围内的一个小程序 其具有程序入口通
  • FreeRTOS记录(九、一个裸机工程转FreeRTOS的实例)

    记录一下一个实际项目由裸机程序改成FreeRTOS 以前产品的平台还是C8051单片机上面的程序 硬件平台改成了STM32L051 同时使用STM32CubeMX生成的工程 使用FreeRTOS系统 EEPROM数据存储读取函数修改更新 2
  • FreeRTOS_中断

    传送门 博客汇总帖 传送门 Cortex M3 中断 异常 传送门 Cortex M3笔记 基础 笔记内容参考 正点原子的FreeRTOS开发手册 cortex m3权威指南 Cortex M3和Cortex M4权威指南等 文中stm32
  • 基于HAL库的FREERTOS-----------三.队列

    一 队列简介 在实际的应用中 常常会遇到一个任务或者中断服务需要和另外一个任务进行 沟通交流 这个 沟通交流 的过程其实就是消息传递的过程 在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式 但是如果在使用操作系统的应用中用
  • FreeRTOS之事件

    FreeRTOS之事件 声明 本人按照正点原子的FreeRTOS例程进行学习的 欢迎各位大佬指责和批评 谢谢 一 事件定义 事件 事件集 与高数上的集合意义差不多 事件啊 其实是实现任务间通信的机制 主要用于实现多任务间的同步 但是事件类型
  • [FreeRTOS入门学习笔记]定时器

    定时器的使用步骤 1 定义一个handle xTimerCreate创建 2 启动定时器 在Task1中调用 通过队列通知守护任务来执行定时器任务 要再config头文件中定义守护任务相关配置 虽然定时器是在task1中启动 但是定时器的任
  • FreeRTOS临界段

    1 临界段 在访问共享资源时不希望被其他任务或者中断打断的代码 这段要执行的代码称为临界段代码 2 设置临界段的目的 保护共享资源 例如 全局变量 公共函数 不可重入函数 函数里面使用 了一些静态全局变量 malloc 等 保护外设的实时性
  • FreeRTOS多任务调度器基础

    Cortex M4中SysTick调度器核心 Cortex M4中的中断管理 Cortex M4中影子栈指针 Cortex M4中SVC和PendSV异常 1 Cortex M4中SysTick调度器核心 systick每一次中断都会触发内
  • FreeRTOSConfig.h 配置优化及深入

    本篇目标 基于上一篇的移植freertos stm32f4 freertos 上 修改 FreeRTOSConfig h 文件的相关配置来优化辅助 FreeRtos 的使用 并且建立一些基本功能 信号量 消息地列等 的简单应用位于 stm3
  • 如何更改 FreeRTOS 中任务的最大可用堆大小?

    我通过以下方式在任务中创建元素列表 l dllist pvPortMalloc sizeof dllist dlllist 有 32 字节大 我的嵌入式系统有 60kB SRAM 所以我希望系统可以轻松处理我的 200 个元素列表 我发现在
  • FreeRTOS 匈牙利表示法 [重复]

    这个问题在这里已经有答案了 我是 RTOS 和 C 编程的新手 而且我仍在习惯 C 的良好实践 因此 我打开了一个使用 FreeRTOS 的项目 我注意到操作系统文件使用匈牙利表示法 我知道一点符号 但面临一些新的 标准 FreeRTOS

随机推荐

  • PHP的依赖关系是什么意思?底层原理是什么?

    PHP的依赖关系指的是PHP应用程序或库与其他软件包或库之间的关系 这些软件包或库可能包括操作系统提供的库 xff0c 例如文件I O和网络功能 xff0c 也可能包括第三方库 xff0c 例如数据库客户端库和图像处理库 底层原理是 xff
  • 什么是Composer?底层原理是什么?

    Composer是PHP的一个依赖管理工具 xff0c 它可以帮助开发者在项目中自动管理依赖关系 xff0c 例如第三方库 框架 组件等 通过Composer xff0c 可以在项目中添加 更新 卸载依赖项 xff0c 并自动解析它们的依赖
  • 为什么composer可以自动管理依赖关系?底层原理是什么?

    Composer能够自动管理依赖关系的原理是基于包管理和自动加载的机制 首先 xff0c Composer通过一个名为Packagist的在线包存储库来管理各种PHP包 xff0c 这个仓库中包含了大量的PHP库和框架 xff0c 开发者可
  • windows线程同步-事件Event用法总结

    事件对象 Win32 中最具弹性的同步机制就属 events 对象了 Event 对象是一种核 心对象 xff0c 它的唯一目的就是成为激发状态或未激发状态 这两种状态全由程序 来控制 xff0c 不会成为 Wait 函数的副作用 Even
  • composer.lock是干什么的?底层原理是什么?

    composer lock文件是Composer工具在安装依赖包时生成的一个锁文件 它记录了当前应用程序所依赖的所有PHP库及其版本号 xff0c 以及所有依赖库所依赖的其他库及其版本号等信息 在运行composer install命令时
  • PHP的Zend引擎是干什么的?底层原理是什么?

    PHP的Zend引擎是PHP解释器的核心组件 xff0c 负责将PHP代码转换为可执行的指令集 xff0c 并执行这些指令 Zend引擎是PHP的默认执行引擎 xff0c 被广泛使用 Zend引擎的底层原理可以分为以下几个关键步骤 xff1
  • PHP解释器是干什么的?底层原理是什么?

    PHP解释器是用于解释执行PHP代码的软件程序 它负责将编写的PHP代码转换为可执行的机器指令 xff0c 并执行这些指令以实现代码的功能 PHP解释器的底层原理可以分为以下几个步骤 xff1a 词法分析 xff08 Lexical Ana
  • PHP代码的底层是什么?底层原理是什么?

    PHP代码的底层是由计算机可执行的机器码 xff08 二进制指令 xff09 组成 底层原理是将PHP代码经过编译和解释执行的过程转化为机器码 底层原理可以分为以下几个步骤 xff1a 词法分析 xff08 Lexical Analysis
  • Jetson Xavier NX 的SD卡系统镜像制作

    Jetson Xavier NX 的SD卡系统镜像制作 一 SD卡系统查看二 系统镜像制作三 系统镜像烧录 一 SD卡系统查看 现有的SD卡的内存为128G xff0c 其中64G内存并未分配 span class token commen
  • 嵌入式Linux下使用crond服务

    参考 xff1a https www linuxidc com Linux 2014 02 97369 htm http www linuxidc com Linux 2014 02 97360 htm https blog csdn ne
  • 关于Flexsns Sky 卡80%,以及乱码的解决问题

    一直被 flexsns sky 这个应用折磨好久了 xff0c 刚开始的时候安装成功 但是打开界面一直卡在80 那里 xff0c ucenter 里面的设置也是对的 官网也是挂的 xff01 于是百思不得解 接下来 我来说说我的解决办法把
  • Ubuntu18.04运行ORB-SLAM3(Demo+本地Realsense D415运行)

    ORB SLAM3论文地址 xff1a https arxiv org abs 2007 11898 代码地址 xff1a https github com UZ SLAMLab ORB SLAM3 一 安装库 根据ORB SLAM3源代码
  • ROS中的坐标与坐标系转换

    ROS中的TF 官网建议新工作直接使用tf2 xff0c 因为它有一个更清洁的界面 xff0c 和更好的使用体验 xff08 自ROS Hydro以来 xff0c tf第一代已被 弃用 xff0c 转而支持tf2 xff09 TF介绍 TF
  • 激光雷达与相机融合(二)-----基于openCV的YOLO目标检测

    代码解析 1 加载模型 span class token comment load image from file span cv span class token operator span Mat img span class toke
  • 线程优先权Thread Priority概念总结

    全文参考 WIN32多线程设计 一书 为什么会有线程优先权 xff1a 为什么CPU处理线程时会按优先级执行 xff1f 想象在忙碌的一天中 xff0c 有很多事情待做但时间又不够 xff0c 其中有很多紧急的事情 比如当晚的英语在线测试
  • 将ros cv_bridge关联到自己安装的Opencv版本

    有时候需要同时使用较高版本的openCV 但一般默认安装的ros系统的cv bridge包关联的Opencv版本都较低 xff0c 这时候就需要将cv bridge关联到自己安装的高版本OpenCV 成功方法为第三条 xff0c 前两条为遇
  • chmod +x 与chmod 777的区别

    chmod 43 x 是将文件状态改为可执行 xff0c 而chmod 777 是改变文件读写权限 在linux中使用man命令查看chmod的大纲我们可以得出以下有用的信息 xff1a chmod OPTION MODE MODE FIL
  • WIndowsServer2012 DHCP服务器配置

    DHCP服务器配置 WIndowsServer2012 DHCP服务器配置服务器配置保留IP设置作用域选项 客户机设置 WIndowsServer2012 DHCP服务器配置 服务器配置 1 首先打开服务器管理器 xff0c 点击工具 xf
  • JavaScript设计模式:四、发布订阅模式

    JavaScript设计模式 xff1a 四 发布订阅模式 文章目录 JavaScript设计模式 xff1a 四 发布订阅模式一 概述1 观察者模式2 发布订阅模式3 观察者模式是不是发布订阅模式 一 概述 观察者模式 xff1a 观察者
  • FreeRTOS教程——二值信号量(四)

    二值信号量 信号量简介 目的 xff1a 共享资源访问 与任务同步 信号量类型 xff1a 二值信号量 计数型信号量 互斥信号量 递归互斥信号量 本质上是一种只包含一个项数的队列 二值信号量 0 和 1 xff0c 一种内核机制 内核同步