• μC/OS-II系统中事件标志的使用


    以下内容主要注重应用,对源码不做分析,对源码有兴趣的可参考官方具体文档,相关链接:https://doc.micrium.com/display/ucos/

    开发环境:TrueSTUDIO

    单片机:STM32F103VET6(HAL库)

    一、创建一个事件标志组,OSFlagCreate()

      事件标志需要创建才能被使用,通过调用OSFlagCreate()函数创建,并指定存储在事件标志组中的初始值。函数原型为:

      1、OS_FLAG_GRP  *OSFlagCreate (OS_FLAGS flags, INT8U *err):

    • flags是包含要存储在事件标志组中的初始值;
    • err保存错误类型;
    • 返回与标志组相关联的指针。

    二、置位或清除事件在一个事件标志组中,OSFlagPost()

      设置或清除事件标志组中的位,函数原型为:

      1、OS_FLAGS  OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U opt, INT8U *err):

    • pgrp是指向所需事件标志组的指针;
    • flags如果'opt'是OS_FLAG_SET,则在'flags'中设置的每个位将在事件标志组中被置位;如果'opt'是OS_FLAG_CLR,则在'flags'中设置的每个位将被清除;
    • opt标志位的状态;
    • err保存错误类型。

    三、在一个事件标志组中等待事件,OSFlagPend()

      等待事件标志组的事件,函数原型为:

      1、OS_FLAGS  OSFlagPend (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT16U timeout, INT8U *err):

    • pgrp是指向所需事件标志组的指针
    • flags指定您希望等待哪个位(即标志)。您需要的位通过在“flags”中设置相应的位来指定。例如,如果你的应用程序想要等待位0和1,那么“标志”将包含0x03。
    • wait_type你指定的所有位被置位还是其中一个为被置位(如果你想等待到事件标志,对应的位被清零,还需要添加OS_FLAG_CONSUME);
    • timeout等待时长(如果是0将一直等下去);
    • err 保存错误类型。

    四、示例代码(非中断方式)

      1、定义一个事件标志组指针:

    /* 定义一个事件标志组 */
    OS_FLAG_GRP *FlagStat;

      2、创建事件标志组:

    /* 创建事件标志组 */
    FlagStat = OSFlagCreate(0x0, &err);

      3、在两个任务中分别发送事件标志:

    static void AppTask1(void *p_arg)
    {
        INT8U err;
    
        (void)p_arg;
    
        while(1)
        {
            if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET)
            {
                /* 设置bit0为1 */
                OSFlagPost(FlagStat, 0x01, OS_FLAG_SET, &err);
            }
            OSTimeDlyHMSM(0, 0, 0, 100);
        }
    }
    
    static void AppTask2(void *p_arg)
    {
        INT8U err;
    
        (void)p_arg;
    
        while(1)
        {
            if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_SET)
            {
                /* 设置bit1 为1 */
                OSFlagPost(FlagStat, 0x02, OS_FLAG_SET, &err);
            }
            OSTimeDlyHMSM(0, 0, 0, 100);
        }
    }

      4、在一个任务中等待两个事件标志:

    static void AppTaskLed(void *p_arg)
    {
        INT8U err;
    
        (void)p_arg;
    
        while(1)
        {
            /* 等待bit0和bit1 都被置位,因为添加OS_FLAG_CONSUME,当等到事件标志会被相应的位会被清零 */
            OSFlagPend(FlagStat, 0x03, OS_FLAG_WAIT_SET_ALL + OS_FLAG_CONSUME, 0, &err);
            if(err == OS_ERR_NONE)
            {
                HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
            }
        }
    }

    五、示例代码(中断方式)

       1、定义一个事件标志组指针:

    /* 定义一个事件标志组 */
    OS_FLAG_GRP *FlagStat;

      2、创建事件标志组:

    /* 创建事件标志组 */
    FlagStat = OSFlagCreate(0x0, &err);

      3、中断函数中进行针对μC/OS系统的处理:

    /**
      * @brief This function handles EXTI line0 interrupt.
      */
    void EXTI0_IRQHandler(void)
    {
    #if uCOS_EN == 1
    
    #if OS_CRITICAL_METHOD == 3u                 /* Allocate storage for CPU status register               */
        OS_CPU_SR   cpu_sr = 0u;
    #endif
    
        OS_ENTER_CRITICAL();
        OSIntEnter();
        OS_EXIT_CRITICAL();
    #endif
    
        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
    
    #if uCOS_EN == 1
        OSIntExit();
    #endif
    
    }
    
    /**
      * @brief This function handles EXTI line[15:10] interrupts.
      */
    void EXTI15_10_IRQHandler(void)
    {
    #if uCOS_EN == 1
    
    #if OS_CRITICAL_METHOD == 3u                 /* Allocate storage for CPU status register               */
        OS_CPU_SR   cpu_sr = 0u;
    #endif
    
        OS_ENTER_CRITICAL();
        OSIntEnter();
        OS_EXIT_CRITICAL();
    #endif
    
        HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
    
    #if uCOS_EN == 1
        OSIntExit();
    #endif
    }

      4、在中断的回调函数中发送事件标志,针对不同端口引脚被触发发送不同的事件标志:

    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
    {
        INT8U err;
    
        if(GPIO_Pin == GPIO_PIN_0)
        {
            OSFlagPost(FlagStat, 0x01, OS_FLAG_SET, &err);
        }
    
        if(GPIO_Pin == GPIO_PIN_13)
        {
            OSFlagPost(FlagStat, 0x02, OS_FLAG_SET, &err);
        }
    }

      5、在一个任务去接收中断发出的事件标志:

    static void AppTaskLed1(void *p_arg)
    {
        INT8U err;
    
        (void)p_arg;
    
        while(1)
        {
            OSFlagPend(FlagStat, 0x03, OS_FLAG_WAIT_SET_ALL + OS_FLAG_CONSUME, 0, &err);
            if(err == OS_ERR_NONE)
            {
                HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
            }
        }
    }

    #endif

  • 相关阅读:
    JS & JQuery 动态处理select option
    如何在Oracle中复制表结构和表数据
    基于cxf的app文件上传接口(带回显功能)
    Jenkins的详细安装及使用--windows
    git用代码库文件完全覆盖本地/git不能提交jar的设置
    Windows平台下Git服务器搭建
    Vue脚手架之Vue-cli
    Vue的生命周期
    Vue状态管理之Vuex
    Vue路由管理之Vue-router
  • 原文地址:https://www.cnblogs.com/wenhao-Web/p/13834687.html
Copyright © 2020-2023  润新知