0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于STM32F407的FreeRTOS学习笔记(7)

CHANBAEK 来源:实在太懒于是不想取名 作者: 电路小白 2023-11-08 11:04 次阅读

本期在二进制信号量的基础上介绍计数信号量

01基本介绍

图片

01.什么是计数信号量

计数信号量顾名思义是用来计数的信号量,相比于二进制信号量,计数信号量的并不只有两种状态。用官方的开发者文档中的话来说,计数信号量可以看作长度大于1的队列,我们并不关心其中的内容而是关系队列是否为空。

关于队列的公众号可以参考这篇文章。

02.如何创建计数信号量

图片

官方的参考文档中提供了两种创建方式(动态和静态)我们使用动态创建方式。调用xSemaphoreCreateCounting函数

其中包含了两个参数,一个是最大计数量还有一个是初始计数量。

创建一个SemaphoreHandler_t类型的句柄变量用以接收返回值。

03.释放和获取信号量

释放和获取信号量和上一期二进制信号量的释放和获取方式一样。均是调用

xSemaphoreGive释放信号量以及调用

xSemaphoreTake获取信号量。

但是计数信号量则多了一个可以调用的函数。

图片

调用这个函数我们就可以获得计数值啦。

02代码编写

1测试流程

我们做两个实验,首先是使用一个LED函数,函数每翻转一次就向计数信号量释放一次信号。

第二个函数轮询计数信号量,当计数信号量的数量比一半多时,使另一个LED也开始进行翻转并同样释放信号量。当计数信号量到达最大数时,关闭第二个灯的翻转。

2大体思路

第一个LED灯翻转,发送信号量。定义一个轮询函数用来时刻检测信号量状况,当信号量到达一定数量时恢复LED2任务的运行,当信号量满时清空信号量列表并挂起LED2

任务的挂起与恢复可以参考这期。

3代码编写

首先是任务启动函数,在这个函数中我们要创建一个计数信号量并且启动其他的相关任务函数。

void Start_LED(void * pvParameters)
{
  taskENTER_CRITICAL();                            

  LED_SemaphoreHandler = xSemaphoreCreateCounting(20,0);//最大计数20,初始0
  if(LED_SemaphoreHandler!=NULL)
  {
    printf("Semaphore Create Successfullyrn");
  }

  xTaskCreate((TaskFunction_t        )LED_TOG,//任务函数
              (char *                )"LED_TOG",//任务名称
              (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
              (void*                 ) NULL,//无返回
              (UBaseType_t          ) 1,//优先级1
              (TaskHandle_t *        )&LED_TOG_Handler);//任务函数句柄

   xTaskCreate((TaskFunction_t        )LED_TOG2,//任务函数
              (char *                )"LED_TOG2",//任务名称
              (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
              (void*                 ) NULL,//无返回
              (UBaseType_t          ) 2,//优先级1
              (TaskHandle_t *        )&LED_TOG2_Handler);//任务函数句柄

     xTaskCreate((TaskFunction_t        )CountTest,//任务函数
              (char *                )"GetCount",//任务名称
              (configSTACK_DEPTH_TYPE) 128,//堆栈空间128Byte
              (void*                 ) NULL,//无返回
              (UBaseType_t          ) 0,//优先级1
              (TaskHandle_t *        )&GetCount_Handler);//任务函数句柄

  taskEXIT_CRITICAL();
  vTaskSuspend(LED_TOG2_Handler);
  vTaskDelete(NULL);
}

其次LED函数的内容非常简单,检测信号量是否创建(指针不为空)如果指针不为空则翻转LED,并且释放信号量。(注意第二个LED的函数不释放信号量防止释放两次信号量)

void LED_TOG(void * pvParameters)//参数为 void * pvParameters
{

  while(1)
  {
    if(LED_SemaphoreHandler!=NULL)
    {
      HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_9);
      xSemaphoreGive(LED_SemaphoreHandler);
    }

    vTaskDelay(500);//延迟500ms
  }
}


void LED_TOG2(void * pvParameters)//参数为 void * pvParameters
{
  while(1)
  {
    if(LED_SemaphoreHandler!=NULL)
    {
      HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);
    }
    vTaskDelay(500);
  }
}

在循环检测函数中,我们定义一个count来接收计数信号量的数量。接着当信号量大于10时我们恢复LED2函数的运行(可以多次恢复,只有一次效果)。

当信号量为20时,我们先暂停LED1函数的运行防止我们清空信号量的时候LED1又在释放信号量。之后通过不断的获取信号量来清空信号量,因为信号量本质就是队列,之后恢复他们的运行。

