├── .github
└── FUNDING.yml
├── LICENSE.TXT
├── README.md
├── rbuf.c
└── rbuf.h
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [nimaltd]# Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: nimaltd # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12 | polar: # Replace with a single Polar username
13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
15 |
--------------------------------------------------------------------------------
/LICENSE.TXT:
--------------------------------------------------------------------------------
1 | Software License Terms
2 |
3 | This software is dual-licensed:
4 |
5 | 1. GNU General Public License v2 (GPLv2):
6 | - You may redistribute and/or modify this software under the terms of GPLv2 as published by the Free Software Foundation.
7 | - This license does not provide any warranty of any kind, including but not limited to MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8 | - See for details.
9 |
10 | 2. Commercial License:
11 | - The commercial license removes all GPLv2 restrictions and allows you to redistribute your closed-source products with the Library embedded.
12 | - This license includes access to software maintenance, such as updates and upgrades. Customers who purchase this license are eligible to receive updates whenever
13 | they are released. However, the software provider is not obligated to release updates on a specific schedule.
14 | - The commercial license is available in two models:
15 | - Single-Product License: Allows usage in one specific product.
16 | - Company-Wide License: Allows usage across all products of the company.
17 | - No Warranty: The software is provided "AS IS" without any warranties, express or implied, including but not limited to the implied warranties of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, or NON-INFRINGEMENT.
18 | - Liability Disclaimer: In no event shall the copyright holder or contributors be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
19 |
20 | By using this software under the commercial license, you agree to these terms and acknowledge that no additional guarantees or obligations are provided beyond what is explicitly stated in this document.
21 |
22 | ---
23 |
24 | Copyright © Nima Askari, 2025. All rights reserved.
25 | For inquiries, contact: nima.askari@gmail.com All rights reserved
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Multitype Ring Buffer (Circular Buffer) Library for STM32
2 | ---
3 | ## Please Do not Forget to get STAR, DONATE and support me on social networks. Thank you. :sparkling_heart:
4 | ---
5 | - Author: Nima Askari
6 | - Github: https://www.github.com/NimaLTD
7 | - Youtube: https://www.youtube.com/@nimaltd
8 | - LinkedIn: https://www.linkedin.com/in/nimaltd
9 | - Instagram: https://instagram.com/github.NimaLTD
10 | ---
11 | > [!CAUTION]
12 | > This Library using malloc(), Please increase the Heap Size.
13 | ---
14 | * Install Library from https://github.com/nimaltd/STM32-PACK/raw/main/RBUF/NimaLTD.I-CUBE-RBUF.pdsc
15 | * Add and enable it.
16 | * Increase the Heap Size.
17 | * Generate Code.
18 | ---
19 | # Watch the Video:
20 |
21 |
22 |

