1 //***************************************************************************** 2 // 3 //! @file am_hal_queue.h 4 //! 5 //! @brief Functions for implementing a queue system. 6 //! 7 //! @addtogroup Miscellaneous3 Queue - Software Features (MISC) 8 //! @ingroup apollo3p_hal 9 //! @{ 10 // 11 //***************************************************************************** 12 13 //***************************************************************************** 14 // 15 // Copyright (c) 2024, Ambiq Micro, Inc. 16 // All rights reserved. 17 // 18 // Redistribution and use in source and binary forms, with or without 19 // modification, are permitted provided that the following conditions are met: 20 // 21 // 1. Redistributions of source code must retain the above copyright notice, 22 // this list of conditions and the following disclaimer. 23 // 24 // 2. Redistributions in binary form must reproduce the above copyright 25 // notice, this list of conditions and the following disclaimer in the 26 // documentation and/or other materials provided with the distribution. 27 // 28 // 3. Neither the name of the copyright holder nor the names of its 29 // contributors may be used to endorse or promote products derived from this 30 // software without specific prior written permission. 31 // 32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 33 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 36 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 37 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 38 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 39 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 40 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 41 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 // POSSIBILITY OF SUCH DAMAGE. 43 // 44 // This is part of revision release_sdk_3_2_0-dd5f40c14b of the AmbiqSuite Development Package. 45 // 46 //***************************************************************************** 47 #ifndef AM_HAL_QUEUE_H 48 #define AM_HAL_QUEUE_H 49 50 //***************************************************************************** 51 // 52 //! @brief A data structure that will operate as a queue. 53 //! 54 //! This data structure holds information necessary for operating a thread-safe 55 //! queue. When declaring a structure of type am_hal_queue_t, you will also need 56 //! to provide some working memory for the queue to use. For more information on 57 //! setting up and using the am_hal_queue_t structure, please see the 58 //! documentation for am_hal_queue_init(). 59 // 60 //***************************************************************************** 61 typedef struct 62 { 63 volatile uint32_t ui32WriteIndex; 64 volatile uint32_t ui32ReadIndex; 65 volatile uint32_t ui32Length; 66 uint32_t ui32Capacity; 67 uint32_t ui32ItemSize; 68 uint8_t *pui8Data; 69 } 70 am_hal_queue_t; 71 72 //***************************************************************************** 73 // 74 // Function-like macros. 75 // 76 //***************************************************************************** 77 78 // 79 //! Returns true if the queue is empty. 80 // 81 #define am_hal_queue_empty(psQueue) \ 82 ((psQueue)->ui32Length == 0) 83 84 // 85 //! Returns true if the queue is full. 86 // 87 #define am_hal_queue_full(psQueue) \ 88 ((psQueue)->ui32Length == (psQueue)->ui32Capacity) 89 90 // 91 //! Returns the amount of space left in the queue (in bytes). 92 // 93 #define am_hal_queue_space_left(psQueue) \ 94 ((psQueue)->ui32Capacity - (psQueue)->ui32Length) 95 96 // 97 //! Returns the number of configured items that will fit in the queue. 98 // 99 #define am_hal_queue_slots_left(psQueue) \ 100 (((psQueue)->ui32Capacity - (psQueue)->ui32Length) \ 101 / (psQueue)->ui32ItemSize) 102 103 // 104 //! Returns the amount of data in the queue (in bytes). 105 // 106 #define am_hal_queue_data_left(psQueue) \ 107 ((psQueue)->ui32Length) 108 109 // 110 //! Returns the number of configured items left in the queue. 111 // 112 #define am_hal_queue_items_left(psQueue) \ 113 ((psQueue)->ui32Length / (psQueue)->ui32ItemSize) 114 115 // 116 //! Can be used as a pointer to the next item to be read from the queue. 117 // 118 #define am_hal_queue_peek(psQueue) \ 119 ((void *) &((psQueue)->pui8Data[(psQueue)->ui32ReadIndex])) 120 121 // 122 //! Can be used as a pointer to the next available slot in the queue memory. 123 // 124 #define am_hal_queue_next_slot(psQueue) \ 125 ((void *) &((psQueue)->pui8Data[(psQueue)->ui32WriteIndex])) 126 127 //***************************************************************************** 128 // 129 //! Use this to make sure you get the size parameters right. 130 // 131 //***************************************************************************** 132 #define am_hal_queue_from_array(queue, array) \ 133 am_hal_queue_init((queue), (array), sizeof((array)[0]), sizeof(array)) 134 135 #ifdef __cplusplus 136 extern "C" 137 { 138 #endif 139 140 //***************************************************************************** 141 // 142 // External function definitions. 143 // 144 //***************************************************************************** 145 //***************************************************************************** 146 // 147 //! @brief Initializes a queue. 148 //! 149 //! @param psQueue - Pointer to a queue structure. 150 //! @param pvData - Pointer to a memory location to be used for data storage. 151 //! @param ui32ItemSize - Number of bytes per item in the queue. 152 //! @param ui32ArraySize - Number of bytes in the data array. 153 //! 154 //! This function initializes the members of a queue structure and attaches it 155 //! to an array of memory that it can use for storage.\n 156 //! This function should be called before the queue is used. 157 //! 158 //! In this example, we are creating a queue that can hold 1024 32-bit 159 //! integers.\n 160 //! The integers themselves will be stored in the array named pui32WorkingSpace, 161 //! while information about the queue itself will be stored in sDataQueue. 162 //! 163 //! @note The caller should not modify any of the members of am_hal_queue_t 164 //! structures. The queue API will handle these members in a thread-safe way. 165 //! @par 166 //! @note The queue will remember what size data is in it. Other queue API 167 //! functions will perform transfers in units of "items" where one "item" is 168 //! the number of bytes you specify in the \e ui32ItemSize argument upon 169 //! initialization. 170 //! 171 //! Example usage: 172 //! 173 //! @code 174 //! 175 //! // 176 //! // Declare a queue structure and an array of bytes we can use to store 177 //! // data. 178 //! // 179 //! am_hal_queue_t sDataQueue; 180 //! uint32_t pui32WorkingSpace[1024]; 181 //! 182 //! // 183 //! // Attach the queue structure to the working memory. 184 //! // 185 //! am_hal_queue_init(&sDataQueue, pui8WorkingSpace, sizeof(uint32_t) 186 //! sizeof(pui32WorkingSpace)); 187 //! 188 //! @endcode 189 //! 190 //! The am_hal_queue_from_array macro is a convenient shorthand for this 191 //! operation. The code below does the same thing as the code above. 192 //! 193 //! @code 194 //! 195 //! 196 //! // Declare a queue structure and an array of bytes we can use to store 197 //! // data. 198 //! // 199 //! am_hal_queue_t sDataQueue; 200 //! uint32_t pui32WorkingSpace[1024]; 201 //! 202 //! // 203 //! // Attach the queue structure to the working memory. 204 //! // 205 //! am_hal_queue_from_array(&sDataQueue, pui8WorkingSpace); 206 //! 207 //! @endcode 208 // 209 //***************************************************************************** 210 extern void am_hal_queue_init(am_hal_queue_t *psQueue, void *pvData, uint32_t ui32ItemSize, uint32_t ui32ArraySize); 211 212 //***************************************************************************** 213 // 214 //! @brief Adds an item to the Queue 215 //! 216 //! @param psQueue - Pointer to a queue structure. 217 //! @param pvSource - Pointer to the data to be added. 218 //! @param ui32NumItems - Number of items to be added. 219 //! 220 //! This function will copy the data pointed to by pvSource into the queue. The 221 //! \e ui32NumItems term specifies the number of items to be copied from \e 222 //! pvSource. The size of an "item" depends on how the queue was initialized. 223 //! Please see am_hal_queue_init() for more information on this. 224 //! 225 //! @return true if the add operation was successful, or false if the queue 226 //! didn't have enough space. 227 // 228 //***************************************************************************** 229 extern bool am_hal_queue_item_add(am_hal_queue_t *psQueue, const void *pvSource, uint32_t ui32NumItems); 230 231 //***************************************************************************** 232 // 233 //! @brief Removes an item from the Queue 234 //! 235 //! @param psQueue - Pointer to a queue structure. 236 //! @param pvDest - Pointer to the data to be added. 237 //! @param ui32NumItems - Number of items to be added. 238 //! 239 //! This function will copy the data from the queue into the memory pointed to 240 //! by pvDest. The \e ui32NumItems term specifies the number of items to be 241 //! copied from the queue. The size of an "item" depends on how the queue was 242 //! initialized. Please see am_hal_queue_init() for more information on this. 243 //! 244 //! @return true if we were able to pull the requested number of items from the 245 //! queue, or false if the queue didn't have that many items to pull. 246 // 247 //***************************************************************************** 248 extern bool am_hal_queue_item_get(am_hal_queue_t *psQueue, void *pvDest, uint32_t ui32NumItems); 249 250 #ifdef __cplusplus 251 } 252 #endif 253 254 #endif // AM_HAL_QUEUE_H 255 256 //***************************************************************************** 257 // 258 // End Doxygen group. 259 //! @} 260 // 261 //***************************************************************************** 262