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