void CountTest(void * pvParameters)
{
  while(1)
  {
    BaseType_t count;
    if(LED_SemaphoreHandler!=NULL)
    {
      count = uxSemaphoreGetCount(LED_SemaphoreHandler);
      if(count >= 9 )
      {
        vTaskResume(LED_TOG2_Handler);//恢复函数2
      }
      if(count >= 20 )
      {
        vTaskSuspend(LED_TOG_Handler);//先挂起函数1
        while(count != 0)
        {
          xSemaphoreTake(LED_SemaphoreHandler,10);
          count = uxSemaphoreGetCount(LED_SemaphoreHandler);
        }

        vTaskResume(LED_TOG_Handler);//恢复函数1
        vTaskSuspend(LED_TOG2_Handler);//挂起函数2
      }

    }
    vTaskDelay(10);
  }
}
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 二进制
    +关注

    关注

    2

    文章

    761

    浏览量

    41475
  • 函数
    +关注

    关注

    3

    文章

    4235

    浏览量

    61965
  • FreeRTOS
    +关注

    关注

    12

    文章

    483

    浏览量

    61724
  • 信号量
    +关注

    关注

    0

    文章

    53

    浏览量

    8282
收藏 人收藏

    评论

    相关推荐

    基于STM32F407FreeRTOS学习笔记(9)

    在嵌入式编程中,定时器是一个非常重要且强大的功能,用来帮我们定时性的调用中断服务函数来帮助我们处理程序。定时器通常是用硬件来实现的,例如STM32F407就有8个硬件定时器。
    的头像 发表于 11-08 11:08 705次阅读
    基于<b class='flag-5'>STM32F407</b>的<b class='flag-5'>FreeRTOS</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>(9)

    STM32F407模板

    STM32F407模板,感兴趣可以看看。
    发表于 07-25 18:52 129次下载

    STM32F407 UCOS III实验

    STM32F407 UCOS III实验,介绍基于STM32F407的UCOSIII实例,参考下
    发表于 09-22 14:08 81次下载

    STM32F407 DCMI摄像头源码

    STM32F407 DCMI摄像头源码(电源技术存在的问题总结)-【资源描述】:STM32F407 DCMI摄像头源码【编程语言】:C语言
    发表于 09-16 16:15 123次下载
    <b class='flag-5'>STM32F407</b> DCMI摄像头源码

    STM32F407标准库学习笔记-AFIO未完

    STM32F407标准库学习笔记-AFIO- 头文件 gpio.h#define GPIO_PinSource0 ((uint8_t)0x00)#define
    发表于 11-29 15:36 2次下载
    <b class='flag-5'>STM32F407</b>标准库<b class='flag-5'>学习</b><b class='flag-5'>笔记</b>-AFIO未完

    STM32F407标准库学习笔记-RCC

    STM32F407标准库学习笔记-RCC- rcc.htypedef struct{ uint32_t SYSCLK_Frequency; /*!< SYSCLK clock
    发表于 11-29 15:51 13次下载
    <b class='flag-5'>STM32F407</b>标准库<b class='flag-5'>学习</b><b class='flag-5'>笔记</b>-RCC

    STM32F407标准库学习笔记-GPIO

    STM32F407标准库学习笔记-GPIO头文件 gpio.h枚举-列举同一寄存器的不同选项typedef enum{ GPIO_Low_Speed = 0x00, /*!<
    发表于 11-29 15:51 46次下载
    <b class='flag-5'>STM32F407</b>标准库<b class='flag-5'>学习</b><b class='flag-5'>笔记</b>-GPIO

    STM32F407的串口UART 基础配置STM32CubeMX

    STM32F407的串口UART 基础配置STM32CubeMX
    发表于 11-29 16:06 54次下载
    <b class='flag-5'>STM32F407</b>的串口UART 基础配置<b class='flag-5'>STM32</b>CubeMX

    [STM32]STM32F407系列教程之四,pwm产生原理

    [STM32]STM32F407系列教程之四,pwm产生原理
    发表于 11-29 17:51 51次下载
    [<b class='flag-5'>STM32</b>]<b class='flag-5'>STM32F407</b>系列教程之四,pwm产生原理

    STM32F407芯片介绍

    1. 文档准备做嵌入式开发的第一步就是了解主芯片,了解STM32F407主要要关注几个文档:1. stm32F407芯片手册2. stm32F407参考手册3. Arm Cortex-M4数据手册
    发表于 12-04 13:21 109次下载
    <b class='flag-5'>STM32F407</b>芯片介绍

    STM32F407开发板用户手册】第1章   初学STM32F407的准备工作

    STM32F407开发板用户手册】第1章   初学STM32F407的准备工作
    发表于 12-04 13:36 75次下载
    【<b class='flag-5'>STM32F407</b>开发板用户手册】第1章   初学<b class='flag-5'>STM32F407</b>的准备工作

    STM32F407原理图下载

    STM32F407原理图下载
    发表于 01-17 13:44 416次下载

    stm32f407原理图

    stm32f407原理图
    发表于 07-14 16:07 201次下载

    STM32F407最小系统

    STM32F407最小系统免费下载。
    发表于 07-31 11:01 166次下载

    STM32F407 FreeRTOS开发手册 V1.1

    STM32F407 FreeRTOS开发手册_V1.1PDF文件下载。
    发表于 07-31 11:16 52次下载