消息傳遞是線程之間的另一種基本通信模型。在消息傳遞模型中,一個線程顯式地發送數據,而另一個線程接收數據。操作更像是某種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 }