文章目录

  • 1、信号量的概念和作用
    • 1、基本概念
    • 2、信号量的常用用途
  • 2、二值信号量
  • 3、计数信号量

前面的文章介绍了freertos的一些相关知识,主要包含邮箱,消息队列,任务通知等,这里继续介绍freertos中的比较重要的信号量的内容。

记录一个很小的知识点,串口下载刷芯片的话boot0选择为1,boot1选择为0,然后按下复位键,就可以进入下载模式了,这里复位键比较重要,一定要记得,不然就会报错,报错信息如下:

这里我们已经连好了boot,但是还是会报错,就是因为还没有按下复位键的原因了,这之后我们再次点击连接,就可以看到连接成功了,效果如下所示:

之后我们在打开文件,然后就可以下载了,这里下载也是比较快的

最后一步一定切记,就是要把这个BOOT复原

1、信号量的概念和作用

1、基本概念

信号量的最初目的是为了给共享资源建立一个标志,该标志表示该共享资源被占用情况。这样, 当一个任务在访问共享资源之前,就可以先对这个标志进行查询,从而在了解资源被占用的情况之后,再来决定自己的行为。

信号量常常用于控制对共享资源的访问和任务同步。信号量相当于在一个有限的资源空间里面能不能得到获取资源的权限,举个例子,就比如某宾馆里面由50间房间,每位房客只有凭借房卡才能进去,同时进去了一个房客(这里假设每间房只能住下一个房客)之后,可用的房间就会少一间。

在上面的例子中,当前的空余房间数量就是一个信号量,住了的房客就相当于信号量的值,如果不巧的话房间全部住满了就说明信号量满了,这个时候只有当房客出去才能空出来,这样就相当于信号量减一,然后又有新的房客住进来,这就相当于信号量加一了。

信号量用于控制共享资源访问的场景相当于一个上锁机制, 代码只有获得了这个锁的钥匙才能够执行。

2、信号量的常用用途

那么信号量的用途是什么呢,为什么要有信号量这样的一个机制呢,上面已经讲到了一点就是当资源不够的时候可以这样来分配信号量,信号量的另一个场合就是任务之间的同步。

具体的就比如当我们单片机 在执行中断服务函数的时候可以通过向任务发送信号量来通知任务它所期待的事件发生了, 当退出中断服务函数以后在任务调度器的调度下同步的任务就会执行。在编写中断服务函数的时候我们都知道一定要快进快出,中断服务函数里面不能放太多的代码,否则的话会影响的中断的实时性。 裸机编写中断服务函数的时候一般都只是在中断服务函数中打个标记,然后在其他的地方根据标记来做具体的处理过程。在使用 RTOS 系统的时候我们就可以借助信号量完成此功能, 当中断发生的时候就释放信号量,中断服务函数不做具体的处理。具体的处理过程做成一个任务,这个任务会获取信号量,如果获取到信号量就说明中断发生了,那么就开始完成相应的处理,这样做的好处就是中断执行时间非常短。 当然任务与任务之间也可以使用信号量来完成同步。

上面提到的都是常规的信号量,FreeRTOS 中还有一些其他特殊类型的信号量,比如互斥信号量和递归互斥信号量,二值信号量,计数型信号量等。

2、二值信号量

上面介绍过了,信号量可以描述资源的占用情况,为描述这种资源的占用的情况可以分为二值和计数两种,那么什么叫二值信号量,因为信号量资源被获取了,信号量值就是 0, 信号量资源被释放,信号量值就是 1, 把这种只有 0和 1 两种情况的信号量称之为二值信号量。

我们首先在下面的图形化配置中添加信号量


这里只要修改个名字就行,没什么特别需要注意的

生成代码之后就可以看到我们生成的信号量了

下面开始配置信号量,在一个任务中使用轮询的方式来检测信号量,信号量的发送有其他事件(这里是串口中断)来产生

