zoukankan      html  css  js  c++  java
  • μC/OS-II系统中信号量的使用

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

    开发环境:TrueSTUDIO

    单片机:STM32F103VET6(HAL库)

    一、创建一个信号量,OSSemCreate()

      信号量需要创建才能被使用,通过调用OSSemCreate()函数创建信号量,并指定初始信号量的数目,初始信号量的取值范围是0~65535。如果您使用信号量来表示一个或多个事件的发生,您通常会将信号量初始化为0。如果您使用这个信号量来访问一个共享资源,那么您需要将这个信号量初始化为1(也就是说,将它用作二进制信号量)。如果该信号量允许应用程序获得n个相同资源中的任何一个,则将该信号量初始化为n,并将其用作计数信号量。函数的原型为:

      1、OS_EVENT  *OSSemCreate (INT16U cnt)。

    • cnt是指初始可用信号量的数目;
    • 返回与信号量相关联的指向事件控制块的指针。

    二、发送一个信号量,OSSemPost()

      发送信号量,函数原型为:

      1、INT8U  OSSemPost (OS_EVENT *pevent)。

    • pevent是信号量相关联的指向事件控制块的指针;
    • 返回值是错误类型。

    三、等待一个信号量,OSSemPend()

      如果没有可用的信号量,则等待信号量,函数原型为:

      1、void  OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)。

    • pevent是信号量相关联的指向事件控制块的指针;
    • timeout等待时长(如果是0将一直等下去,直到有可用的信号量);
    • err保存错误类型。

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

      1、定义一个信号量事件指针:

    /* 定义一个信号量事件指针 */
    OS_EVENT *Semp;

      2、创建信号量,初始可用的信号量为0:

    /* 创建信号量,初始可用的信号量为0 */
    Semp = OSSemCreate(0);

      3、在一个任务中发送信号量

    static void AppTask1(void *p_arg)
    {
        (void)p_arg;
    
        while(1)
        {
            /* 发送一个信号量 */
            OSSemPost(Semp);
            OSTimeDlyHMSM(0, 0, 1, 0);
        }
    }

      4、在一个任务中接收信号量

    static void AppTaskLed(void *p_arg)
    {
        INT8U err;
    
        (void)p_arg;
    
        while(1)
        {
            /* 等待一个信号量 */
            OSSemPend(Semp, 0, &err);
            if(err == OS_ERR_NONE)
            {
                HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
            }
        }
    }

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

      1、定义信号量事件指针:

    /* 定义信号量事件指针 */
    OS_EVENT *Semp1;
    OS_EVENT *Semp2;

      2、创建信号量,初始可用的信号量为0:

    /* 创建两个信号量,初始可用的信号量都为0 */
    Semp1 = OSSemCreate(0);
    Semp2 = OSSemCreate(0);

      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)
    {
        if(GPIO_Pin == GPIO_PIN_0)
        {
            /* 发送信号量 */
            OSSemPost(Semp1);
        }
    
        if(GPIO_Pin == GPIO_PIN_13)
        {
            /* 发送信号量 */
            OSSemPost(Semp2);
        }
    }

      5、在两个任务分别去接收中断发出的信号量:

    static void AppTaskLed1(void *p_arg)
    {
        INT8U err;
    
        (void)p_arg;
    
        while(1)
        {
            /* 等待可用的信号量 */
            OSSemPend(Semp1, 0, &err);
            if(err == OS_ERR_NONE)
            {
                HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
            }
        }
    }
    
    static void AppTaskLed2(void *p_arg)
    {
        INT8U err;
    
        (void)p_arg;
    
        while(1)
        {
            /* 等待可用的信号量 */
            OSSemPend(Semp2, 0, &err);
            if(err == OS_ERR_NONE)
            {
                HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
            }
        }
    }

    #endif

  • 相关阅读:
    Pascal's Triangle II
    Pascal's Triangle
    Best Time to Buy and Sell Stock II
    Best Time to Buy and Sell Stock
    Populating Next Right Pointers in Each Node
    path sum II
    Path Sum
    [转载]小波时频图
    [转载]小波时频图
    [转载]Hilbert变换及谱分析
  • 原文地址:https://www.cnblogs.com/wenhao-Web/p/13797416.html
Copyright © 2011-2022 走看看