以下内容主要注重应用,对源码不做分析,对源码有兴趣的可参考官方具体文档,相关链接: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