消息传递是线程之间的另一种基本通信模型。在消息传递模型中,一个线程显式地发送数据,而另一个线程接收数据。操作更像是某种I/O,而不是直接访问要共享的信息。在 CMSIS-RTOS 中,这种机制称为消息队列。和fifo的操作类似,数据从一个线程传递到另一个线程。使用消息队列功能,您可以控制、发送、接收或等待消息。要传递的数据可以是整型或指针类型:
Note:osMessageQueuePut, osMessageQueueGet, osMessageQueueGetCapacity, osMessageQueueGetMsgSize, osMessageQueueGetCount, osMessageQueueGetSpace 可在中断中调用。
1 typedef struct { 2 const char *name; /** 指向消息队列的名称 **/ 3 uint32_t attr_bits; /** 保留属性位 **/ 4 void *cb_mem; /** 指向消息队列控制块的内存。NULL,使用动态内存分配内存 **/ 5 uint32_t cb_size; /** 消息队列控制块的内存大小,最小值是 osRtxMessageQueueCbSize **/ 6 void *mq_mem; /** 指向存储消息的内存。NULL,使用动态内存分配内存 **/ 7 uint32_t mq_size; /** 存储消息的内存大小,最小值是 msg_count * msg_size **/ 8 } osMessageQueueAttr_t;
osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr)
msg_count:最大的消息数量。
msg_size :最大的消息字节大小,msg_size会被取整到32-bit,以满足内存块的32-bit对齐。
attr :消息队列属性。
返回消息队列ID,或者NULL。不可在中断中调用。
osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout)
mq_id :消息队列ID。
msg_ptr:指向将要放入消息队列的消息缓存区地址
msg_prio:消息优先级,用于在插入时根据消息的优先级(数字越高表示优先级越高)对消息进行排序。
timeout:等待超时时间。0,函数立即返回;osWaitForever,一直等待,直到消息被放入消息队列;other,等待的tick数。
返回值:
osOK:消息成功放入消息队列。
osErrorTimeout:等待超时失败。
osErrorResource:没有足够的空间错误。
osErrorParameter:mq_id参数错误,或者在中断中调用时设置的超时时间非零。
osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout)
mq_id :消息队列ID。
msg_ptr:指向从消息队列中获取的消息所存放的缓存区地址
msg_prio:用于存放获取的消息的优先级,或者设置为NULL。
timeout:等待超时时间。0,函数立即返回;osWaitForever,一直等待,直到消息从消息队列中获取;other,等待的tick数。
返回值:
osOK:成功获取消息。
osErrorTimeout:等待超时失败。
osErrorResource:未获取任何消息。
osErrorParameter:mq_id参数错误,或者在中断中调用时设置的超时时间非零。
1 void 2 testMsgQueue(void) 3 { 4 msg_queue = osMessageQueueNew(3, 4, NULL); 5 6 osThreadNew(_putThread, NULL, NULL); 7 osThreadNew(_getThread, NULL, NULL); 8 } 9 10 static void 11 _putThread(void *argument) 12 { 13 (void)argument; 14 uint32_t cnt = 0; 15 16 for(;;) { 17 osMessageQueuePut(msg_queue, &cnt, 0, 10); 18 cnt ++; 19 osDelay(1000); 20 } 21 } 22 23 static void 24 _getThread(void *argument) 25 { 26 (void)argument; 27 uint32_t cnt; 28 29 for(;;) { 30 osMessageQueueGet(msg_queue, &cnt, NULL, osWaitForever); 31 menuShow(&seg_led, cnt, 0); 32 } 33 }