23 |
24 |
25 | ---
26 | ``` c
27 | #include "rbuf.h"
28 | .
29 | .
30 | .
31 | int main(void)
32 | {
33 | .
34 | .
35 | .
36 | uint8_t wdata = 5, rdata;
37 | RBUF_HandleTypeDef* rbuf = RBUF_Init(sizeof(uint8_t), 16);
38 | RBUF_Push(&rbuf, &wdata);
39 | RBUF_Pop(&rbuf, &rdata);
40 | }
41 | ```
42 |
--------------------------------------------------------------------------------
/rbuf.c:
--------------------------------------------------------------------------------
1 |
2 | /************************************************************************************************************
3 | ************** Include Headers
4 | ************************************************************************************************************/
5 |
6 | #include "rbuf.h"
7 |
8 | /************************************************************************************************************
9 | ************** Private Definitions
10 | ************************************************************************************************************/
11 |
12 | // none
13 |
14 | /************************************************************************************************************
15 | ************** Private Variables
16 | ************************************************************************************************************/
17 |
18 | // none
19 |
20 | /************************************************************************************************************
21 | ************** Private Functions
22 | ************************************************************************************************************/
23 |
24 | // none
25 |
26 | /************************************************************************************************************
27 | ************** Public Functions
28 | ************************************************************************************************************/
29 |
30 | /**
31 | * @brief Initializes a ring buffer.
32 | * @note This function initializes a ring buffer with the specified item size
33 | * and capacity. Memory is allocated for the buffer based on the item size
34 | * and capacity provided. The buffer is initially empty.
35 | * @param ItemSize: Size of each item in the buffer.
36 | * @param Capacity: Maximum number of items the buffer can hold.
37 | * @retval Pointer to the initialized RBUF_HandleTypeDef structure if successful,
38 | * NULL if memory allocation fails.
39 | */
40 | RBUF_HandleTypeDef* RBUF_Init(size_t ItemSize, uint32_t Capacity)
41 | {
42 | RBUF_HandleTypeDef *rbuf = (RBUF_HandleTypeDef*) malloc(sizeof(RBUF_HandleTypeDef));
43 | if (rbuf == NULL)
44 | {
45 | return NULL;
46 | }
47 | rbuf->ItemSize = ItemSize;
48 | rbuf->Capacity = Capacity;
49 | rbuf->Buffer = malloc(ItemSize * Capacity);
50 | if (rbuf->Buffer == NULL)
51 | {
52 | free(rbuf);
53 | return NULL;
54 | }
55 | rbuf->Head = 0;
56 | rbuf->Tail = 0;
57 | rbuf->Count = 0;
58 | return rbuf;
59 | }
60 |
61 | /***********************************************************************************************************/
62 |
63 | /**
64 | * @brief Destroys a ring buffer and frees memory.
65 | * @note This function deallocates the memory allocated for the ring buffer
66 | * pointed to by the given handle.
67 | * @param rbuf: Pointer to the ring buffer handle.
68 | * @retval None
69 | */
70 | void RBUF_DeInit(RBUF_HandleTypeDef *rbuf)
71 | {
72 | if (rbuf != NULL)
73 | {
74 | if (rbuf->Buffer != NULL)
75 | {
76 | free(rbuf->Buffer);
77 | }
78 | free(rbuf);
79 | }
80 | }
81 |
82 | /***********************************************************************************************************/
83 |
84 | /**
85 | * @brief Checks if the ring buffer is full.
86 | * @note This function checks whether the ring buffer is full or not.
87 | * It returns true if the number of elements in the buffer is equal
88 | * to its capacity, indicating that the buffer is full; otherwise,
89 | * it returns false.
90 | * @param rbuf: Pointer to the ring buffer handle.
91 | * @retval true if the buffer is full, false otherwise.
92 | */
93 | bool RBUF_IsFull(RBUF_HandleTypeDef *rbuf)
94 | {
95 | return rbuf->Count == rbuf->Capacity;
96 | }
97 |
98 | /***********************************************************************************************************/
99 |
100 | /**
101 | * @brief Checks if the ring buffer is empty.
102 | * @note This function checks whether the ring buffer is empty or not.
103 | * It returns true if the number of elements in the buffer is zero,
104 | * indicating that the buffer is empty; otherwise, it returns false.
105 | * @param rbuf: Pointer to the ring buffer handle.
106 | * @retval true if the buffer is empty, false otherwise.
107 | */
108 | bool RBUF_IsEmpty(RBUF_HandleTypeDef *rbuf)
109 | {
110 | return rbuf->Count == 0;
111 | }
112 |
113 | /***********************************************************************************************************/
114 |
115 | /**
116 | * @brief Get the number of free slots available in the ring buffer.
117 | * @note This function returns the number of free slots available in the
118 | * ring buffer. It calculates the difference between the capacity
119 | * of the buffer and the current count of elements.
120 | * @param rbuf: Pointer to the ring buffer handle.
121 | * @retval Number of free slots in the ring buffer.
122 | */
123 | uint32_t RBUF_Available(RBUF_HandleTypeDef *rbuf)
124 | {
125 | return rbuf->Capacity - rbuf->Count;
126 | }
127 |
128 | /***********************************************************************************************************/
129 |
130 | /**
131 | * @brief Get the number of used slots in the ring buffer.
132 | * @note This function returns the number of used slots in the
133 | * ring buffer.
134 | * @param rbuf: Pointer to the ring buffer handle.
135 | * @retval Number of used slots in the ring buffer.
136 | */
137 | uint32_t RBUF_Used(RBUF_HandleTypeDef *rbuf)
138 | {
139 | return rbuf->Count;
140 | }
141 |
142 | /***********************************************************************************************************/
143 |
144 | /**
145 | * @brief Make empty the buffer..
146 | * @note Erase all data and pointers.
147 | * @param rbuf: Pointer to the ring buffer handle.
148 | * @retval None.
149 | */
150 | void RBUF_Format(RBUF_HandleTypeDef *rbuf)
151 | {
152 | rbuf->Head = 0;
153 | rbuf->Tail = 0;
154 | rbuf->Count = 0;
155 | memset(rbuf->Buffer, 0, rbuf->Capacity * rbuf->ItemSize);
156 | }
157 |
158 | /***********************************************************************************************************/
159 |
160 | /**
161 | * @brief Pushes data into the ring buffer.
162 | * @note This function pushes data into the ring buffer if there is available
163 | * space. If the buffer is full, the operation fails and returns false.
164 | * @param rbuf: Pointer to the ring buffer handle.
165 | * @param data: Pointer to the data to be pushed into the buffer.
166 | * @retval true if the data was successfully pushed, false otherwise (buffer full).
167 | */
168 | bool RBUF_Push(RBUF_HandleTypeDef *rbuf, const void *data)
169 | {
170 | if (RBUF_IsFull(rbuf))
171 | {
172 | return false;
173 | }
174 | uint8_t *dest = (uint8_t*) rbuf->Buffer + rbuf->Head * rbuf->ItemSize;
175 | memcpy(dest, data, rbuf->ItemSize);
176 | rbuf->Head = (rbuf->Head + 1) % rbuf->Capacity;
177 | rbuf->Count++;
178 | return true;
179 | }
180 |
181 | /***********************************************************************************************************/
182 |
183 | /**
184 | * @brief Push n*data into the ring buffer.
185 | * @note This function pushes data into the ring buffer if there is available
186 | * space. If the buffer is full, the operation fails and returns false.
187 | * @param rbuf: Pointer to the ring buffer handle.
188 | * @param data: Pointer to the data to be pushed into the buffer.
189 | * @param num: number of data to be pushed into the buffer.
190 | * @retval true if the data was successfully pushed, false otherwise (buffer full).
191 | */
192 | bool RBUF_PushN(RBUF_HandleTypeDef *rbuf, const void *data, uint32_t num)
193 | {
194 | const uint8_t *src = (const uint8_t*) data;
195 | if (num > RBUF_Available(rbuf))
196 | {
197 | return false;
198 | }
199 | for (uint32_t i = 0; i < num; ++i)
200 | {
201 | uint8_t *dest = (uint8_t*) rbuf->Buffer + rbuf->Head * rbuf->ItemSize;
202 | memcpy(dest, src, rbuf->ItemSize);
203 | rbuf->Head = (rbuf->Head + 1) % rbuf->Capacity;
204 | rbuf->Count++;
205 | src += rbuf->ItemSize;
206 | }
207 | return true;
208 | }
209 |
210 | /***********************************************************************************************************/
211 |
212 | /**
213 | * @brief Pops data from the ring buffer.
214 | * @note This function pops data from the ring buffer if there is available
215 | * data. If the buffer is empty, the operation fails and returns false.
216 | * @param rbuf: Pointer to the ring buffer handle.
217 | * @param data: Pointer to the memory where the popped data will be stored.
218 | * @retval true if data was successfully popped, false otherwise (buffer empty).
219 | */
220 | bool RBUF_Pop(RBUF_HandleTypeDef *rbuf, void *data)
221 | {
222 | if (RBUF_IsEmpty(rbuf))
223 | {
224 | return false;
225 | }
226 | uint8_t *src = (uint8_t*) rbuf->Buffer + rbuf->Tail * rbuf->ItemSize;
227 | memcpy(data, src, rbuf->ItemSize);
228 | rbuf->Tail = (rbuf->Tail + 1) % rbuf->Capacity;
229 | rbuf->Count--;
230 | return true;
231 | }
232 |
233 | /***********************************************************************************************************/
234 |
235 | /**
236 | * @brief Pops n*data from the ring buffer.
237 | * @note This function pops data from the ring buffer if there is available
238 | * data. If the buffer is empty, the operation fails and returns false.
239 | * @param rbuf: Pointer to the ring buffer handle.
240 | * @param data: Pointer to the memory where the popped data will be stored.
241 | * @param num: number of data to read.
242 | * @retval true if data was successfully popped, false otherwise (buffer empty).
243 | */
244 | bool RBUF_PopN(RBUF_HandleTypeDef *rbuf, void *data, uint32_t num)
245 | {
246 | uint8_t *dest = (uint8_t*) data;
247 | if (num > RBUF_Used(rbuf))
248 | {
249 | return false;
250 | }
251 | for (uint32_t i = 0; i < num; ++i)
252 | {
253 | uint8_t *src = (uint8_t*) rbuf->Buffer + rbuf->Tail * rbuf->ItemSize;
254 | memcpy(dest, src, rbuf->ItemSize);
255 | rbuf->Tail = (rbuf->Tail + 1) % rbuf->Capacity;
256 | rbuf->Count--;
257 | dest += rbuf->ItemSize;
258 | }
259 | return true;
260 | }
261 |
--------------------------------------------------------------------------------
/rbuf.h:
--------------------------------------------------------------------------------
1 | #ifndef _RBUF_H_
2 | #define _RBUF_H_
3 |
4 | /***********************************************************************************************************
5 |
6 | Author: Nima Askari
7 | Github: https://www.github.com/NimaLTD
8 | LinkedIn: https://www.linkedin.com/in/nimaltd
9 | Youtube: https://www.youtube.com/@nimaltd
10 | Instagram: https://instagram.com/github.NimaLTD
11 |
12 | Version: 2.2.0
13 |
14 | History:
15 | 2.2.0
16 | - Added RBUF_PushN(),RBUF_PopN() functions
17 |
18 | 2.1.0
19 | - Added RBUF_Used(),RBUF_Format() functions
20 |
21 | 2.0.0
22 | - Rewrite again
23 | - Support STM32CubeMx Packet installer
24 |
25 | ***********************************************************************************************************/
26 |
27 | #ifdef __cplusplus
28 | extern "C"
29 | {
30 | #endif
31 |
32 | /************************************************************************************************************
33 | ************** Include Headers
34 | ************************************************************************************************************/
35 |
36 | #include
37 | #include
38 | #include
39 | #include
40 |
41 | /************************************************************************************************************
42 | ************** Public Definitions
43 | ************************************************************************************************************/
44 |
45 | // none
46 |
47 | /************************************************************************************************************
48 | ************** Public struct/enum
49 | ************************************************************************************************************/
50 |
51 | typedef struct
52 | {
53 | size_t ItemSize;
54 | uint32_t Capacity;
55 | uint32_t Head;
56 | uint32_t Tail;
57 | uint32_t Count;
58 | void *Buffer;
59 |
60 | } RBUF_HandleTypeDef;
61 |
62 | /************************************************************************************************************
63 | ************** Public Functions
64 | ************************************************************************************************************/
65 |
66 | RBUF_HandleTypeDef* RBUF_Init(size_t ItemSize, uint32_t Capacity);
67 | void RBUF_DeInit(RBUF_HandleTypeDef *rbuf);
68 | bool RBUF_IsFull(RBUF_HandleTypeDef *rbuf);
69 | bool RBUF_IsEmpty(RBUF_HandleTypeDef *rbuf);
70 | uint32_t RBUF_Available(RBUF_HandleTypeDef *rbuf);
71 | uint32_t RBUF_Used(RBUF_HandleTypeDef *rbuf);
72 | void RBUF_Format(RBUF_HandleTypeDef *rbuf);
73 | bool RBUF_Push(RBUF_HandleTypeDef *rbuf, const void *data);
74 | bool RBUF_PushN(RBUF_HandleTypeDef *rbuf, const void *data, uint32_t num);
75 | bool RBUF_Pop(RBUF_HandleTypeDef *rbuf, void *data);
76 | bool RBUF_PopN(RBUF_HandleTypeDef *rbuf, void *data, uint32_t num);
77 |
78 | #ifdef __cplusplus
79 | }
80 | #endif
81 | #endif
82 |
--------------------------------------------------------------------------------