/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ // ==== Message Queue Management ==== /** @addtogroup CMSIS_RTOS_Message Message Queue @ingroup CMSIS_RTOS @brief Exchange messages between threads in a FIFO-like operation. @details \b Message \b passing is another basic communication model between threads. In the message passing model, one thread sends data explicitly, while another thread receives it. The operation is more like some kind of I/O rather than a direct access to information to be shared. In CMSIS-RTOS, this mechanism is called s \b message \b queue. The data is passed from one thread to another in a FIFO-like operation. Using message queue functions, you can control, send, receive, or wait for messages. The data to be passed can be of integer or pointer type: \image html "MessageQueue.png" "CMSIS-RTOS Message Queue" Compared to a \ref CMSIS_RTOS_PoolMgmt, message queues are less efficient in general, but solve a broader range of problems. Sometimes, threads do not have a common address space or the use of shared memory raises problems, such as mutual exclusion. Working with Message Queues --------------------------- Follow these steps to create and use a message queue: -# Setup the message queue: \code{.c} osMessageQueueId_t MsgQ_Id; // Define a message queue ID \endcode -# Then, create the message queue in a thread: \code{.c} MsgQId_Isr = osMessageQueueNew (16, sizeof(uint32_t), NULL); // Instance a message queue for 16 elements of uint32_t \endcode -# Fill the message queue with data: \code{.c} uint32_t data = 512; osMessageQueuePut(MsgQ_Id, data, 0, 0); \endcode -# From the receiving thread access the data using: \code{.c} uint32_t msg; osMessageQueueGet(MsgQ_Id, &msg, NULL, 0); \endcode @{ */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \def osMessageQueueId_t \details */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \struct osMessageQueueAttr_t \details Attributes structure for message queue. */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \fn osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) \details */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \fn osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); \details Code Example: \code{.c} #include "cmsis_os2.h" // CMSIS RTOS header file /*---------------------------------------------------------------------------- * Message Queue creation & usage *---------------------------------------------------------------------------*/ void Thread_MsgQueue1 (void *argument); // thread function 1 void Thread_MsgQueue2 (void *argument); // thread function 2 osThreadId_t tid_Thread_MsgQueue1; // thread id 1 osThreadId_t tid_Thread_MsgQueue2; // thread id 2 #define MSGQUEUE_OBJECTS 16 // number of Message Queue Objects typedef struct { // object data type uint8_t Buf[32]; uint8_t Idx; } MSGQUEUE_OBJ_t; osMemoryPoolId_t mpid_MemPool2; // memory pool id osMessageQueueId_t mid_MsgQueue; // message queue id int Init_MsgQueue (void) { mid_MsgQueue = osMessageQueueNew(MSGQUEUE_OBJECTS, sizeof(MSGQUEUE_OBJ_t), NULL); if (!mid_MsgQueue) { ; // Message Queue object not created, handle failure } tid_Thread_MsgQueue1 = osThreadNew (Thread_MsgQueue1, NULL, NULL); if (!tid_Thread_MsgQueue1) return(-1); tid_Thread_MsgQueue2 = osThreadNew (Thread_MsgQueue2, NULL, NULL); if (!tid_Thread_MsgQueue2) return(-1); return(0); } void Thread_MsgQueue1 (void *argument) { MSGQUEUE_OBJ_t pMsg = 0; while (1) { ; // Insert thread code here... pMsg->Buf[0] = 0x55; // do some work... pMsg->Idx = 0; osMessageQueuePut (mid_MsgQueue, &pMsg, NULL, NULL); osThreadYield (); // suspend thread } } void Thread_MsgQueue2 (void *argument) { MSGQUEUE_OBJ_t pMsg = 0; while (1) { ; // Insert thread code here... status = osMessageQueueGet (mid_MsgQueue, &pMsg, NULL, NULL); // wait for message if (status == osOK) { ; // process data } } } \endcode */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \fn osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) \details */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \fn uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) \details */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \fn uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) \details */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \fn uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) \details */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \fn uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) \details */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \fn osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) \details */ /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ /** \fn osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) \details */ /// @}