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
  • FreeRTOS例程4-串口DMA收发不定长数据

    FreeRTOS例程4 串口DMA收发不定长数据 知乎 zhihu com
  • FreeRTOS简述和移植文档

    FreeRTOS简述和移植文档 文章目录 FreeRTOS简述和移植文档 1 前言 2 FreeRTOS简述 1 概述 2 实现 3 主要特色 4 支持平台 3 移植FreeRTOS 4 最后 1 前言 目前由于IOT的飞速发展 针对单片机
  • 一文教你学会keil软件仿真

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

    中断概念 Cortex M的NVIC最多支持240个IRQ 中断请求 1个不可屏蔽中断 NMI 1个Systick 滴答定时器 定时器中断和多个系统异常 Cortex M处理器有多个用于管中断和异常的可编程寄存器 这些寄存器大多数都在 NV
  • FreeRTOS ------- 任务(task)

    在学习RTOS的时候 个人觉得带着问题去学习 会了解到更多 1 什么是任务 在FreeRTOS中 每个执行线程都被称为 任务 每个任务都是在自己权限范围内的一个小程序 其具有程序入口每个任务都是在自己权限范围内的一个小程序 其具有程序入口通
  • Error: L6218E: Undefined symbol vApplicationGetIdleTaskMemory (referred from tasks.o).

    我用的是F103ZET6的板子 移植成功后 编译出现两个错误是关于stm32f10x it c 里 void SVC Handler void void PendSV Handler void 两个函数的占用问题 随后编译出现以下两个问题
  • 【FreeRTOS】任务通知的使用

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

    线程安全 多线程程序处于一个多变的环境 可访问的全局变量和堆数据随时可能被其他的线程改变 多个线程同时访问一个共享数据 可能造成严重的后果 出现问题的是之前移植了一个freemodbus的从站 多个任务访问全局变量保持寄存器区 导致最后读出
  • FreeRTOS笔记(一)简介

    这个笔记主要依据韦东山freertos快速入门系列记录 感谢韦东山老师的总结 什么是实时操作系统 操作系统是一个控制程序 负责协调分配计算资源和内存资源给不同的应用程序使用 并防止系统出现故障 操作系统通过一个调度算法和内存管理算法尽可能把
  • 基于STM32的FreeRTOS学习之中断测试实验(五)

    记录一下 方便以后翻阅 本章内容是接着上一章节进行的实际演练 1 实验目的 FreeRTOS可以屏蔽优先级低于configMAX SYSCALL INTERRUPT PRIORITY的中断 不会屏蔽高于其的中断 本次实验就是验证这个说法 本
  • FreeRTOS学习笔记(8)---- 软件定时器

    使用FreeRTOS软件定时器需要在文件FreeRTOSConfig h先做如下配置 1 configUSE TIMERS 使能软件定时器 2 configTIMER TASK PRIORITY 定时器任务优先级 3 configTIMER
  • freeRTOS出现任务卡死的情况。

    最近在做一个产品二代升级的项目 代码是上一任工程师留下的 很多BUG 而且融合了HAL库和LL库 以及github上下载的GSM源码 很不好用 我这边是将2G模块换成了4G 且添加了单独的BLE模块 因此只在源码的基础上 去除2G和BLE代
  • 13-FreeRTOS任务创建与删除

    任务创建和删除API函数位于文件task c中 需要包含task h头文件 task h里面包函数任务的类型函数 例如 对xTaskCreate的调用 通过指针方式 返回一个TaskHandle t 变量 然后可将该变量用vTaskDele
  • FreeRTOS实时操作系统(三)任务挂起与恢复

    系列文章 FreeRTOS实时操作系统 一 RTOS的基本概念 FreeRTOS实时操作系统 二 任务创建与任务删除 HAL库 FreeRTOS实时操作系统 三 任务挂起与恢复 FreeRTOS实时操作系统 四 中断任务管理 FreeRTO
  • FreeRTOS 配置TICK_RATE_HZ

    我使用的是带有 5 4 版 FreeRTOS 的 MSP430f5438 我有一个有趣的问题 我无法弄清楚 基本上 当我将 configTICK RATE HZ 设置为不同的值时 LED 闪烁得更快或更慢 它应该保持相同的速率 我将 con
  • 如何将 void* 转换为函数指针?

    我在 FreeRTOS 中使用 xTaskCreate 其第四个参数 void const 是传递给新线程调用的函数的参数 void connect to foo void const task params void on connect
  • 防止GCC LTO删除函数

    我使用 GCC ARM Embedded 和 FreeRTOS FreeRTOS具有的功能vTaskSwitchContext 仅在某些情况下使用 内联汇编代码 问题是 当我使用LTO时 GCC不考虑内联汇编代码并认为该函数没有被使用 因此
  • 小型 ARM 微控制器的 RTOS 内核之间的可量化差异 [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 有许多不同的 RTOS 可用于微控制器 我专门寻找支持 ARM Cortex M 处理器的 RTOS 另外 我对闭源解决方案不感兴趣 试图从网站
  • 有关 CMake 错误的问题:没有为目标提供源

    我正在尝试使用 cmake 和 eclipse 将 FreeRtos 添加到我的项目中 但出现错误 我运行的是 debian 10 我的 cmake 版本是 3 13 4 cmake 的文件可以在以下位置找到这个 git 仓库 https

随机推荐

  • 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 一种内核机制 内核同步