1 /** 2 * Copyright (c) 2015, Realtek Semiconductor Corporation. All rights reserved. 3 */ 4 5 #ifndef _OS_MSG_H_ 6 #define _OS_MSG_H_ 7 8 #include <stdint.h> 9 #include <stdbool.h> 10 11 #ifdef __cplusplus 12 extern "C" { 13 #endif 14 15 /** 16 * \addtogroup OS OSIF 17 * \defgroup Message Message Queue 18 * 19 * \brief Exchange messages between tasks in a FIFO-like operation. 20 * \details The Message Queue function group allows to control, send, receive, or wait for message. 21 * Message transmission is a basic communication model between tasks that one task sends 22 * data explicitly, while another task receives it. The operation is more like some 23 * kind of I/O rather than a direct access to information to be shared. The data to be 24 * passed can be any type.\n 25 * 26 * \image html OS-message-queue-overview.jpg "Message Queue Overview" width=617px height=321px 27 * 28 * \ingroup OS 29 */ 30 31 32 bool os_msg_queue_create_intern(void **pp_handle, uint32_t msg_num, uint32_t msg_size, 33 const char *p_func, uint32_t file_line); 34 35 bool os_msg_queue_delete_intern(void *p_handle, const char *p_func, uint32_t file_line); 36 37 bool os_msg_queue_peek_intern(void *p_handle, uint32_t *p_msg_num, 38 const char *p_func, uint32_t file_line); 39 40 bool os_msg_send_intern(void *p_handle, void *p_msg, uint32_t wait_ms, 41 const char *p_func, uint32_t file_line); 42 43 bool os_msg_recv_intern(void *p_handle, void *p_msg, uint32_t wait_ms, 44 const char *p_func, uint32_t file_line); 45 46 bool os_msg_peek_intern(void *p_handle, void *p_msg, uint32_t wait_ms, 47 const char *p_func, uint32_t file_line); 48 49 /** 50 * os_msg.h 51 * 52 * \brief Creates a message queue instance. This allocates the storage required by the 53 * new queue and passes back a handle for the queue. 54 * 55 * \param[out] pp_handle Used to pass back a handle by which the message queue 56 * can be referenced. 57 * 58 * \param[in] msg_num The maximum number of items that the queue can contain. 59 * 60 * \param[in] msg_size The number of bytes each item in the queue will require. Items 61 * are queued by copy, not by reference, so this is the number of 62 * bytes that will be copied for each posted item. Each item on the 63 * queue must be the same size. 64 * 65 * \return The status of the message queue creation. 66 * \retval true Message queue was created successfully. 67 * \retval false Message queue was failed to create. 68 * 69 * <b>Example usage</b> 70 * \code{.c} 71 * struct test_msg 72 * { 73 * uint8_t id; 74 * uint8_t data[16]; 75 * } 76 * 77 * #define MSG_NUM 10 78 * 79 * int test(void) 80 * { 81 * void *p_handle = NULL; 82 * 83 * // Create a queue capable of containing 10 items of structure test_msg. 84 * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) 85 * { 86 * // Message queue created successfully. 87 * } 88 * else 89 * { 90 * // Message queue failed to create. 91 * return -1; 92 * } 93 * 94 * // Delete the message queue. 95 * os_msg_queue_delete(p_handle); 96 * 97 * return 0; 98 * } 99 * \endcode 100 * 101 * \ingroup Message 102 */ 103 #define os_msg_queue_create(pp_handle, msg_num, msg_size) \ 104 os_msg_queue_create_intern(pp_handle, msg_num, msg_size, __func__, __LINE__) 105 106 /** 107 * os_msg.h 108 * 109 * \brief Delete the specified message queue, and free all the memory allocated for 110 * storing of items placed on the queue. 111 * 112 * \param[in] p_handle The handle to the message queue being deleted. 113 * 114 * \return The status of the message queue deletion. 115 * \retval true Message queue was deleted successfully. 116 * \retval false Message queue was failed to delete. 117 * 118 * <b>Example usage</b> 119 * \code{.c} 120 * struct test_msg 121 * { 122 * uint8_t id; 123 * uint8_t data[16]; 124 * } 125 * 126 * #define MSG_NUM 10 127 * 128 * int test(void) 129 * { 130 * void *p_handle = NULL; 131 * 132 * // Create a queue capable of containing 10 items of structure test_msg. 133 * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) 134 * { 135 * // Message queue created successfully. 136 * } 137 * else 138 * { 139 * // Message queue failed to create. 140 * return -1; 141 * } 142 * 143 * // Delete the message queue. 144 * os_msg_queue_delete(p_handle); 145 * 146 * return 0; 147 * } 148 * \endcode 149 * 150 * \ingroup Message 151 */ 152 #define os_msg_queue_delete(p_handle) \ 153 os_msg_queue_delete_intern(p_handle, __func__, __LINE__) 154 155 /** 156 * os_msg.h 157 * 158 * \brief Peek the number of items sent and resided on the message queue. 159 * 160 * \param[in] p_handle The handle to the message queue being peeked. 161 * 162 * \param[out] p_msg_num Used to pass back the number of items residing on the message queue. 163 * 164 * \return The status of the message queue peek. 165 * \retval true Message queue was peeked successfully. 166 * \retval false Message queue was failed to peek. 167 * 168 * <b>Example usage</b> 169 * \code{.c} 170 * struct test_msg 171 * { 172 * uint8_t id; 173 * uint8_t data[16]; 174 * } 175 * 176 * #define MSG_NUM 10 177 * 178 * int test(void) 179 * { 180 * void *p_handle = NULL; 181 * uint32_t msg_num; 182 * 183 * // Create a queue capable of containing 10 items of structure test_msg. 184 * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) 185 * { 186 * // Message queue created successfully. 187 * } 188 * else 189 * { 190 * // Message queue failed to create. 191 * return -1; 192 * } 193 * 194 * // Peek the number of items sent on this message queue. 195 * os_msg_queue_peek(p_handle, &msg_num); 196 * 197 * return 0; 198 * } 199 * \endcode 200 * 201 * \ingroup Message 202 */ 203 #define os_msg_queue_peek(p_handle, p_msg_num) \ 204 os_msg_queue_peek_intern(p_handle, p_msg_num, __func__, __LINE__) 205 206 /** 207 * os_msg.h 208 * 209 * \brief Send an item to the back of the specified message queue. The item is 210 * queued by copy, not by reference. 211 * 212 * \param[in] p_handle The handle to the message queue on which the item is to be sent. 213 * 214 * \param[in] p_msg Pointer to the item that is to be sent on the queue. The referenced 215 * item rather than pointer itself will be copied on the queue. 216 * 217 * \param[in] wait_ms The maximum amount of time in milliseconds that the task should 218 * block waiting for the item to sent on the queue. 219 * \arg \c 0 No blocking and return immediately. 220 * \arg \c 0xFFFFFFFF Block infinitely until the item sent. 221 * \arg \c others The timeout value in milliseconds. 222 * 223 * \return The status of the message item sent. 224 * \retval true Message item was sent successfully. 225 * \retval false Message item was failed to send. 226 * 227 * <b>Example usage</b> 228 * \code{.c} 229 * struct test_msg 230 * { 231 * uint8_t id; 232 * uint8_t data[16]; 233 * } 234 * 235 * #define MSG_NUM 10 236 * 237 * int test(void) 238 * { 239 * void *p_handle = NULL; 240 * struct test_msg msg; 241 * 242 * // Create a queue capable of containing 10 items of structure test_msg. 243 * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) 244 * { 245 * // Message queue created successfully. 246 * } 247 * else 248 * { 249 * // Message queue failed to create. 250 * return -1; 251 * } 252 * 253 * // Send the item to this message queue. 254 * msg.id = 1; 255 * msg.data[0] = 0; 256 * os_msg_send(p_handle, &msg, 0); 257 * 258 * return 0; 259 * } 260 * \endcode 261 * 262 * \ingroup Message 263 */ 264 #define os_msg_send(p_handle, p_msg, wait_ms) \ 265 os_msg_send_intern(p_handle, p_msg, wait_ms, __func__, __LINE__) 266 267 /** 268 * os_msg.h 269 * 270 * \brief Receive an item from the specified message queue. The item is received by 271 * copy rather than by reference, so a buffer of adequate size must be provided. 272 * 273 * \param[in] p_handle The handle to the message queue from which the item is to be received. 274 * 275 * \param[out] p_msg Pointer to the buffer into which the received item will be copied. 276 * item rather than pointer itself will be copied on the queue. 277 * 278 * \param[in] wait_ms The maximum amount of time in milliseconds that the task should 279 * block waiting for an item to be received from the queue. 280 * \arg \c 0 No blocking and return immediately. 281 * \arg \c 0xFFFFFFFF Block infinitely until the item received. 282 * \arg \c others The timeout value in milliseconds. 283 * 284 * \return The status of the message item received. 285 * \retval true Message item was received successfully. 286 * \retval false Message item was failed to receive. 287 * 288 * <b>Example usage</b> 289 * \code{.c} 290 * struct test_msg 291 * { 292 * uint8_t id; 293 * uint8_t data[16]; 294 * } 295 * 296 * #define MSG_NUM 10 297 * 298 * void *p_handle = NULL; 299 * 300 * void send_msg(void) 301 * { 302 * struct test_msg msg; 303 * 304 * // Create a queue capable of containing 10 items of structure test_msg. 305 * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) 306 * { 307 * // Message queue created successfully. 308 * } 309 * else 310 * { 311 * // Message queue failed to create. 312 * return -1; 313 * } 314 * 315 * // Send the item to this message queue. 316 * msg.id = 1; 317 * msg.data[0] = 0; 318 * os_msg_send(p_handle, &msg, 0); 319 * 320 * return 0; 321 * } 322 * 323 * void receive_msg(void) 324 * { 325 * struct test_msg msg; 326 * 327 * // Receive the message queue item. 328 * if (os_msg_recv(p_handle, &msg, 0) == true) 329 * { 330 * // Message item received successfully. 331 * } 332 * else 333 * { 334 * // Message item failed to receive. 335 * return -1; 336 * } 337 * 338 * return 0; 339 * } 340 * \endcode 341 * 342 * \ingroup Message 343 */ 344 #define os_msg_recv(p_handle, p_msg, wait_ms) \ 345 os_msg_recv_intern(p_handle, p_msg, wait_ms, __func__, __LINE__) 346 347 /** 348 * os_msg.h 349 * 350 * \brief Receive but not remove an item from the specified message queue. The item is 351 * received by copy rather than by reference, so a buffer of adequate size must 352 * be provided. 353 * 354 * \param[in] p_handle The handle to the message queue on which the item is to be peeked. 355 * 356 * \param[out] p_msg Pointer to the buffer into which the received item will be copied. 357 * item rather than pointer itself will be copied on the queue. 358 * 359 * \param[in] wait_ms The maximum amount of time in milliseconds that the task should 360 * block waiting for an item to be received from the queue. 361 * \arg \c 0 No blocking and return immediately. 362 * \arg \c 0xFFFFFFFF Block infinitely until the item received. 363 * \arg \c others The timeout value in milliseconds. 364 * 365 * \return The status of the message item received. 366 * \retval true Message item was received successfully. 367 * \retval false Message item was failed to receive. 368 * 369 * <b>Example usage</b> 370 * \code{.c} 371 * struct test_msg 372 * { 373 * uint8_t id; 374 * uint8_t data[16]; 375 * } 376 * 377 * #define MSG_NUM 10 378 * 379 * void *p_handle = NULL; 380 * 381 * void send_msg(void) 382 * { 383 * struct test_msg msg; 384 * 385 * // Create a queue capable of containing 10 items of structure test_msg. 386 * if (os_msg_queue_create(&p_handle, MSG_NUM, sizeof(struct test_msg)) == true) 387 * { 388 * // Message queue created successfully. 389 * } 390 * else 391 * { 392 * // Message queue failed to create. 393 * return -1; 394 * } 395 * 396 * // Send the item to this message queue. 397 * msg.id = 1; 398 * msg.data[0] = 0; 399 * os_msg_send(p_handle, &msg, 0); 400 * 401 * return 0; 402 * } 403 * 404 * void peek_msg(void) 405 * { 406 * struct test_msg msg; 407 * 408 * // Peek the message queue item. 409 * if (os_msg_peek(p_handle, &msg, 0) == true) 410 * { 411 * // Message item peeked successfully. 412 * } 413 * else 414 * { 415 * // Message item failed to peek. 416 * return -1; 417 * } 418 * 419 * return 0; 420 * } 421 * \endcode 422 * 423 * \ingroup Message 424 */ 425 #define os_msg_peek(p_handle, p_msg, wait_ms) \ 426 os_msg_peek_intern(p_handle, p_msg, wait_ms, __func__, __LINE__) 427 428 #ifdef __cplusplus 429 } 430 #endif 431 432 #endif /* _OS_MSG_H_ */ 433