CubeMX STM32 FreeRTOS 计数信号量实验

一、概述

软件:
1、MDK-ARM 5
2、STM32CubeMX
3、开发板:STM32F106ZET6

二、主要内容

计数信号量的使用场景:一个二值信号量最多只可以锁存一个中断事件。在锁存的事件还未被处理之前,如果还有中断事件发生,那么后续发生的中断事件将会丢失。如果 用计数信号量代替二值信号量,那么,这种丢中断的情形将可以避免。

cubemx:版本5.2.1
STM32:stm32f103zet6
系统时钟:72M
1、RCC配置
CubeMX STM32 FreeRTOS 计数信号量实验_第1张图片
2、SYS配置,注意Timebase Source的选择
CubeMX STM32 FreeRTOS 计数信号量实验_第2张图片
3、FreeRTOS:创建两个任务
CubeMX STM32 FreeRTOS 计数信号量实验_第3张图片
4、FreeRTOS:创建深度为10的计数信号量
CubeMX STM32 FreeRTOS 计数信号量实验_第4张图片
5、根据原理图,将LED对应引脚设置为输出模式
CubeMX STM32 FreeRTOS 计数信号量实验_第5张图片

三、程序实现

  1. 添加freertos.c 中task01内容,StartTask01功能是:发送 1 次信号量,间隔一秒后发送 2 次,再间隔一秒发送 3 次,然后等待 2秒。
/* USER CODE END Header_StartTask01 */
void StartTask01(void const * argument)
{
  /* USER CODE BEGIN StartTask01 */
  /* Infinite loop */
  for(;;)
  {
		osDelay(1000);
		osSemaphoreRelease(myCountingSem01Handle);
		osDelay(1000);
		osSemaphoreRelease(myCountingSem01Handle);
		osSemaphoreRelease(myCountingSem01Handle);
		osDelay(1000);
		osSemaphoreRelease(myCountingSem01Handle);
		osSemaphoreRelease(myCountingSem01Handle);
		osSemaphoreRelease(myCountingSem01Handle);
		osDelay(2000);
	}
	
  /* USER CODE END StartTask01 */
}
  1. 添加freertos.c 中task02内容,等待信号量,然后控制 LED0 和 LED1 闪烁一次。
/* USER CODE END Header_StartTask02 */
void StartTask02(void const * argument)
{
  /* USER CODE BEGIN StartTask02 */
  /* Infinite loop */
  for(;;)
  {
		osSemaphoreWait(myCountingSem01Handle,osWaitForever);
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13,GPIO_PIN_SET);
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_14,GPIO_PIN_SET);
		osDelay(100);
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_13,GPIO_PIN_RESET);
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_14,GPIO_PIN_RESET);
		osDelay(100);
  }
  /* USER CODE END StartTask02 */
}

四、结果分析

编译下载运行。
现象是: LED 闪 1 次,一秒后闪 2 次,再过一秒闪 3 次,再等三秒, LED 闪 1次…如此循环。
程序分析:
在 StartTask01()任务中,连续调用 osSemaphoreRelease(myCountingSem01Handle);两次或者三次耗时是很短的,而StartTask02()任务执行一次 LED 闪烁耗时大约是 200 毫秒,会造成信号量值的累积。

如果把信号量的定义语句:

myCountingSem01Handle = osSemaphoreCreate(osSemaphore(myCountingSem01), 10);

的最后一个参数改为 1,即改为:

myCountingSem01Handle = osSemaphoreCreate(osSemaphore(myCountingSem01), 1);

这样就变成了二值信号量。

运行结果是, LED 闪 1 次,一秒后闪 1 次,再过一秒闪 1 次,再等三秒, LED 闪 1次…如此循环。

由此可知,在连续释放二值信号时,如果处理信号量相关事件的函数来不及处理,就会造成事件的丢失。
从而也可以看出,计数信号量相对于二值信号量的优势。

你可能感兴趣的:(CubeMX STM32 FreeRTOS 计数信号量实验)