源码如下:

     if (myBinary01Handle != 0){err = xSemaphoreTake(myBinary01Handle, portMAX_DELAY); //获取信号量if (err == pdPASS){printf("收到消息\r\n:");for (int i = 0; i < 8; i++)printf("%c", RxBuff[i]);printf("\n");if (strncmp((char*) RxBuff, "LED1on", 6) == 0) //字符串进行比较,如果完全匹配,就认为收到了HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);else if (strncmp((char*) RxBuff, "LED1off", 6) == 0)HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);else if (strncmp((char*) RxBuff, "LED2on", 6) == 0)HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);else if (strncmp((char*) RxBuff, "LED2off", 6) == 0)HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);elseprintf("输入的命令错误\r\n");}}elseosDelay(10);

这里用的串口的方式产生的信号量,串口发送完成,这里是判断0X0A结尾就是结束,就是换行符,发送完成之后就发送信号量

源码如下:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{RxBuff[Rx_Count++] = RxByte; //每次接收一个字节数据,换行符为0X0D,0X0A,结尾就是0X0Aif ((RxByte == 0x0A) && (myBinary01Handle != 0)){xSemaphoreGiveFromISR(myBinary01Handle, NULL); //中断方式发送信号量printf("成功接收到信号量\r\n");Rx_Count = 0;}if (Rx_Count > 8){printf("命令错误\r\n");memset(RxBuff, 0, sizeof(RxBuff));Rx_Count = 0;}while (HAL_UART_Receive_IT(&huart1, &RxByte, 1) == HAL_OK);
}

因此我们这里要使用串口的话就要在末尾加上换行符,效果如下所示

这里我们首先尝试打开LED的命令,发送下面指令

可以看到LED开启

下面来关闭LED试试,输入下面命令

可以看到LED被关闭

这样就实现了二值信号量了!

3、计数信号量

计数信号量常见用法诸如事件计数还有资源管理,事件计数为:首先产生一个计数信号量(此时信号量被初始化为0)事件处理函数释放信号量之后,计数信号量自增,其他的一些任务接收到信号量,这样信号量计数值就会自减,这样一来,计数信号量的值就是事件发生的数量和事件处理的数量差值。资源管理为,任务必须先获取信号量才能执行,任务获取之后信号量计数值自检,任务完成之后他就又会把信号量归还,这个时候就是自增。

在cubemx中配置如下所示,这里需要先使能这个宏,不然计数信号量那边就是灰色的,无法调用


然后就是这里就可以设定数值,这里信号量的数值设置为8

代码生成之后的可以看到我们生成的信号量如下所示

这里需要用一个周期函数来对按键进行扫描

按键扫面函数还是我们之前讲过的

下面是计数信号量的分配还有获取

源码如下

   if(myCountingSem01Handle != NULL){switch(key_flag){case 1:err = xSemaphoreTake(myCountingSem01Handle, portMAX_DELAY);if (err == pdFALSE)printf("获取信号量失败!\r\n");else {sem_value = uxSemaphoreGetCount(myCountingSem01Handle);printf("获取信号量成功,信号量值为 = %d\r\n",sem_value);HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);}break;case 2:err = xSemaphoreGive(myCountingSem01Handle);if (err == pdFALSE)printf("发送信号量失败!\r\n");else {sem_value = uxSemaphoreGetCount(myCountingSem01Handle);printf("发送信号量成功,信号量值为 = %d\r\n",sem_value);HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);}break;}}

信号量发布如下所示

信号量接收效果如下所示,最后我们可以看到接收超过了就会失败了

