• μC/OS-II系统中消息邮箱的使用


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

    开发环境:TrueSTUDIO

    单片机:STM32F103VET6(HAL库)

    一、创建一个邮箱,OSMboxCreate()

      邮箱需要创建才能使用,通过调用OSMboxCreate()并指定指针的初始值来完成邮箱的创建。通常,初始值是一个空指针,但邮箱最初可以包含消息。如果使用邮箱表示事件的发生(即发送消息),通常将其初始化为空指针,因为事件(很可能)没有发生。如果使用邮箱访问共享资源,则使用非空指针初始化邮箱。函数原型为:

      1、OS_EVENT  *OSMboxCreate (void *msg)。

    • msg是指向您希望存入邮箱的消息的指针(如果您将这个值设置为空指针(即(void *)0),那么邮箱将被认为是空的);
    • 返回与邮箱相关联的指向事件控制块的指针。

    二、向一个邮箱发送一个消息,OSMboxPost()

      将消息存入邮箱,函数原型为:

      1、INT8U  OSMboxPost (OS_EVENT *pevent, void *msg)。

    • pevent是邮箱相关联的指向事件控制块的指针;
    • msg是指向您希望存入邮箱的消息的指针(发送的不能是空指针,由于邮箱发送的消息是地址,被发送的消息最好是全局变量);
    • 返回值是错误类型。

    三、在一个邮箱等待一个消息,OSMboxPend()

      等待消息到达邮箱,函数原型为:

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

    • pevent是邮箱相关联的指向事件控制块的指针;
    • timeout等待时长(如果是0将一直等下去,直到邮箱中有消息);
    • err错误类型;
    • 返回值是邮箱中收到的消息指针。

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

      1、定义一个邮箱事件指针:

    /* 定义一个邮箱事件指针 */
    OS_EVENT *MesageBox;

      2、创建一个邮箱并与上面定义的指针相关联,默认邮箱中消息为空

     /* 创建邮箱 */
     MesageBox = OSMboxCreate((void *)0);

      3、在任务中发送一个消息到消息邮箱

    static void AppTaskLed1(void *p_arg)
    {
        (void)p_arg;
    
        while(1)
        {
            if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET)
            {
                key_count1++;
                OSMboxPost(MesageBox, &key_count1);
            }
            OSTimeDlyHMSM(0, 0, 0, 100);
        }
    }

      4、在任务中执行消息邮箱的消息接收

    static void AppTaskLed2(void *p_arg)
    {
        INT8U err;
    
        (void)p_arg;
    
        while(1)
        {
            key_count2 = *(INT8U *)OSMboxPend(MesageBox, 0, &err);
            if(err == OS_ERR_NONE)
            {
                if(key_count2 > 0)
                {
                    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
                }
            }
        }
    }

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

      1、定义两个邮箱事件指针:

    OS_EVENT *MesageBox1;
    OS_EVENT *MesageBox2;

      2、创建两个邮箱并与上面定义的指针相关联,默认邮箱中消息为空

     /* 创建邮箱 */
     MesageBox1 = OSMboxCreate((void *)0);
     MesageBox2 = OSMboxCreate((void *)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)
        {
            key_count1++;
            OSMboxPost(MesageBox1, &key_count1);
        }
    
        if(GPIO_Pin == GPIO_PIN_13)
        {
            key_count2++;
            OSMboxPost(MesageBox2, &key_count2);
        }
    }

      5、创建两个任务分别去接收中断发出的邮箱消息:

    static void AppTaskLed1(void *p_arg)
    {
        INT8U err;
        INT8U count1 = 0;
    
        (void)p_arg;
    
        while(1)
        {
            count1 = *(INT8U *)OSMboxPend(MesageBox1, 0, &err);
            if(count1 > 0)
            {
                HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
            }
        }
    }
    
    static void AppTaskLed2(void *p_arg)
    {
        INT8U err;
        INT8U count2 = 0;
    
        (void)p_arg;
    
        while(1)
        {
            count2 = *(INT8U *)OSMboxPend(MesageBox2, 0, &err);
            if(count2 > 0)
            {
                HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
            }
        }
    }

    #endif

  • 相关阅读:
    【转】使用TortoiseSVN搭建本地的版本控制库
    操作系统的大端小端
    从《王者荣耀》谈游戏的帧同步
    二叉搜索树的第K大节点
    Mysql千万级大表优化
    海量数据存储方案
    递归函数思维
    time_wait的快速回收和重用
    Nginx配置反向代理服务器
    MySQL-怎样使update操作sleep一段时间
  • 原文地址:https://www.cnblogs.com/wenhao-Web/p/13788406.html
Copyright © 2020-2023  润新知