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

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

编译环境:Atollic TrueSTUDIO for STM32 9.3.0

硬件:基于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

posted @ 2020-10-09 20:48  不要让自己太懒  阅读(917)  评论(0编辑  收藏  举报