stm32外设笔记-freertos配置(四)相关推荐

  1. STM32学习笔记(四)丨TIM定时器及其应用(定时中断、内外时钟源选择)

    本篇文章包含的内容 一.TIM 定时器 1.1 TIM 定时器简介 1.2 TIM 定时器类型及其工作原理简介 1.2.1 基本定时器工作原理及其结构 1.2.2 通用定时器工作原理及其结构 1.2. ...

  2. STM32入门笔记(03):系统时钟控制 RCC (STM32CubeMx 初始化配置)

    目的/起源: B站@立邦大侠 的在视频里面提到,他用STM32CubeMx 更清晰地进行STM32系统时钟配置以及时钟架构. STM32 开发流程 : 芯片选型 - 原理图设计 - PCBlayout ...

  3. 《STM32学习笔记》4——核心功能电路与编程(下)

    接上文,文中的图片,大多数来自视频的截图(来自洋桃电子). 欢迎大家批评指正! STM32学习笔记-专栏 文章目录 一.蜂鸣器驱动 1.蜂鸣器介绍 2.蜂鸣器电路 3.蜂鸣器程序 二. MIDI 音乐 ...

  4. 【STM32学习笔记-点亮LED灯】

    STM32学习笔记-点亮LED灯 文章目录 STM32学习笔记-点亮LED灯 一.原理图分析 二.代码分析 1.mian函数 2.led.c函数 3.led.h函数 4.函数文件整理 5.LED_In ...

  5. STM32学习笔记(六)丨TIM定时器及其应用(输入捕获丨测量PWM波形的频率和占空比)

    本篇文章包含的内容 一.输入捕获 1.1 输入捕获简介 1.2 输入捕获通道的工作原理 1.3 输入捕获的主从触发模式 1.4 输入捕获和PWMI结构 二.频率的测量方法 2.1 测频法 2.2 测周 ...

  6. STM32学习笔记(15)——SPI协议

    STM32学习笔记(15)--SPI协议 一.SPI协议简介 1. 物理层 2. 协议层 (1) 通讯的开始与停止 (2)时钟极性CPOL.时钟相位CPHA 二.STM32的SPI外设 1. 通讯引脚 ...

  7. STM32入门笔记(02):定时器之定时器中断、输入捕获和PWM输出(SPL库函数版)

    目录 定时器 8个定时器 定时器功能 定时器中断 常用通用定时器的寄存器 定时器中断实验目的: 定时器库函数及步骤 实验程序讲解 PWM 简介 STM32 PWM工作过程 PWM模式1 与 PWM模式 ...

  8. STM32学习笔记(八)丨ADC模数转换器(ADC单、双通道转换)

    本篇文章包含的内容 一.ADC 模数转换器 1.1 ADC简介 1.2 逐次逼近型ADC工作原理 1.3 STM32中的ADC基本结构 1.4 STM32中ADC的输入通道 1.5 STM32中的AD ...

  9. STM32学习笔记(七)---SysTick

    STM32学习笔记(七)-SysTick 文章目录 STM32学习笔记(七)---SysTick 一.SysTick简介 二.SysTick功能框图 三.SysTick寄存器 四.SYSTICK使用 ...

最新文章

  1. 六大“未来式”存储器,谁将脱颖而出?
  2. mysql b 树删除操作,B-树的删除过程介绍
  3. openvino人脸
  4. 2017年伊始,你需要尝试的25个Android第三方库
  5. android studio使用nodejs本地服务器json数据_使用Node.js的Alexa技巧
  6. 深入理解java注解,java的4个元注解,注解三要素——定义、使用及读取执行,深入了解注解的底层本质,通过反射自动、动态获取注解所有属性以及属性值
  7. 超棒的jQuery密码强度检验插件 - Complexify
  8. asp.net mvc 缓存CaChe使用
  9. sql 删除最低分数_软件测试从业者:必备SQL语句21天打卡,前10天
  10. cocos2d-x的定时器
  11. 力扣-530. 二叉搜索树的最小绝对差
  12. android 黑名单中电话拦截
  13. masm汇编语言linux命令,Windows10下利用DOSBOX和MASM32搭建汇编语言开发环境
  14. 可以上传、下载文件的SSH客户端软件--SecureCRT绿色版
  15. harmonyos系统官网,harmonyos系统官网2.0版本
  16. OSPF —— 多区域部署 + ABR + ASBR + 路由重分发
  17. 热拉登陆找不到服务器,在线服务器服务器路径.ppt
  18. JVM系列(十七):字节码指令集
  19. 聊一聊前端程序员的现状与挑战
  20. jms:listener配置字段解释

热门文章

  1. python tkinter 进制转换工具
  2. BIM模型文件下载——某加油站服务区Revit模型
  3. C#和西门子PLC使用Udp通信
  4. Android FlowLayout流式布局
  5. MySQL优化--整理
  6. 仿礼物说小程序项目实战——1.项目介绍分析
  7. MX87QD主板使用说明书
  8. 我的世界java版无效会话_我的世界局域网联机显示无效的会话和搜不到主机
  9. 银联在线支付对接流程以及签名算法
  10. 常数和基本初等函数的导数