1/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 2// ==== Message Queue Management ==== 3/** 4@addtogroup CMSIS_RTOS_Message Message Queue 5@ingroup CMSIS_RTOS 6@brief Exchange messages between threads in a FIFO-like operation. 7@details 8\b Message \b passing is another basic communication model between threads. In the message passing model, one thread sends 9data explicitly, while another thread receives it. The operation is more like some kind of I/O rather than a direct access to 10information to be shared. In CMSIS-RTOS, this mechanism is called a \b message \b queue. The data is passed from one thread 11to another in a FIFO-like operation. Using message queue functions, you can control, send, receive, or wait for messages. The 12data to be passed can be of integer or pointer type: 13 14\image html "MessageQueue.png" "CMSIS-RTOS Message Queue" 15 16Compared to a \ref CMSIS_RTOS_PoolMgmt, message queues are less efficient in general, but solve a broader range of problems. 17Sometimes, threads do not have a common address space or the use of shared memory raises problems, such as mutual exclusion. 18 19\note The functions \ref osMessageQueuePut, \ref osMessageQueueGet, \ref osMessageQueueGetCapacity, 20\ref osMessageQueueGetMsgSize, \ref osMessageQueueGetCount, \ref osMessageQueueGetSpace can be called from 21\ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 22 23@{ 24*/ 25/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 26/** 27\def osMessageQueueId_t 28\details 29Returned by: 30- \ref osMessageQueueNew 31*/ 32 33/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 34/** 35\struct osMessageQueueAttr_t 36\details 37Specifies the following attributes for the \ref osMessageQueueNew function. 38*/ 39 40/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 41/** 42\fn osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) 43\details 44The function \ref osMessageQueueNew creates and initializes a message queue object. 45The function returns a message queue object identifier or \token{NULL} in case of an error. 46 47The function can be called after kernel initialization with \ref osKernelInitialize. It is possible to 48create message queue objects before the RTOS kernel is started with \ref osKernelStart. 49 50The total amount of memory required for the message queue data is at least <code>msg_count * msg_size</code>. 51The \em msg_size is rounded up to a double even number to ensure 32-bit alignment of the memory blocks. 52 53The memory blocks allocated from the message queue have a fixed size defined with the parameter \c msg_size. 54 55\note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 56 57<b>Code Example</b> 58 59Refer to \ref osMessageQueuePut 60*/ 61 62/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 63/** 64\fn const char *osMessageQueueGetName (osMessageQueueId_t mq_id) 65\details 66The function \b osMessageQueueGetName returns the pointer to the name string of the message queue identified by parameter \a 67mq_id or \token{NULL} in case of an error. 68 69\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 70*/ 71 72/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 73/** 74\fn osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) 75\details 76The blocking function \b osMessageQueuePut puts the message pointed to by \a msg_ptr into the the message queue specified 77by parameter \a mq_id. The parameter \a msg_prio is used to sort message according their priority (higher numbers indicate 78a higher priority) on insertion. 79 80The parameter \a timeout specifies how long the system waits to put the message into the queue. While the system waits, the 81thread that is calling this function is put into the \ref ThreadStates "BLOCKED" state. The parameter \ref CMSIS_RTOS_TimeOutValue "timeout" 82can have the following values: 83 - when \a timeout is \token{0}, the function returns instantly (i.e. try semantics). 84 - when \a timeout is set to \b osWaitForever the function will wait for an infinite time until the message is delivered (i.e. wait semantics). 85 - all other values specify a time in kernel ticks for a timeout (i.e. timed-wait semantics). 86 87Possible \ref osStatus_t return values: 88 - \em osOK: the message has been put into the queue. 89 - \em osErrorTimeout: the message could not be put into the queue in the given time (wait-timed semantics). 90 - \em osErrorResource: not enough space in the queue (try semantics). 91 - \em osErrorParameter: parameter \em mq_id is \token{NULL} or invalid, non-zero timeout specified in an ISR. 92 - \em osErrorSafetyClass: the calling thread safety class is lower than the safety class of the specified message queue. 93 94\note May be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" if the parameter \a timeout is set to 95\token{0}. 96 97<b>Code Example:</b> 98\code 99#include "cmsis_os2.h" // CMSIS RTOS header file 100 101/*---------------------------------------------------------------------------- 102 * Message Queue creation & usage 103 *---------------------------------------------------------------------------*/ 104 105#define MSGQUEUE_OBJECTS 16 // number of Message Queue Objects 106 107typedef struct { // object data type 108 uint8_t Buf[32]; 109 uint8_t Idx; 110} MSGQUEUE_OBJ_t; 111 112osMessageQueueId_t mid_MsgQueue; // message queue id 113 114osThreadId_t tid_Thread_MsgQueue1; // thread id 1 115osThreadId_t tid_Thread_MsgQueue2; // thread id 2 116 117void Thread_MsgQueue1 (void *argument); // thread function 1 118void Thread_MsgQueue2 (void *argument); // thread function 2 119 120int Init_MsgQueue (void) { 121 122 mid_MsgQueue = osMessageQueueNew(MSGQUEUE_OBJECTS, sizeof(MSGQUEUE_OBJ_t), NULL); 123 if (mid_MsgQueue == NULL) { 124 ; // Message Queue object not created, handle failure 125 } 126 127 tid_Thread_MsgQueue1 = osThreadNew(Thread_MsgQueue1, NULL, NULL); 128 if (tid_Thread_MsgQueue1 == NULL) { 129 return(-1); 130 } 131 tid_Thread_MsgQueue2 = osThreadNew(Thread_MsgQueue2, NULL, NULL); 132 if (tid_Thread_MsgQueue2 == NULL) { 133 return(-1); 134 } 135 136 return(0); 137} 138 139void Thread_MsgQueue1 (void *argument) { 140 MSGQUEUE_OBJ_t msg; 141 142 while (1) { 143 ; // Insert thread code here... 144 msg.Buf[0] = 0x55U; // do some work... 145 msg.Idx = 0U; 146 osMessageQueuePut(mid_MsgQueue, &msg, 0U, 0U); 147 osThreadYield(); // suspend thread 148 } 149} 150 151void Thread_MsgQueue2 (void *argument) { 152 MSGQUEUE_OBJ_t msg; 153 osStatus_t status; 154 155 while (1) { 156 ; // Insert thread code here... 157 status = osMessageQueueGet(mid_MsgQueue, &msg, NULL, 0U); // wait for message 158 if (status == osOK) { 159 ; // process data 160 } 161 } 162} 163\endcode 164*/ 165 166/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 167/** 168\fn osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) 169\details 170The function \b osMessageQueueGet retrieves a message from the message queue specified by the parameter \a mq_id and saves it 171to the buffer pointed to by the parameter \a msg_ptr. The message priority is stored to parameter \a msg_prio if not token{NULL}. 172 173The parameter \a timeout specifies how long the system waits to retrieve the message from the queue. While the system waits, 174the thread that is calling this function is put into the \ref ThreadStates "BLOCKED" state. The parameter 175\ref CMSIS_RTOS_TimeOutValue "timeout" can have the following values: 176 - when \a timeout is \token{0}, the function returns instantly (i.e. try semantics). 177 - when \a timeout is set to \b osWaitForever the function will wait for an infinite time until the message is retrieved (i.e. wait semantics). 178 - all other values specify a time in kernel ticks for a timeout (i.e. timed-wait semantics). 179 180Possible \ref osStatus_t return values: 181 - \em osOK: the message has been retrieved from the queue. 182 - \em osErrorTimeout: the message could not be retrieved from the queue in the given time (timed-wait semantics). 183 - \em osErrorResource: nothing to get from the queue (try semantics). 184 - \em osErrorParameter: parameter \em mq_id is \token{NULL} or invalid, non-zero timeout specified in an ISR. 185 - \em osErrorSafetyClass: the calling thread safety class is lower than the safety class of the specified message queue. 186 187\note May be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines" if the parameter \a timeout is set to 188\token{0}. 189 190<b>Code Example</b> 191 192Refer to \ref osMessageQueuePut 193*/ 194 195/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 196/** 197\fn uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) 198\details 199The function \b osMessageQueueGetCapacity returns the maximum number of messages in the message queue object specified by 200parameter \a mq_id or \token{0} in case of an error. 201 202\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 203*/ 204 205/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 206/** 207\fn uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) 208\details 209The function \b osMessageQueueGetMsgSize returns the maximum message size in bytes for the message queue object specified by 210parameter \a mq_id or \token{0} in case of an error. 211 212\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 213*/ 214 215/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 216/** 217\fn uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) 218\details 219The function \b osMessageQueueGetCount returns the number of queued messages in the message queue object specified by 220parameter \a mq_id or \token{0} in case of an error. 221 222\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 223*/ 224 225/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 226/** 227\fn uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) 228\details 229The function \b osMessageQueueGetSpace returns the number available slots for messages in the message queue object specified 230by parameter \a mq_id or \token{0} in case of an error. 231 232\note This function may be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 233*/ 234 235/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 236/** 237\fn osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) 238\details 239The function \b osMessageQueueReset resets the message queue specified by the parameter \a mq_id. 240 241Possible \ref osStatus_t return values: 242 - \em osOK: the message queue has been rest. 243 - \em osErrorParameter: parameter \em mq_id is \token{NULL} or invalid. 244 - \em osErrorResource: the message queue is in an invalid state. 245 - \em osErrorISR: \b osMessageQueueReset cannot be called from interrupt service routines. 246 - \em osErrorSafetyClass: the calling thread safety class is lower than the safety class of the specified message queue. 247 248\note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 249*/ 250 251/*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/ 252/** 253\fn osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) 254\details 255The function \b osMessageQueueDelete deletes a message queue object specified by parameter \a mq_id. It releases internal 256memory obtained for message queue handling. After this call, the \a mq_id is no longer valid and cannot be used. The 257message queue may be created again using the function \ref osMessageQueueNew. 258 259Possible \ref osStatus_t return values: 260 - \em osOK: the message queue object has been deleted. 261 - \em osErrorParameter: parameter \em mq_id is \token{NULL} or invalid. 262 - \em osErrorResource: the message queue is in an invalid state. 263 - \em osErrorISR: \b osMessageQueueDelete cannot be called from interrupt service routines. 264 - \em osErrorSafetyClass: the calling thread safety class is lower than the safety class of the specified message queue. 265 266\note This function \b cannot be called from \ref CMSIS_RTOS_ISR_Calls "Interrupt Service Routines". 267*/ 268/// @} 269 270// these struct members must stay outside the group to avoid double entries in documentation 271/** 272\var osMessageQueueAttr_t::attr_bits 273\details 274Reserved for future use (must be set to '0' for future compatibility). 275 276\var osMessageQueueAttr_t::cb_mem 277\details 278Pointer to a memory for the message queue control block object. Refer to \ref CMSIS_RTOS_MemoryMgmt_Manual for more information. 279 280Default: \token{NULL} to use \ref CMSIS_RTOS_MemoryMgmt_Automatic for the message queue control block. 281 282\var osMessageQueueAttr_t::cb_size 283\details 284The size (in bytes) of memory block passed with \ref cb_mem. Required value depends on the underlying kernel implementation. 285 286Default: \token{0} as the default is no memory provided with \ref cb_mem. 287 288\var osMessageQueueAttr_t::name 289\details 290Pointer to a constant string with a human readable name (displayed during debugging) of the message queue object. 291 292Default: \token{NULL} no name specified. 293 294\var osMessageQueueAttr_t::mq_mem 295\details 296Pointer to a memory for the message queue data. Refer to \ref CMSIS_RTOS_MemoryMgmt_Manual for more information. 297 298Default: \token{NULL} to use \ref CMSIS_RTOS_MemoryMgmt_Automatic for the memory pool data. 299 300\var osMessageQueueAttr_t::mq_size 301\details 302The size (in bytes) of memory block passed with \ref mq_mem. The minimum memory block size is <code>msg_count * msg_size</code> (parameters of the \ref osMessageQueueNew function). The \em msg_size is rounded up to a double even number to ensure 32-bit alignment of the memory blocks. 303 304Default: 0 as the default is no memory provided with \ref mq_mem. 305*/ 306