1 /*
2  * Copyright (c) 2023-2024, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /** ============================================================================
33  *  @file       MessageQueueP.h
34  *
35  *  @brief      MessageQueue module for the RTOS Porting Interface
36  *
37  *  MessageQueueP objects are RTOS message queues backed by OS-specific queue or
38  *  mailbox objects.
39  *
40  *  Message queues can be used for intertask communication. They support sending
41  *  messages between tasks, and between interrupts and tasks.
42  *  Message queues can either be allocated statically with
43  *  #MessageQueueP_construct() or dynamically with #MessageQueueP_create().
44  *
45  *  ============================================================================
46  */
47 
48 #ifndef ti_dpl_MessageQueueP__include
49 #define ti_dpl_MessageQueueP__include
50 
51 #include <stdint.h>
52 #include <stdbool.h>
53 #include <stddef.h>
54 #include <ti/devices/DeviceFamily.h>
55 
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59 
60 /*!
61  *  @brief    Number of bytes greater than or equal to the size of any RTOS Queue/Mailbox data structure.
62  *
63  *  Zephyr: 44
64  */
65 #define MessageQueueP_STRUCT_SIZE (44)
66 
67 /*!
68  *  @brief    Required number of bytes of a statically allocated message queue buffer.
69  *
70  * This macro is defined to support the user in configuring the size of a message queue
71  * buffer. A pointer to this user defined buffer is one of the arguments of the
72  * #MessageQueueP_construct() function.
73  * The macro gives the minimal number of bytes required for the message queue.
74  */
75 
76 #define MessageQueueP_BUFFER_SIZE(msgSize, msgCount) ((msgCount) * (msgSize))
77 
78 /*!
79  *  @brief    MessageQueueP structure.
80  *
81  *  Opaque structure that should be large enough to hold any of the RTOS specific MessageQueueP objects.
82  */
83 typedef union MessageQueueP_Struct
84 {
85     uint32_t dummy; /*!< Align object */
86     uint8_t data[MessageQueueP_STRUCT_SIZE];
87 } MessageQueueP_Struct;
88 
89 /*!
90  *  @brief    Wait forever define
91  */
92 #define MessageQueueP_WAIT_FOREVER ~(0)
93 
94 /*!
95  *  @brief    No wait define
96  */
97 #define MessageQueueP_NO_WAIT (0)
98 
99 /*!
100  *  @brief    Status codes for MessageQueueP APIs
101  */
102 typedef enum
103 {
104     /*! API completed successfully */
105     MessageQueueP_OK      = 0,
106     /*! API failed because of a timeout */
107     MessageQueueP_TIMEOUT = -1
108 } MessageQueueP_Status;
109 
110 /*!
111  *  @brief    Opaque client reference to an instance of a MessageQueueP
112  *
113  * A MessageQueueP_Handle returned from #MessageQueueP_create() or
114  * #MessageQueueP_construct() represents that instance. It is then is used
115  * in the other instance based functions (e.g. #MessageQueueP_pend(),
116  * #MessageQueueP_post(), etc.).
117  */
118 typedef void *MessageQueueP_Handle;
119 
120 /*!
121  * @brief Create a MessageQueueP, allocating memory on the heap.
122  *
123  * #MessageQueueP_create creates a new message queue object. #MessageQueueP_create
124  * returns the handle of the new message queue object or NULL if the message queue
125  * could not be created.
126  *
127  * The message queue object will be allocated on the heap - make sure you have a
128  * sufficiently large heap.
129  *
130  * \note This API cannot be called from interrupt contexts.
131  *
132  * For FreeRTOS, configSUPPORT_DYNAMIC_ALLOCATION has to be set to 1 in FreeRTOSConfig.h.
133  * See 'Configuration with FreeRTOS' in the Core SDK User's Guide for how to do this.
134  *
135  * @param msgSize        The size, in bytes, required to hold each item in the message queue
136  * @param msgCount       The maximum number of items the message queue can hold at any one time
137  *
138  * @retval MessageQueueP handle (NULL on failure)
139  */
140 extern MessageQueueP_Handle MessageQueueP_create(size_t msgSize, size_t msgCount);
141 
142 /*!
143  * @brief Construct a MessageQueueP from statically allocated memory.
144  *
145  * #MessageQueueP_construct creates a new message queue object. #MessageQueueP_construct
146  * returns the handle of the new message queue object or NULL if the message queue
147  * could not be created.
148  *
149  * To use #MessageQueueP_construct \a msgBuf must point to a valid preallocated memory
150  * array that is at least large enough to hold the maximum number of items that can be
151  * in the message queue at any one time.
152  *  - When used with FreeRTOS the array size must be at least ( \a msgCount * \a msgSize) bytes.
153  *  - When used with TI-RTOS the array size must be at least ( \a msgCount * ( \a msgSize + 8)) bytes.
154  *  - Since the buffer must be a aligned properly, it may be necessary to 'round up' the total size
155  *    of the buffer to the next multiple of the alignment for odd sized messages.
156  *
157  * \note This API cannot be called from interrupt contexts.
158  *
159  * For FreeRTOS, configSUPPORT_STATIC_ALLOCATION has to be set to 1 in FreeRTOSConfig.h.
160  * See 'Configuration with FreeRTOS' in the Core SDK User's Guide for how to do this.
161  *
162  * @param queueStruct    Must point to a variable that holds the message queue's data structure
163  * @param msgSize        The size, in bytes, required to hold each item in the message queue
164  * @param msgCount       The maximum number of items the message queue can hold at any one time
165  * @param msgBuf         Pointer to variable that holds the message queue's data buffer
166  *
167  * @retval MessageQueueP handle (NULL on failure)
168  */
169 MessageQueueP_Handle MessageQueueP_construct(MessageQueueP_Struct *queueStruct,
170                                              size_t msgSize,
171                                              size_t msgCount,
172                                              void *msgBuf);
173 
174 /*!
175  * @brief Delete a MessageQueueP.
176  *
177  * #MessageQueueP_delete finalizes and frees this previously allocated message queue
178  * object, setting the referenced handle to NULL.
179  * This function should be used when the message queue was created by the
180  * #MessageQueueP_create() function.
181  *
182  * \note This API cannot be called from interrupt contexts.
183  *
184  * @param handle    A handle to the message queue to be deleted
185  */
186 extern void MessageQueueP_delete(MessageQueueP_Handle handle);
187 
188 /*!
189  * @brief Destruct a MessageQueueP.
190  *
191  * #MessageQueueP_destruct finalizes the message queue object inside the provided structure.
192  * This function should be used when the message queue was constructed by the
193  * #MessageQueueP_construct() function.
194  *
195  * \note This API cannot be called from interrupt contexts.
196  *
197  * @param handle    A handle to the message queue to be destructed
198  */
199 extern void MessageQueueP_destruct(MessageQueueP_Handle handle);
200 
201 /*!
202  * @brief Receive an item from a message queue.
203  *
204  * #MessageQueueP_pend receives an item from the provided message queue.
205  *
206  * @param handle     The handle to the message queue from which the item is to be received
207  * @param message    Pointer to the buffer into which the received item will be copied
208  * @param timeout    The maximum duration in system clock ticks a task should block waiting
209  *                   for an item to be received. When no wait or wait forever options are
210  *                   wanted the #MessageQueueP_NO_WAIT and #MessageQueueP_WAIT_FOREVER defines
211  *                   can be used.
212  *
213  * @retval Status of the function
214  *             - #MessageQueueP_OK: Item recieved
215  *             - #MessageQueueP_TIMEOUT: Timed out. Item was not recieved.
216  */
217 extern MessageQueueP_Status MessageQueueP_pend(MessageQueueP_Handle handle, void *message, uint32_t timeout);
218 
219 /*!
220  * @brief Receive an item from a message queue without removing the item from the queue.
221  *
222  * #MessageQueueP_peek receives an item from the provided message queue without removing the
223  * item from the queue.
224  *
225  * @param handle     The handle to the message queue from which the item is to be received
226  * @param message    Pointer to the buffer into which the received item will be copied
227  * @param timeout    The maximum duraton in system clock ticks a task should block waiting
228  *                   for an item to be received. When no wait or wait forever options are
229  *                   wanted the #MessageQueueP_NO_WAIT and #MessageQueueP_WAIT_FOREVER defines
230  *                   can be used.
231  *
232  * @retval Status of the function
233  *             - #MessageQueueP_OK: Item recieved
234  *             - #MessageQueueP_TIMEOUT: Timed out. Item was not recieved.
235  */
236 extern MessageQueueP_Status MessageQueueP_peek(MessageQueueP_Handle handle, void *message, uint32_t timeout);
237 
238 /*!
239  * @brief Post an item on a message queue.
240  *
241  * #MessageQueueP_post posts an item on the provided message queue.
242  *
243  * @param handle     The handle to the message queue to which the item is to be posted
244  * @param message    Pointer to the buffer from which the item to be posted is copied
245  * @param timeout    The maximum duraton in system clock ticks a task should block waiting
246  *                   for an item to be posted. When no wait or wait forever options are
247  *                   wanted the #MessageQueueP_NO_WAIT and #MessageQueueP_WAIT_FOREVER defines
248  *                   can be used.
249  *
250  * @retval Status of the function
251  *             - #MessageQueueP_OK: Item posted
252  *             - #MessageQueueP_TIMEOUT: Timed out. Item was not posted.
253  */
254 extern MessageQueueP_Status MessageQueueP_post(MessageQueueP_Handle handle, const void *message, uint32_t timeout);
255 
256 /*!
257  * @brief Post an item in the front of a message queue.
258  *
259  * #MessageQueueP_postFront posts an item in the front of the provided message queue.
260  *
261  * @param handle     The handle to the message queue to which the item is to be posted
262  * @param message    Pointer to the buffer from which the item to be posted is copied
263  * @param timeout    The maximum duration in system clock ticks a task should block waiting
264  *                   for an item to be posted. When no wait or wait forever options are
265  *                   wanted the #MessageQueueP_NO_WAIT and #MessageQueueP_WAIT_FOREVER defines
266  *                   can be used.
267  *
268  * @retval Status of the function
269  *             - #MessageQueueP_OK: Item posted
270  *             - #MessageQueueP_TIMEOUT: Timed out. Item was not posted.
271  */
272 extern MessageQueueP_Status MessageQueueP_postFront(MessageQueueP_Handle handle, const void *message, uint32_t timeout);
273 
274 /*!
275  * @brief Get the number of messages stored in a message queue.
276  *
277  * Returns the number of messages in the specified message queue.
278  *
279  * @param handle    A MessageQueueP_Handle returned from #MessageQueueP_create()
280  *                  or #MessageQueueP_construct()
281  *
282  * @retval Number of stored messages in the specified message queue
283  */
284 extern size_t MessageQueueP_getPendingCount(MessageQueueP_Handle handle);
285 
286 /*!
287  * @brief Get the number of free spaces in a message queue.
288  *
289  * Returns the number of free spaces in the specified message queue.
290  *
291  * @param handle    A MessageQueueP_Handle returned from #MessageQueueP_create()
292  *                  or #MessageQueueP_construct()
293  *
294  *  @retval Number of free spaces in the specified message queue
295  */
296 extern size_t MessageQueueP_getFreeCount(MessageQueueP_Handle handle);
297 
298 #ifdef __cplusplus
299 }
300 #endif
301 
302 #endif /* ti_dpl_MessageQueueP__include */