aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios/os/oslib
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios/os/oslib')
-rw-r--r--lib/chibios/os/oslib/dox/lib.dox100
-rw-r--r--lib/chibios/os/oslib/include/chbsem.h311
-rw-r--r--lib/chibios/os/oslib/include/chdelegates.h208
-rw-r--r--lib/chibios/os/oslib/include/chfactory.h523
-rw-r--r--lib/chibios/os/oslib/include/chjobs.h397
-rw-r--r--lib/chibios/os/oslib/include/chlib.h264
-rw-r--r--lib/chibios/os/oslib/include/chmboxes.h209
-rw-r--r--lib/chibios/os/oslib/include/chmemcore.h211
-rw-r--r--lib/chibios/os/oslib/include/chmemheaps.h178
-rw-r--r--lib/chibios/os/oslib/include/chmempools.h385
-rw-r--r--lib/chibios/os/oslib/include/chobjcaches.h304
-rw-r--r--lib/chibios/os/oslib/include/chobjfifos.h430
-rw-r--r--lib/chibios/os/oslib/include/chpipes.h208
-rw-r--r--lib/chibios/os/oslib/oslib.mk57
-rw-r--r--lib/chibios/os/oslib/readme.txt2
-rw-r--r--lib/chibios/os/oslib/src/chdelegates.c239
-rw-r--r--lib/chibios/os/oslib/src/chfactory.c829
-rw-r--r--lib/chibios/os/oslib/src/chmboxes.c522
-rw-r--r--lib/chibios/os/oslib/src/chmemcore.c227
-rw-r--r--lib/chibios/os/oslib/src/chmemheaps.c399
-rw-r--r--lib/chibios/os/oslib/src/chmempools.c336
-rw-r--r--lib/chibios/os/oslib/src/chobjcaches.c491
-rw-r--r--lib/chibios/os/oslib/src/chpipes.c388
23 files changed, 7218 insertions, 0 deletions
diff --git a/lib/chibios/os/oslib/dox/lib.dox b/lib/chibios/os/oslib/dox/lib.dox
new file mode 100644
index 000000000..7386c1365
--- /dev/null
+++ b/lib/chibios/os/oslib/dox/lib.dox
@@ -0,0 +1,100 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19/**
20 * @defgroup oslib OS Library
21 * @details The OS Library is a set of RTOS extensions compatible with both
22 * the RT and NIL RTOSes.
23 */
24
25/**
26 * @defgroup oslib_info Version Numbers and Identification
27 * @ingroup oslib
28 */
29
30/**
31 * @defgroup oslib_synchronization Synchronization
32 * @details Synchronization services.
33 * @ingroup oslib
34 */
35
36/**
37 * @defgroup oslib_binary_semaphores Binary Semaphores
38 * @ingroup oslib_synchronization
39 */
40
41/**
42 * @defgroup oslib_mailboxes Mailboxes
43 * @ingroup oslib_synchronization
44 */
45
46/**
47 * @defgroup oslib_pipes Pipes
48 * @ingroup oslib_synchronization
49 */
50
51/**
52 * @defgroup oslib_delegates Delegate Threads
53 * @ingroup oslib_synchronization
54 */
55
56/**
57 * @defgroup oslib_jobs_queues Jobs Queues
58 * @ingroup oslib_synchronization
59 */
60
61/**
62 * @defgroup oslib_memory Memory Management
63 * @details Memory Management services.
64 * @ingroup oslib
65 */
66
67/**
68 * @defgroup oslib_memcore Core Memory Manager
69 * @ingroup oslib_memory
70 */
71
72/**
73 * @defgroup oslib_memheaps Memory Heaps
74 * @ingroup oslib_memory
75 */
76
77/**
78 * @defgroup oslib_mempools Memory Pools
79 * @ingroup oslib_memory
80 */
81
82/**
83 * @defgroup oslib_complex Complex Services
84 * @ingroup oslib
85 */
86
87/**
88 * @defgroup oslib_objects_fifos Objects FIFOs
89 * @ingroup oslib_complex
90 */
91
92/**
93 * @defgroup oslib_objchaches Objects Caches
94 * @ingroup oslib_complex
95 */
96
97/**
98 * @defgroup oslib_objects_factory Dynamic Objects Factory
99 * @ingroup oslib_complex
100 */
diff --git a/lib/chibios/os/oslib/include/chbsem.h b/lib/chibios/os/oslib/include/chbsem.h
new file mode 100644
index 000000000..7969d4fd0
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chbsem.h
@@ -0,0 +1,311 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chbsem.h
22 * @brief Binary semaphores structures and macros.
23 * @details Binary semaphores related APIs and services.
24 * <h2>Operation mode</h2>
25 * Binary semaphores are implemented as a set of inline functions
26 * that use the existing counting semaphores primitives. The
27 * difference between counting and binary semaphores is that the
28 * counter of binary semaphores is not allowed to grow above the
29 * value 1. Repeated signal operation are ignored. A binary
30 * semaphore can thus have only two defined states:
31 * - <b>Taken</b>, when its counter has a value of zero or lower
32 * than zero. A negative number represent the number of threads
33 * queued on the binary semaphore.
34 * - <b>Not taken</b>, when its counter has a value of one.
35 * .
36 * Binary semaphores are different from mutexes because there is no
37 * concept of ownership, a binary semaphore can be taken by a
38 * thread and signaled by another thread or an interrupt handler,
39 * mutexes can only be taken and released by the same thread. Another
40 * difference is that binary semaphores, unlike mutexes, do not
41 * implement the priority inheritance protocol.<br>
42 * In order to use the binary semaphores APIs the
43 * @p CH_CFG_USE_SEMAPHORES option must be enabled in @p chconf.h.
44 *
45 * @addtogroup oslib_binary_semaphores
46 * @{
47 */
48
49#ifndef CHBSEM_H
50#define CHBSEM_H
51
52#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
53
54/*===========================================================================*/
55/* Module constants. */
56/*===========================================================================*/
57
58/*===========================================================================*/
59/* Module pre-compile time settings. */
60/*===========================================================================*/
61
62/*===========================================================================*/
63/* Derived constants and error checks. */
64/*===========================================================================*/
65
66/*===========================================================================*/
67/* Module data structures and types. */
68/*===========================================================================*/
69
70/**
71 * @extends semaphore_t
72 *
73 * @brief Binary semaphore type.
74 */
75typedef struct ch_binary_semaphore {
76 semaphore_t sem;
77} binary_semaphore_t;
78
79/*===========================================================================*/
80/* Module macros. */
81/*===========================================================================*/
82
83/**
84 * @brief Data part of a static semaphore initializer.
85 * @details This macro should be used when statically initializing a semaphore
86 * that is part of a bigger structure.
87 *
88 * @param[in] name the name of the semaphore variable
89 * @param[in] taken the semaphore initial state
90 */
91#define _BSEMAPHORE_DATA(name, taken) \
92 {_SEMAPHORE_DATA(name.sem, ((taken) ? 0 : 1))}
93
94/**
95 * @brief Static semaphore initializer.
96 * @details Statically initialized semaphores require no explicit
97 * initialization using @p chBSemInit().
98 *
99 * @param[in] name the name of the semaphore variable
100 * @param[in] taken the semaphore initial state
101 */
102#define BSEMAPHORE_DECL(name, taken) \
103 binary_semaphore_t name = _BSEMAPHORE_DATA(name, taken)
104
105/*===========================================================================*/
106/* External declarations. */
107/*===========================================================================*/
108
109/*===========================================================================*/
110/* Module inline functions. */
111/*===========================================================================*/
112
113/**
114 * @brief Initializes a binary semaphore.
115 *
116 * @param[out] bsp pointer to a @p binary_semaphore_t structure
117 * @param[in] taken initial state of the binary semaphore:
118 * - @a false, the initial state is not taken.
119 * - @a true, the initial state is taken.
120 * .
121 *
122 * @init
123 */
124static inline void chBSemObjectInit(binary_semaphore_t *bsp, bool taken) {
125
126 chSemObjectInit(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1);
127}
128
129/**
130 * @brief Wait operation on the binary semaphore.
131 *
132 * @param[in] bsp pointer to a @p binary_semaphore_t structure
133 * @return A message specifying how the invoking thread has been
134 * released from the semaphore.
135 * @retval MSG_OK if the binary semaphore has been successfully taken.
136 * @retval MSG_RESET if the binary semaphore has been reset using
137 * @p bsemReset().
138 *
139 * @api
140 */
141static inline msg_t chBSemWait(binary_semaphore_t *bsp) {
142
143 return chSemWait(&bsp->sem);
144}
145
146/**
147 * @brief Wait operation on the binary semaphore.
148 *
149 * @param[in] bsp pointer to a @p binary_semaphore_t structure
150 * @return A message specifying how the invoking thread has been
151 * released from the semaphore.
152 * @retval MSG_OK if the binary semaphore has been successfully taken.
153 * @retval MSG_RESET if the binary semaphore has been reset using
154 * @p bsemReset().
155 *
156 * @sclass
157 */
158static inline msg_t chBSemWaitS(binary_semaphore_t *bsp) {
159
160 chDbgCheckClassS();
161
162 return chSemWaitS(&bsp->sem);
163}
164
165/**
166 * @brief Wait operation on the binary semaphore.
167 *
168 * @param[in] bsp pointer to a @p binary_semaphore_t structure
169 * @param[in] timeout the number of ticks before the operation timeouts,
170 * the following special values are allowed:
171 * - @a TIME_IMMEDIATE immediate timeout.
172 * - @a TIME_INFINITE no timeout.
173 * .
174 * @return A message specifying how the invoking thread has been
175 * released from the semaphore.
176 * @retval MSG_OK if the binary semaphore has been successfully taken.
177 * @retval MSG_RESET if the binary semaphore has been reset using
178 * @p bsemReset().
179 * @retval MSG_TIMEOUT if the binary semaphore has not been signaled or reset
180 * within the specified timeout.
181 *
182 * @sclass
183 */
184static inline msg_t chBSemWaitTimeoutS(binary_semaphore_t *bsp,
185 sysinterval_t timeout) {
186
187 chDbgCheckClassS();
188
189 return chSemWaitTimeoutS(&bsp->sem, timeout);
190}
191
192/**
193 * @brief Wait operation on the binary semaphore.
194 *
195 * @param[in] bsp pointer to a @p binary_semaphore_t structure
196 * @param[in] timeout the number of ticks before the operation timeouts,
197 * the following special values are allowed:
198 * - @a TIME_IMMEDIATE immediate timeout.
199 * - @a TIME_INFINITE no timeout.
200 * .
201 * @return A message specifying how the invoking thread has been
202 * released from the semaphore.
203 * @retval MSG_OK if the binary semaphore has been successfully taken.
204 * @retval MSG_RESET if the binary semaphore has been reset using
205 * @p bsemReset().
206 * @retval MSG_TIMEOUT if the binary semaphore has not been signaled or reset
207 * within the specified timeout.
208 *
209 * @api
210 */
211static inline msg_t chBSemWaitTimeout(binary_semaphore_t *bsp,
212 sysinterval_t timeout) {
213
214 return chSemWaitTimeout(&bsp->sem, timeout);
215}
216
217/**
218 * @brief Reset operation on the binary semaphore.
219 * @note The released threads can recognize they were waked up by a reset
220 * rather than a signal because the @p bsemWait() will return
221 * @p MSG_RESET instead of @p MSG_OK.
222 * @note This function does not reschedule.
223 *
224 * @param[in] bsp pointer to a @p binary_semaphore_t structure
225 * @param[in] taken new state of the binary semaphore
226 * - @a false, the new state is not taken.
227 * - @a true, the new state is taken.
228 * .
229 *
230 * @iclass
231 */
232static inline void chBSemResetI(binary_semaphore_t *bsp, bool taken) {
233
234 chDbgCheckClassI();
235
236 chSemResetI(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1);
237}
238
239/**
240 * @brief Reset operation on the binary semaphore.
241 * @note The released threads can recognize they were waked up by a reset
242 * rather than a signal because the @p bsemWait() will return
243 * @p MSG_RESET instead of @p MSG_OK.
244 *
245 * @param[in] bsp pointer to a @p binary_semaphore_t structure
246 * @param[in] taken new state of the binary semaphore
247 * - @a false, the new state is not taken.
248 * - @a true, the new state is taken.
249 * .
250 *
251 * @api
252 */
253static inline void chBSemReset(binary_semaphore_t *bsp, bool taken) {
254
255 chSemReset(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1);
256}
257
258/**
259 * @brief Performs a signal operation on a binary semaphore.
260 * @note This function does not reschedule.
261 *
262 * @param[in] bsp pointer to a @p binary_semaphore_t structure
263 *
264 * @iclass
265 */
266static inline void chBSemSignalI(binary_semaphore_t *bsp) {
267
268 chDbgCheckClassI();
269
270 if (bsp->sem.cnt < (cnt_t)1) {
271 chSemSignalI(&bsp->sem);
272 }
273}
274
275/**
276 * @brief Performs a signal operation on a binary semaphore.
277 *
278 * @param[in] bsp pointer to a @p binary_semaphore_t structure
279 *
280 * @api
281 */
282static inline void chBSemSignal(binary_semaphore_t *bsp) {
283
284 chSysLock();
285 chBSemSignalI(bsp);
286 chSchRescheduleS();
287 chSysUnlock();
288}
289
290/**
291 * @brief Returns the binary semaphore current state.
292 *
293 * @param[in] bsp pointer to a @p binary_semaphore_t structure
294 * @return The binary semaphore current state.
295 * @retval false if the binary semaphore is not taken.
296 * @retval true if the binary semaphore is taken.
297 *
298 * @iclass
299 */
300static inline bool chBSemGetStateI(const binary_semaphore_t *bsp) {
301
302 chDbgCheckClassI();
303
304 return (bsp->sem.cnt > (cnt_t)0) ? false : true;
305}
306
307#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
308
309#endif /* CHBSEM_H */
310
311/** @} */
diff --git a/lib/chibios/os/oslib/include/chdelegates.h b/lib/chibios/os/oslib/include/chdelegates.h
new file mode 100644
index 000000000..b5b62f991
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chdelegates.h
@@ -0,0 +1,208 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chdelegates.h
22 * @brief Delegate threads macros and structures.
23 *
24 * @addtogroup oslib_delegates
25 * @{
26 */
27
28#ifndef CHDELEGATES_H
29#define CHDELEGATES_H
30
31#if (CH_CFG_USE_DELEGATES == TRUE) || defined(__DOXYGEN__)
32
33/*lint -save -e829 [17.1] Required by design.*/
34#include <stdarg.h>
35/*lint -restore*/
36
37/*===========================================================================*/
38/* Module constants. */
39/*===========================================================================*/
40
41/*===========================================================================*/
42/* Module pre-compile time settings. */
43/*===========================================================================*/
44
45/*===========================================================================*/
46/* Derived constants and error checks. */
47/*===========================================================================*/
48
49#if CH_CFG_USE_MESSAGES == FALSE
50#error "CH_CFG_USE_DELEGATES requires CH_CFG_USE_MESSAGES"
51#endif
52
53/*===========================================================================*/
54/* Module data structures and types. */
55/*===========================================================================*/
56
57/**
58 * @brief Type of a delegate veneer function.
59 */
60typedef msg_t (*delegate_veneer_t)(va_list *argsp);
61
62/**
63 * @brief Type of a delegate function with no parameters.
64 */
65typedef msg_t (*delegate_fn0_t)(void);
66
67/**
68 * @brief Type of a delegate function with one parameter.
69 */
70typedef msg_t (*delegate_fn1_t)(msg_t p1);
71
72/**
73 * @brief Type of a delegate function with two parameters.
74 */
75typedef msg_t (*delegate_fn2_t)(msg_t p1, msg_t p2);
76
77/**
78 * @brief Type of a delegate function with three parameters.
79 */
80typedef msg_t (*delegate_fn3_t)(msg_t p1, msg_t p2, msg_t p3);
81
82/**
83 * @brief Type of a delegate function with four parameters.
84 */
85typedef msg_t (*delegate_fn4_t)(msg_t p1, msg_t p2, msg_t p3, msg_t p4);
86
87/*===========================================================================*/
88/* Module macros. */
89/*===========================================================================*/
90
91/*===========================================================================*/
92/* External declarations. */
93/*===========================================================================*/
94
95#ifdef __cplusplus
96extern "C" {
97#endif
98 msg_t __ch_delegate_fn0(va_list *argsp);
99 msg_t __ch_delegate_fn1(va_list *argsp);
100 msg_t __ch_delegate_fn2(va_list *argsp);
101 msg_t __ch_delegate_fn3(va_list *argsp);
102 msg_t __ch_delegate_fn4(va_list *argsp);
103 void chDelegateDispatch(void);
104 msg_t chDelegateDispatchTimeout(sysinterval_t timeout);
105 msg_t chDelegateCallVeneer(thread_t *tp, delegate_veneer_t veneer, ...);
106#ifdef __cplusplus
107}
108#endif
109
110/*===========================================================================*/
111/* Module inline functions. */
112/*===========================================================================*/
113
114/**
115 * @brief Direct call to a function with no parameters.
116 * @note The return value is assumed to be not larger than a data
117 * pointer type. If you need a portable function then use
118 * @p chDelegateCallVeneer() instead.
119 *
120 * @param[in] tp pointer to the delegate thread
121 * @param[in] func pointer to the function to be called
122 * @return The function return value as a @p msg_t.
123 */
124static inline msg_t chDelegateCallDirect0(thread_t *tp, delegate_fn0_t func) {
125
126 return chDelegateCallVeneer(tp, __ch_delegate_fn0, func);
127}
128
129/**
130 * @brief Direct call to a function with one parameter.
131 * @note The return value and parameters are assumed to be not larger
132 * than a data pointer type. If you need a portable function then use
133 * @p chDelegateCallVeneer() instead.
134 *
135 * @param[in] tp pointer to the delegate thread
136 * @param[in] func pointer to the function to be called
137 * @param[in] p1 parameter 1 passed as a @p msg_t
138 * @return The function return value as a @p msg_t.
139 */
140static inline msg_t chDelegateCallDirect1(thread_t *tp, delegate_fn1_t func,
141 msg_t p1) {
142
143 return chDelegateCallVeneer(tp, __ch_delegate_fn1, func, p1);
144}
145
146/**
147 * @brief Direct call to a function with two parameters.
148 * @note The return value and parameters are assumed to be not larger
149 * than a data pointer type. If you need a portable function then use
150 * @p chDelegateCallVeneer() instead.
151 *
152 * @param[in] tp pointer to the delegate thread
153 * @param[in] func pointer to the function to be called
154 * @param[in] p1 parameter 1 passed as a @p msg_t
155 * @param[in] p2 parameter 2 passed as a @p msg_t
156 * @return The function return value as a @p msg_t.
157 */
158static inline msg_t chDelegateCallDirect2(thread_t *tp, delegate_fn2_t func,
159 msg_t p1, msg_t p2) {
160
161 return chDelegateCallVeneer(tp, __ch_delegate_fn2, func, p1, p2);
162}
163
164/**
165 * @brief Direct call to a function with three parameters.
166 * @note The return value and parameters are assumed to be not larger
167 * than a data pointer type. If you need a portable function then use
168 * @p chDelegateCallVeneer() instead.
169 *
170 * @param[in] tp pointer to the delegate thread
171 * @param[in] func pointer to the function to be called
172 * @param[in] p1 parameter 1 passed as a @p msg_t
173 * @param[in] p2 parameter 2 passed as a @p msg_t
174 * @param[in] p3 parameter 3 passed as a @p msg_t
175 * @return The function return value as a @p msg_t.
176 */
177static inline msg_t chDelegateCallDirect3(thread_t *tp, delegate_fn3_t func,
178 msg_t p1, msg_t p2, msg_t p3) {
179
180 return chDelegateCallVeneer(tp, __ch_delegate_fn3, func, p1, p2, p3);
181}
182
183/**
184 * @brief Direct call to a function with four parameters.
185 * @note The return value and parameters are assumed to be not larger
186 * than a data pointer type. If you need a portable function then use
187 * @p chDelegateCallVeneer() instead.
188 *
189 * @param[in] tp pointer to the delegate thread
190 * @param[in] func pointer to the function to be called
191 * @param[in] p1 parameter 1 passed as a @p msg_t
192 * @param[in] p2 parameter 2 passed as a @p msg_t
193 * @param[in] p3 parameter 3 passed as a @p msg_t
194 * @param[in] p4 parameter 4 passed as a @p msg_t
195 * @return The function return value as a @p msg_t.
196 */
197static inline msg_t chDelegateCallDirect4(thread_t *tp, delegate_fn4_t func,
198 msg_t p1, msg_t p2, msg_t p3,
199 msg_t p4) {
200
201 return chDelegateCallVeneer(tp, __ch_delegate_fn4, func, p1, p2, p3, p4);
202}
203
204#endif /* CH_CFG_USE_DELEGATES == TRUE */
205
206#endif /* CHDELEGATES_H */
207
208/** @} */
diff --git a/lib/chibios/os/oslib/include/chfactory.h b/lib/chibios/os/oslib/include/chfactory.h
new file mode 100644
index 000000000..c751c6fd1
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chfactory.h
@@ -0,0 +1,523 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chfactory.h
22 * @brief ChibiOS objects factory structures and macros.
23 *
24 * @addtogroup oslib_objects_factory
25 * @{
26 */
27
28#ifndef CHFACTORY_H
29#define CHFACTORY_H
30
31#if (CH_CFG_USE_FACTORY == TRUE) || defined(__DOXYGEN__)
32
33/*===========================================================================*/
34/* Module constants. */
35/*===========================================================================*/
36
37/*===========================================================================*/
38/* Module pre-compile time settings. */
39/*===========================================================================*/
40
41/**
42 * @brief Maximum length for object names.
43 * @details If the specified length is zero then the name is stored by
44 * pointer but this could have unintended side effects.
45 */
46#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH) || defined(__DOXYGEN__)
47#define CH_CFG_FACTORY_MAX_NAMES_LENGTH 8
48#endif
49
50/**
51 * @brief Enables the registry of generic objects.
52 */
53#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY) || defined(__DOXYGEN__)
54#define CH_CFG_FACTORY_OBJECTS_REGISTRY TRUE
55#endif
56
57/**
58 * @brief Enables factory for generic buffers.
59 */
60#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS) || defined(__DOXYGEN__)
61#define CH_CFG_FACTORY_GENERIC_BUFFERS TRUE
62#endif
63
64/**
65 * @brief Enables factory for semaphores.
66 */
67#if !defined(CH_CFG_FACTORY_SEMAPHORES) || defined(__DOXYGEN__)
68#define CH_CFG_FACTORY_SEMAPHORES TRUE
69#endif
70
71/**
72 * @brief Enables factory for mailboxes.
73 */
74#if !defined(CH_CFG_FACTORY_MAILBOXES) || defined(__DOXYGEN__)
75#define CH_CFG_FACTORY_MAILBOXES TRUE
76#endif
77
78/**
79 * @brief Enables factory for objects FIFOs.
80 */
81#if !defined(CH_CFG_FACTORY_OBJ_FIFOS) || defined(__DOXYGEN__)
82#define CH_CFG_FACTORY_OBJ_FIFOS TRUE
83#endif
84
85/**
86 * @brief Enables factory for objects FIFOs.
87 */
88#if !defined(CH_CFG_FACTORY_OBJ_FIFOS) || defined(__DOXYGEN__)
89#define CH_CFG_FACTORY_OBJ_FIFOS TRUE
90#endif
91
92/**
93 * @brief Enables factory for Pipes.
94 */
95#if !defined(CH_CFG_FACTORY_PIPES) || defined(__DOXYGEN__)
96#define CH_CFG_FACTORY_PIPES TRUE
97#endif
98
99/*===========================================================================*/
100/* Derived constants and error checks. */
101/*===========================================================================*/
102
103#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) && (CH_CFG_USE_SEMAPHORES == FALSE)
104/*lint -save -e767 [20.5] Valid because the #undef.*/
105#undef CH_CFG_FACTORY_SEMAPHORES
106#define CH_CFG_FACTORY_SEMAPHORES FALSE
107/*lint restore*/
108#endif
109
110#if (CH_CFG_FACTORY_MAILBOXES == TRUE) && (CH_CFG_USE_MAILBOXES == FALSE)
111/*lint -save -e767 [20.5] Valid because the #undef.*/
112#undef CH_CFG_FACTORY_MAILBOXES
113#define CH_CFG_FACTORY_MAILBOXES FALSE
114/*lint restore*/
115#endif
116
117#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) && (CH_CFG_USE_OBJ_FIFOS == FALSE)
118/*lint -save -e767 [20.5] Valid because the #undef.*/
119#undef CH_CFG_FACTORY_OBJ_FIFOS
120#define CH_CFG_FACTORY_OBJ_FIFOS FALSE
121/*lint restore*/
122#endif
123
124#if (CH_CFG_FACTORY_PIPES == TRUE) && (CH_CFG_USE_PIPES == FALSE)
125/*lint -save -e767 [20.5] Valid because the #undef.*/
126#undef CH_CFG_FACTORY_PIPES
127#define CH_CFG_FACTORY_PIPES FALSE
128/*lint restore*/
129#endif
130
131#define CH_FACTORY_REQUIRES_POOLS \
132 ((CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || \
133 (CH_CFG_FACTORY_SEMAPHORES == TRUE))
134
135#define CH_FACTORY_REQUIRES_HEAP \
136 ((CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || \
137 (CH_CFG_FACTORY_MAILBOXES == TRUE) || \
138 (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || \
139 (CH_CFG_FACTORY_PIPES == TRUE))
140
141#if (CH_CFG_FACTORY_MAX_NAMES_LENGTH < 0) || \
142 (CH_CFG_FACTORY_MAX_NAMES_LENGTH > 32)
143#error "invalid CH_CFG_FACTORY_MAX_NAMES_LENGTH value"
144#endif
145
146#if (CH_CFG_USE_MUTEXES == FALSE) && (CH_CFG_USE_SEMAPHORES == FALSE)
147#error "CH_CFG_USE_FACTORY requires CH_CFG_USE_MUTEXES and/or CH_CFG_USE_SEMAPHORES"
148#endif
149
150#if CH_CFG_USE_MEMCORE == FALSE
151#error "CH_CFG_USE_FACTORY requires CH_CFG_USE_MEMCORE"
152#endif
153
154#if CH_FACTORY_REQUIRES_POOLS && (CH_CFG_USE_MEMPOOLS == FALSE)
155#error "CH_CFG_USE_MEMPOOLS is required"
156#endif
157
158#if CH_FACTORY_REQUIRES_HEAP && (CH_CFG_USE_HEAP == FALSE)
159#error "CH_CFG_USE_HEAP is required"
160#endif
161
162/*===========================================================================*/
163/* Module data structures and types. */
164/*===========================================================================*/
165
166/**
167 * @brief Type of a dynamic object list element.
168 */
169typedef struct ch_dyn_element {
170 /**
171 * @brief Next dynamic object in the list.
172 */
173 struct ch_dyn_element *next;
174 /**
175 * @brief Number of references to this object.
176 */
177 ucnt_t refs;
178#if (CH_CFG_FACTORY_MAX_NAMES_LENGTH > 0) || defined(__DOXYGEN__)
179 char name[CH_CFG_FACTORY_MAX_NAMES_LENGTH];
180#else
181 const char *name;
182#endif
183} dyn_element_t;
184
185/**
186 * @brief Type of a dynamic object list.
187 */
188typedef struct ch_dyn_list {
189 dyn_element_t *next;
190} dyn_list_t;
191
192#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
193/**
194 * @brief Type of a registered object.
195 */
196typedef struct ch_registered_static_object {
197 /**
198 * @brief List element of the registered object.
199 */
200 dyn_element_t element;
201 /**
202 * @brief Pointer to the object.
203 * @note The type of the object is not stored in anyway.
204 */
205 void *objp;
206} registered_object_t;
207#endif
208
209#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
210/**
211 * @brief Type of a dynamic buffer object.
212 */
213typedef struct ch_dyn_object {
214 /**
215 * @brief List element of the dynamic buffer object.
216 */
217 dyn_element_t element;
218} dyn_buffer_t;
219#endif
220
221#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
222/**
223 * @brief Type of a dynamic semaphore.
224 */
225typedef struct ch_dyn_semaphore {
226 /**
227 * @brief List element of the dynamic semaphore.
228 */
229 dyn_element_t element;
230 /**
231 * @brief The semaphore.
232 */
233 semaphore_t sem;
234} dyn_semaphore_t;
235#endif
236
237#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
238/**
239 * @brief Type of a dynamic buffer object.
240 */
241typedef struct ch_dyn_mailbox {
242 /**
243 * @brief List element of the dynamic buffer object.
244 */
245 dyn_element_t element;
246 /**
247 * @brief The mailbox.
248 */
249 mailbox_t mbx;
250} dyn_mailbox_t;
251#endif
252
253#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
254/**
255 * @brief Type of a dynamic buffer object.
256 */
257typedef struct ch_dyn_objects_fifo {
258 /**
259 * @brief List element of the dynamic buffer object.
260 */
261 dyn_element_t element;
262 /**
263 * @brief The objects FIFO.
264 */
265 objects_fifo_t fifo;
266} dyn_objects_fifo_t;
267#endif
268
269#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
270/**
271 * @brief Type of a dynamic pipe object.
272 */
273typedef struct ch_dyn_pipe {
274 /**
275 * @brief List element of the dynamic pipe object.
276 */
277 dyn_element_t element;
278 /**
279 * @brief The pipe.
280 */
281 pipe_t pipe;
282} dyn_pipe_t;
283#endif
284
285/**
286 * @brief Type of the factory main object.
287 */
288typedef struct ch_objects_factory {
289 /**
290 * @brief Factory access mutex or semaphore.
291 */
292#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
293 mutex_t mtx;
294#else
295 semaphore_t sem;
296#endif
297 /**
298 * @brief List of the registered objects.
299 */
300 dyn_list_t obj_list;
301 /**
302 * @brief Pool of the available registered objects.
303 */
304 memory_pool_t obj_pool;
305#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
306 /**
307 * @brief List of the allocated buffer objects.
308 */
309 dyn_list_t buf_list;
310#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS = TRUE */
311#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
312 /**
313 * @brief List of the allocated semaphores.
314 */
315 dyn_list_t sem_list;
316 /**
317 * @brief Pool of the available semaphores.
318 */
319 memory_pool_t sem_pool;
320#endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */
321#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
322 /**
323 * @brief List of the allocated buffer objects.
324 */
325 dyn_list_t mbx_list;
326#endif /* CH_CFG_FACTORY_MAILBOXES = TRUE */
327#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
328 /**
329 * @brief List of the allocated "objects FIFO" objects.
330 */
331 dyn_list_t fifo_list;
332#endif /* CH_CFG_FACTORY_OBJ_FIFOS = TRUE */
333#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
334 /**
335 * @brief List of the allocated pipe objects.
336 */
337 dyn_list_t pipe_list;
338#endif /* CH_CFG_FACTORY_PIPES = TRUE */
339} objects_factory_t;
340
341/*===========================================================================*/
342/* Module macros. */
343/*===========================================================================*/
344
345/*===========================================================================*/
346/* External declarations. */
347/*===========================================================================*/
348
349#if !defined(__DOXYGEN__)
350extern objects_factory_t ch_factory;
351#endif
352
353#ifdef __cplusplus
354extern "C" {
355#endif
356 void _factory_init(void);
357#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
358 registered_object_t *chFactoryRegisterObject(const char *name,
359 void *objp);
360 registered_object_t *chFactoryFindObject(const char *name);
361 registered_object_t *chFactoryFindObjectByPointer(void *objp);
362 void chFactoryReleaseObject(registered_object_t *rop);
363#endif
364#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
365 dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size);
366 dyn_buffer_t *chFactoryFindBuffer(const char *name);
367 void chFactoryReleaseBuffer(dyn_buffer_t *dbp);
368#endif
369#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
370 dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n);
371 dyn_semaphore_t *chFactoryFindSemaphore(const char *name);
372 void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp);
373#endif
374#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
375 dyn_mailbox_t *chFactoryCreateMailbox(const char *name, size_t n);
376 dyn_mailbox_t *chFactoryFindMailbox(const char *name);
377 void chFactoryReleaseMailbox(dyn_mailbox_t *dmp);
378#endif
379#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
380 dyn_objects_fifo_t *chFactoryCreateObjectsFIFO(const char *name,
381 size_t objsize,
382 size_t objn,
383 unsigned objalign);
384 dyn_objects_fifo_t *chFactoryFindObjectsFIFO(const char *name);
385 void chFactoryReleaseObjectsFIFO(dyn_objects_fifo_t *dofp);
386#endif
387#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
388 dyn_pipe_t *chFactoryCreatePipe(const char *name, size_t size);
389 dyn_pipe_t *chFactoryFindPipe(const char *name);
390 void chFactoryReleasePipe(dyn_pipe_t *dpp);
391#endif
392#ifdef __cplusplus
393}
394#endif
395
396/*===========================================================================*/
397/* Module inline functions. */
398/*===========================================================================*/
399
400/**
401 * @brief Duplicates an object reference.
402 * @note This function can be used on any kind of dynamic object.
403 *
404 * @param[in] dep pointer to the element field of the object
405 * @return The duplicated object reference.
406 *
407 * @api
408 */
409static inline dyn_element_t *chFactoryDuplicateReference(dyn_element_t *dep) {
410
411 dep->refs++;
412
413 return dep;
414}
415
416#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
417/**
418 * @brief Returns the pointer to the inner registered object.
419 *
420 * @param[in] rop registered object reference
421 * @return The pointer to the registered object.
422 *
423 * @api
424 */
425static inline void *chFactoryGetObject(registered_object_t *rop) {
426
427 return rop->objp;
428}
429#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
430
431#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
432/**
433 * @brief Returns the size of a generic dynamic buffer object.
434 *
435 * @param[in] dbp dynamic buffer object reference
436 * @return The size of the buffer object in bytes.
437 *
438 * @api
439 */
440static inline size_t chFactoryGetBufferSize(dyn_buffer_t *dbp) {
441
442 return chHeapGetSize(dbp) - sizeof (dyn_element_t);
443}
444
445/**
446 * @brief Returns the pointer to the inner buffer.
447 *
448 * @param[in] dbp dynamic buffer object reference
449 * @return The pointer to the dynamic buffer.
450 *
451 * @api
452 */
453static inline uint8_t *chFactoryGetBuffer(dyn_buffer_t *dbp) {
454
455 return (uint8_t *)(dbp + 1);
456}
457#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE */
458
459#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
460/**
461 * @brief Returns the pointer to the inner semaphore.
462 *
463 * @param[in] dsp dynamic semaphore object reference
464 * @return The pointer to the semaphore.
465 *
466 * @api
467 */
468static inline semaphore_t *chFactoryGetSemaphore(dyn_semaphore_t *dsp) {
469
470 return &dsp->sem;
471}
472#endif /* CH_CFG_FACTORY_SEMAPHORES == TRUE */
473
474#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
475/**
476 * @brief Returns the pointer to the inner mailbox.
477 *
478 * @param[in] dmp dynamic mailbox object reference
479 * @return The pointer to the mailbox.
480 *
481 * @api
482 */
483static inline mailbox_t *chFactoryGetMailbox(dyn_mailbox_t *dmp) {
484
485 return &dmp->mbx;
486}
487#endif /* CH_CFG_FACTORY_MAILBOXES == TRUE */
488
489#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
490/**
491 * @brief Returns the pointer to the inner objects FIFO.
492 *
493 * @param[in] dofp dynamic "objects FIFO" object reference
494 * @return The pointer to the objects FIFO.
495 *
496 * @api
497 */
498static inline objects_fifo_t *chFactoryGetObjectsFIFO(dyn_objects_fifo_t *dofp) {
499
500 return &dofp->fifo;
501}
502#endif /* CH_CFG_FACTORY_OBJ_FIFOS == TRUE */
503
504#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
505/**
506 * @brief Returns the pointer to the inner pipe.
507 *
508 * @param[in] dpp dynamic pipe object reference
509 * @return The pointer to the pipe.
510 *
511 * @api
512 */
513static inline pipe_t *chFactoryGetPipe(dyn_pipe_t *dpp) {
514
515 return &dpp->pipe;
516}
517#endif /* CH_CFG_FACTORY_PIPES == TRUE */
518
519#endif /* CH_CFG_USE_FACTORY == TRUE */
520
521#endif /* CHFACTORY_H */
522
523/** @} */
diff --git a/lib/chibios/os/oslib/include/chjobs.h b/lib/chibios/os/oslib/include/chjobs.h
new file mode 100644
index 000000000..5eaa0e4ec
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chjobs.h
@@ -0,0 +1,397 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chjobs.h
22 * @brief Jobs Queues structures and macros.
23 * @details This module implements queues of generic jobs to be delegated
24 * asynchronously to a pool of dedicated threads.
25 * Operations defined for Jobs Queues
26 * - <b>Get</b>: An job object is taken from the pool of the
27 * available jobs.
28 * - <b>Post</b>: A job is posted to the queue, it will be
29 * returned to the pool after execution.
30 * .
31 *
32 * @addtogroup oslib_jobs_queues
33 * @{
34 */
35
36#ifndef CHJOBS_H
37#define CHJOBS_H
38
39#if (CH_CFG_USE_JOBS == TRUE) || defined(__DOXYGEN__)
40
41/*===========================================================================*/
42/* Module constants. */
43/*===========================================================================*/
44
45/**
46 * @brief Dispatcher return code in case of a @p JOB_NUL has been received.
47 */
48#define MSG_JOB_NULL ((msg_t)-2)
49
50/*===========================================================================*/
51/* Module pre-compile time settings. */
52/*===========================================================================*/
53
54/*===========================================================================*/
55/* Derived constants and error checks. */
56/*===========================================================================*/
57
58#if CH_CFG_USE_MEMPOOLS == FALSE
59#error "CH_CFG_USE_JOBS requires CH_CFG_USE_MEMPOOLS"
60#endif
61
62#if CH_CFG_USE_SEMAPHORES == FALSE
63#error "CH_CFG_USE_JOBS requires CH_CFG_USE_SEMAPHORES"
64#endif
65
66#if CH_CFG_USE_MAILBOXES == FALSE
67#error "CH_CFG_USE_JOBS requires CH_CFG_USE_MAILBOXES"
68#endif
69
70/*===========================================================================*/
71/* Module data structures and types. */
72/*===========================================================================*/
73
74/**
75 * @brief Type of a jobs queue.
76 */
77typedef struct ch_jobs_queue {
78 /**
79 * @brief Pool of the free jobs.
80 */
81 guarded_memory_pool_t free;
82 /**
83 * @brief Mailbox of the sent jobs.
84 */
85 mailbox_t mbx;
86} jobs_queue_t;
87
88/**
89 * @brief Type of a job function.
90 */
91typedef void (*job_function_t)(void *arg);
92
93/**
94 * @brief Type of a job descriptor.
95 */
96typedef struct ch_job_descriptor {
97 /**
98 * @brief Job function.
99 */
100 job_function_t jobfunc;
101 /**
102 * @brief Argument to be passed to the job function.
103 */
104 void *jobarg;
105} job_descriptor_t;
106
107/*===========================================================================*/
108/* Module macros. */
109/*===========================================================================*/
110
111/*===========================================================================*/
112/* External declarations. */
113/*===========================================================================*/
114
115#ifdef __cplusplus
116extern "C" {
117#endif
118
119#ifdef __cplusplus
120}
121#endif
122
123/*===========================================================================*/
124/* Module inline functions. */
125/*===========================================================================*/
126
127/**
128 * @brief Initializes a jobs queue object.
129 *
130 * @param[out] jqp pointer to a @p jobs_queue_t structure
131 * @param[in] jobsn number of jobs available
132 * @param[in] jobsbuf pointer to the buffer of jobs, it must be able
133 * to hold @p jobsn @p job_descriptor_t structures
134 * @param[in] msgbuf pointer to the buffer of messages, it must be able
135 * to hold @p jobsn @p msg_t messages
136 *
137 * @init
138 */
139static inline void chJobObjectInit(jobs_queue_t *jqp,
140 size_t jobsn,
141 job_descriptor_t *jobsbuf,
142 msg_t *msgbuf) {
143
144 chDbgCheck((jobsn > 0U) && (jobsbuf != NULL) && (msgbuf != NULL));
145
146 chGuardedPoolObjectInit(&jqp->free, sizeof (job_descriptor_t));
147 chGuardedPoolLoadArray(&jqp->free, (void *)jobsbuf, jobsn);
148 chMBObjectInit(&jqp->mbx, msgbuf, jobsn);
149}
150
151/**
152 * @brief Allocates a free job object.
153 *
154 * @param[in] jqp pointer to a @p jobs_queue_t structure
155 * @return The pointer to the allocated job object.
156 *
157 * @api
158 */
159static inline job_descriptor_t *chJobGet(jobs_queue_t *jqp) {
160
161 return (job_descriptor_t *)chGuardedPoolAllocTimeout(&jqp->free, TIME_INFINITE);
162}
163
164/**
165 * @brief Allocates a free job object.
166 *
167 * @param[in] jqp pointer to a @p jobs_queue_t structure
168 * @return The pointer to the allocated job object.
169 * @retval NULL if a job object is not immediately available.
170 *
171 * @iclass
172 */
173static inline job_descriptor_t *chJobGetI(jobs_queue_t *jqp) {
174
175 return (job_descriptor_t *)chGuardedPoolAllocI(&jqp->free);
176}
177
178/**
179 * @brief Allocates a free job object.
180 *
181 * @param[in] jqp pointer to a @p jobs_queue_t structure
182 * @param[in] timeout the number of ticks before the operation timeouts,
183 * the following special values are allowed:
184 * - @a TIME_IMMEDIATE immediate timeout.
185 * - @a TIME_INFINITE no timeout.
186 * .
187 * @return The pointer to the allocated job object.
188 * @retval NULL if a job object is not available within the specified
189 * timeout.
190 *
191 * @sclass
192 */
193static inline job_descriptor_t *chJobGetTimeoutS(jobs_queue_t *jqp,
194 sysinterval_t timeout) {
195
196 return (job_descriptor_t *)chGuardedPoolAllocTimeoutS(&jqp->free, timeout);
197}
198
199/**
200 * @brief Allocates a free job object.
201 *
202 * @param[in] jqp pointer to a @p jobs_queue_t structure
203 * @param[in] timeout the number of ticks before the operation timeouts,
204 * the following special values are allowed:
205 * - @a TIME_IMMEDIATE immediate timeout.
206 * - @a TIME_INFINITE no timeout.
207 * .
208 * @return The pointer to the allocated job object.
209 * @retval NULL if a job object is not available within the specified
210 * timeout.
211 *
212 * @api
213 */
214static inline job_descriptor_t *chJobGetTimeout(jobs_queue_t *jqp,
215 sysinterval_t timeout) {
216
217 return (job_descriptor_t *)chGuardedPoolAllocTimeout(&jqp->free, timeout);
218}
219
220/**
221 * @brief Posts a job object.
222 * @note By design the object can be always immediately posted.
223 *
224 * @param[in] jqp pointer to a @p jobs_queue_t structure
225 * @param[in] jp pointer to the job object to be posted
226 *
227 * @iclass
228 */
229static inline void chJobPostI(jobs_queue_t *jqp, job_descriptor_t *jp) {
230 msg_t msg;
231
232 msg = chMBPostI(&jqp->mbx, (msg_t)jp);
233 chDbgAssert(msg == MSG_OK, "post failed");
234}
235
236/**
237 * @brief Posts a job object.
238 * @note By design the object can be always immediately posted.
239 *
240 * @param[in] jqp pointer to a @p jobs_queue_t structure
241 * @param[in] jp pointer to the job object to be posted
242 *
243 * @sclass
244 */
245static inline void chJobPostS(jobs_queue_t *jqp, job_descriptor_t *jp) {
246 msg_t msg;
247
248 msg = chMBPostTimeoutS(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
249 chDbgAssert(msg == MSG_OK, "post failed");
250}
251
252/**
253 * @brief Posts a job object.
254 * @note By design the object can be always immediately posted.
255 *
256 * @param[in] jqp pointer to a @p jobs_queue_t structure
257 * @param[in] jp pointer to the job object to be posted
258 *
259 * @api
260 */
261static inline void chJobPost(jobs_queue_t *jqp, job_descriptor_t *jp) {
262 msg_t msg;
263
264 msg = chMBPostTimeout(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
265 chDbgAssert(msg == MSG_OK, "post failed");
266}
267
268/**
269 * @brief Posts an high priority job object.
270 * @note By design the object can be always immediately posted.
271 *
272 * @param[in] jqp pointer to a @p jobs_queue_t structure
273 * @param[in] jp pointer to the job object to be posted
274 *
275 * @iclass
276 */
277static inline void chJobPostAheadI(jobs_queue_t *jqp, job_descriptor_t *jp) {
278 msg_t msg;
279
280 msg = chMBPostAheadI(&jqp->mbx, (msg_t)jp);
281 chDbgAssert(msg == MSG_OK, "post failed");
282}
283
284/**
285 * @brief Posts an high priority job object.
286 * @note By design the object can be always immediately posted.
287 *
288 * @param[in] jqp pointer to a @p jobs_queue_t structure
289 * @param[in] jp pointer to the job object to be posted
290 *
291 * @sclass
292 */
293static inline void chJobPostAheadS(jobs_queue_t *jqp, job_descriptor_t *jp) {
294 msg_t msg;
295
296 msg = chMBPostAheadTimeoutS(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
297 chDbgAssert(msg == MSG_OK, "post failed");
298}
299
300/**
301 * @brief Posts an high priority job object.
302 * @note By design the object can be always immediately posted.
303 *
304 * @param[in] jqp pointer to a @p jobs_queue_t structure
305 * @param[in] jp pointer to the job object to be posted
306 *
307 * @api
308 */
309static inline void chJobPostAhead(jobs_queue_t *jqp, job_descriptor_t *jp) {
310 msg_t msg;
311
312 msg = chMBPostAheadTimeout(&jqp->mbx, (msg_t)jp, TIME_IMMEDIATE);
313 chDbgAssert(msg == MSG_OK, "post failed");
314}
315
316/**
317 * @brief Waits for a job then executes it.
318 *
319 * @param[in] jqp pointer to a @p jobs_queue_t structure
320 * @return The function outcome.
321 * @retval MSG_OK if a job has been executed.
322 * @retval MSG_RESET if the internal mailbox has been reset.
323 * @retval MSG_JOB_NULL if a @p JOB_NULL has been received.
324 */
325static inline msg_t chJobDispatch(jobs_queue_t *jqp) {
326 msg_t msg, jmsg;
327
328 /* Waiting for a job.*/
329 msg = chMBFetchTimeout(&jqp->mbx, &jmsg, TIME_INFINITE);
330 if (msg == MSG_OK) {
331 job_descriptor_t *jp = (job_descriptor_t *)jmsg;
332
333 chDbgAssert(jp != NULL, "is NULL");
334
335 if (jp->jobfunc != NULL) {
336
337 /* Invoking the job function.*/
338 jp->jobfunc(jp->jobarg);
339
340 /* Returning the job descriptor object.*/
341 chGuardedPoolFree(&jqp->free, (void *)jp);
342 }
343 else {
344 msg = MSG_JOB_NULL;
345 }
346 }
347
348 return msg;
349}
350
351/**
352 * @brief Waits for a job then executes it.
353 *
354 * @param[in] jqp pointer to a @p jobs_queue_t structure
355 * @param[in] timeout the number of ticks before the operation timeouts,
356 * the following special values are allowed:
357 * - @a TIME_IMMEDIATE immediate timeout.
358 * - @a TIME_INFINITE no timeout.
359 * .
360 * @return The function outcome.
361 * @retval MSG_OK if a job has been executed.
362 * @retval MSG_TIMEOUT if a timeout occurred.
363 * @retval MSG_RESET if the internal mailbox has been reset.
364 * @retval MSG_JOB_NULL if a @p JOB_NULL has been received.
365 */
366static inline msg_t chJobDispatchTimeout(jobs_queue_t *jqp,
367 sysinterval_t timeout) {
368 msg_t msg, jmsg;
369
370 /* Waiting for a job or a timeout.*/
371 msg = chMBFetchTimeout(&jqp->mbx, &jmsg, timeout);
372 if (msg == MSG_OK) {
373 job_descriptor_t *jp = (job_descriptor_t *)jmsg;
374
375 chDbgAssert(jp != NULL, "is NULL");
376
377 if (jp->jobfunc != NULL) {
378
379 /* Invoking the job function.*/
380 jp->jobfunc(jp->jobarg);
381
382 /* Returning the job descriptor object.*/
383 chGuardedPoolFree(&jqp->free, (void *)jp);
384 }
385 else {
386 msg = MSG_JOB_NULL;
387 }
388 }
389
390 return msg;
391}
392
393#endif /* CH_CFG_USE_JOBS == TRUE */
394
395#endif /* CHJOBS_H */
396
397/** @} */
diff --git a/lib/chibios/os/oslib/include/chlib.h b/lib/chibios/os/oslib/include/chlib.h
new file mode 100644
index 000000000..e8ad22f8e
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chlib.h
@@ -0,0 +1,264 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chlib.h
22 * @brief ChibiOS/LIB main include file.
23 * @details This header includes all the required library headers. This file
24 * is meant do be included by @p ch.h not directly by user.
25 *
26 * @addtogroup oslib_info
27 * @details OS Library related info.
28 * @{
29 */
30
31#ifndef CHLIB_H
32#define CHLIB_H
33
34/*===========================================================================*/
35/* Module constants. */
36/*===========================================================================*/
37
38/**
39 * @brief ChibiOS/LIB identification macro.
40 */
41#define _CHIBIOS_OSLIB_
42
43/**
44 * @brief Stable release flag.
45 */
46#define CH_OSLIB_STABLE 1
47
48/**
49 * @name ChibiOS/LIB version identification
50 * @{
51 */
52/**
53 * @brief OS Library version string.
54 */
55#define CH_OSLIB_VERSION "1.2.1"
56
57/**
58 * @brief OS Library version major number.
59 */
60#define CH_OSLIB_MAJOR 1
61
62/**
63 * @brief OS Library version minor number.
64 */
65#define CH_OSLIB_MINOR 2
66
67/**
68 * @brief OS Library version patch number.
69 */
70#define CH_OSLIB_PATCH 1
71/** @} */
72
73/*===========================================================================*/
74/* Module pre-compile time settings. */
75/*===========================================================================*/
76
77/*===========================================================================*/
78/* Derived constants and error checks. */
79/*===========================================================================*/
80
81/* Host OS checks.*/
82#if !defined(_CHIBIOS_RT_) && !defined(_CHIBIOS_NIL_)
83#error "OS check failed, must be included after ch.h"
84#endif
85
86/* Configuration file checks.*/
87#if !defined(CH_CFG_USE_MAILBOXES)
88#error "CH_CFG_USE_MAILBOXES not defined in chconf.h"
89#endif
90
91#if !defined(CH_CFG_USE_MEMCORE)
92#error "CH_CFG_USE_MEMCORE not defined in chconf.h"
93#endif
94
95#if !defined(CH_CFG_USE_HEAP)
96#error "CH_CFG_USE_HEAP not defined in chconf.h"
97#endif
98
99#if !defined(CH_CFG_USE_MEMPOOLS)
100#error "CH_CFG_USE_MEMPOOLS not defined in chconf.h"
101#endif
102
103#if !defined(CH_CFG_USE_OBJ_FIFOS)
104#error "CH_CFG_USE_OBJ_FIFOS not defined in chconf.h"
105#endif
106
107#if !defined(CH_CFG_USE_PIPES)
108#error "CH_CFG_USE_PIPES not defined in chconf.h"
109#endif
110
111#if !defined(CH_CFG_USE_OBJ_CACHES)
112#error "CH_CFG_USE_OBJ_CACHES not defined in chconf.h"
113#endif
114
115#if !defined(CH_CFG_USE_DELEGATES)
116#error "CH_CFG_USE_DELEGATES not defined in chconf.h"
117#endif
118
119#if !defined(CH_CFG_USE_JOBS)
120#error "CH_CFG_USE_JOBS not defined in chconf.h"
121#endif
122
123/* Objects factory options checks.*/
124#if !defined(CH_CFG_USE_FACTORY)
125#error "CH_CFG_USE_FACTORY not defined in chconf.h"
126#endif
127
128#if !defined(CH_CFG_FACTORY_MAX_NAMES_LENGTH)
129#error "CH_CFG_FACTORY_MAX_NAMES_LENGTH not defined in chconf.h"
130#endif
131
132#if !defined(CH_CFG_FACTORY_OBJECTS_REGISTRY)
133#error "CH_CFG_FACTORY_OBJECTS_REGISTRY not defined in chconf.h"
134#endif
135
136#if !defined(CH_CFG_FACTORY_GENERIC_BUFFERS)
137#error "CH_CFG_FACTORY_GENERIC_BUFFERS not defined in chconf.h"
138#endif
139
140#if !defined(CH_CFG_FACTORY_SEMAPHORES)
141#error "CH_CFG_FACTORY_SEMAPHORES not defined in chconf.h"
142#endif
143
144#if !defined(CH_CFG_FACTORY_MAILBOXES)
145#error "CH_CFG_FACTORY_MAILBOXES not defined in chconf.h"
146#endif
147
148#if !defined(CH_CFG_FACTORY_OBJ_FIFOS)
149#error "CH_CFG_FACTORY_OBJ_FIFOS not defined in chconf.h"
150#endif
151
152/* License checks.*/
153#if !defined(CH_CUSTOMER_LIC_OSLIB) || !defined(CH_LICENSE_FEATURES)
154#error "malformed chlicense.h"
155#endif
156
157#if (CH_LICENSE_FEATURES != CH_FEATURES_FULL) && \
158 (CH_LICENSE_FEATURES != CH_FEATURES_INTERMEDIATE) && \
159 (CH_LICENSE_FEATURES != CH_FEATURES_BASIC)
160#error "invalid CH_LICENSE_FEATURES setting"
161#endif
162
163/* Restrictions in basic and intermediate modes.*/
164#if (CH_CUSTOMER_LIC_OSLIB == FALSE) || \
165 (CH_LICENSE_FEATURES == CH_FEATURES_INTERMEDIATE) || \
166 (CH_LICENSE_FEATURES == CH_FEATURES_BASIC)
167
168/* Restricted subsystems.*/
169#undef CH_CFG_USE_FACTORY
170
171#define CH_CFG_USE_FACTORY FALSE
172
173#endif /* (CH_CUSTOMER_LIC_OSLIB == FALSE) ||
174 (CH_LICENSE_FEATURES == CH_FEATURES_INTERMEDIATE) ||
175 (CH_LICENSE_FEATURES == CH_FEATURES_BASIC) */
176
177/* Restrictions in basic mode.*/
178#if (CH_CUSTOMER_LIC_OSLIB == FALSE) || \
179 (CH_LICENSE_FEATURES == CH_FEATURES_BASIC)
180
181/* Restricted subsystems.*/
182#undef CH_CFG_USE_HEAP
183#undef CH_CFG_USE_MEMPOOLS
184#undef CH_CFG_USE_OBJ_FIFOS
185#undef CH_CFG_USE_PIPES
186#undef CH_CFG_USE_OBJ_CACHES
187#undef CH_CFG_USE_DELEGATES
188#undef CH_CFG_USE_JOBS
189
190#define CH_CFG_USE_HEAP FALSE
191#define CH_CFG_USE_MEMPOOLS FALSE
192#define CH_CFG_USE_OBJ_FIFOS FALSE
193#define CH_CFG_USE_PIPES FALSE
194#define CH_CFG_USE_OBJ_CACHES FALSE
195#define CH_CFG_USE_DELEGATES FALSE
196#define CH_CFG_USE_JOBS FALSE
197
198#endif /* (CH_CUSTOMER_LIC_OSLIB == FALSE) ||
199 (CH_LICENSE_FEATURES == CH_FEATURES_BASIC) */
200
201/* Restrictions in unlicensed mode.*/
202#if (CH_CUSTOMER_LIC_OSLIB == FALSE)
203
204/* Restricted subsystems.*/
205#undef CH_CFG_USE_MAILBOXES
206
207#define CH_CFG_USE_MAILBOXES FALSE
208
209#endif /* CH_CUSTOMER_LIC_OSLIB == FALSE */
210
211/*===========================================================================*/
212/* Module data structures and types. */
213/*===========================================================================*/
214
215/*===========================================================================*/
216/* Module macros. */
217/*===========================================================================*/
218
219/*===========================================================================*/
220/* External declarations. */
221/*===========================================================================*/
222
223/*===========================================================================*/
224/* Late inclusions. */
225/*===========================================================================*/
226
227/* OS Library headers.*/
228#include "chbsem.h"
229#include "chmboxes.h"
230#include "chmemcore.h"
231#include "chmemheaps.h"
232#include "chmempools.h"
233#include "chobjfifos.h"
234#include "chpipes.h"
235#include "chobjcaches.h"
236#include "chdelegates.h"
237#include "chjobs.h"
238#include "chfactory.h"
239
240/*===========================================================================*/
241/* Module inline functions. */
242/*===========================================================================*/
243
244/**
245 * @brief Initialization of all library modules.
246 *
247 * @notapi
248 */
249static inline void _oslib_init(void) {
250
251#if CH_CFG_USE_MEMCORE == TRUE
252 _core_init();
253#endif
254#if CH_CFG_USE_HEAP == TRUE
255 _heap_init();
256#endif
257#if CH_CFG_USE_FACTORY == TRUE
258 _factory_init();
259#endif
260}
261
262#endif /* CHLIB_H */
263
264/** @} */
diff --git a/lib/chibios/os/oslib/include/chmboxes.h b/lib/chibios/os/oslib/include/chmboxes.h
new file mode 100644
index 000000000..d925f219e
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chmboxes.h
@@ -0,0 +1,209 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chmboxes.h
22 * @brief Mailboxes macros and structures.
23 *
24 * @addtogroup oslib_mailboxes
25 * @{
26 */
27
28#ifndef CHMBOXES_H
29#define CHMBOXES_H
30
31#if (CH_CFG_USE_MAILBOXES == TRUE) || defined(__DOXYGEN__)
32
33/*===========================================================================*/
34/* Module constants. */
35/*===========================================================================*/
36
37/*===========================================================================*/
38/* Module pre-compile time settings. */
39/*===========================================================================*/
40
41/*===========================================================================*/
42/* Derived constants and error checks. */
43/*===========================================================================*/
44
45/*===========================================================================*/
46/* Module data structures and types. */
47/*===========================================================================*/
48
49/**
50 * @brief Structure representing a mailbox object.
51 */
52typedef struct {
53 msg_t *buffer; /**< @brief Pointer to the mailbox
54 buffer. */
55 msg_t *top; /**< @brief Pointer to the location
56 after the buffer. */
57 msg_t *wrptr; /**< @brief Write pointer. */
58 msg_t *rdptr; /**< @brief Read pointer. */
59 size_t cnt; /**< @brief Messages in queue. */
60 bool reset; /**< @brief True in reset state. */
61 threads_queue_t qw; /**< @brief Queued writers. */
62 threads_queue_t qr; /**< @brief Queued readers. */
63} mailbox_t;
64
65/*===========================================================================*/
66/* Module macros. */
67/*===========================================================================*/
68
69/**
70 * @brief Data part of a static mailbox initializer.
71 * @details This macro should be used when statically initializing a
72 * mailbox that is part of a bigger structure.
73 *
74 * @param[in] name the name of the mailbox variable
75 * @param[in] buffer pointer to the mailbox buffer array of @p msg_t
76 * @param[in] size number of @p msg_t elements in the buffer array
77 */
78#define _MAILBOX_DATA(name, buffer, size) { \
79 (msg_t *)(buffer), \
80 (msg_t *)(buffer) + size, \
81 (msg_t *)(buffer), \
82 (msg_t *)(buffer), \
83 (size_t)0, \
84 false, \
85 _THREADS_QUEUE_DATA(name.qw), \
86 _THREADS_QUEUE_DATA(name.qr), \
87}
88
89/**
90 * @brief Static mailbox initializer.
91 * @details Statically initialized mailboxes require no explicit
92 * initialization using @p chMBObjectInit().
93 *
94 * @param[in] name the name of the mailbox variable
95 * @param[in] buffer pointer to the mailbox buffer array of @p msg_t
96 * @param[in] size number of @p msg_t elements in the buffer array
97 */
98#define MAILBOX_DECL(name, buffer, size) \
99 mailbox_t name = _MAILBOX_DATA(name, buffer, size)
100
101/*===========================================================================*/
102/* External declarations. */
103/*===========================================================================*/
104
105#ifdef __cplusplus
106extern "C" {
107#endif
108 void chMBObjectInit(mailbox_t *mbp, msg_t *buf, size_t n);
109 void chMBReset(mailbox_t *mbp);
110 void chMBResetI(mailbox_t *mbp);
111 msg_t chMBPostTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout);
112 msg_t chMBPostTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout);
113 msg_t chMBPostI(mailbox_t *mbp, msg_t msg);
114 msg_t chMBPostAheadTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout);
115 msg_t chMBPostAheadTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout);
116 msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg);
117 msg_t chMBFetchTimeout(mailbox_t *mbp, msg_t *msgp, sysinterval_t timeout);
118 msg_t chMBFetchTimeoutS(mailbox_t *mbp, msg_t *msgp, sysinterval_t timeout);
119 msg_t chMBFetchI(mailbox_t *mbp, msg_t *msgp);
120#ifdef __cplusplus
121}
122#endif
123
124/*===========================================================================*/
125/* Module inline functions. */
126/*===========================================================================*/
127
128/**
129 * @brief Returns the mailbox buffer size as number of messages.
130 *
131 * @param[in] mbp the pointer to an initialized @p mailbox_t object
132 * @return The size of the mailbox.
133 *
134 * @iclass
135 */
136static inline size_t chMBGetSizeI(const mailbox_t *mbp) {
137
138 /*lint -save -e9033 [10.8] Perfectly safe pointers
139 arithmetic.*/
140 return (size_t)(mbp->top - mbp->buffer);
141 /*lint -restore*/
142}
143
144/**
145 * @brief Returns the number of used message slots into a mailbox.
146 *
147 * @param[in] mbp the pointer to an initialized @p mailbox_t object
148 * @return The number of queued messages.
149 *
150 * @iclass
151 */
152static inline size_t chMBGetUsedCountI(const mailbox_t *mbp) {
153
154 chDbgCheckClassI();
155
156 return mbp->cnt;
157}
158
159/**
160 * @brief Returns the number of free message slots into a mailbox.
161 *
162 * @param[in] mbp the pointer to an initialized @p mailbox_t object
163 * @return The number of empty message slots.
164 *
165 * @iclass
166 */
167static inline size_t chMBGetFreeCountI(const mailbox_t *mbp) {
168
169 chDbgCheckClassI();
170
171 return chMBGetSizeI(mbp) - chMBGetUsedCountI(mbp);
172}
173
174/**
175 * @brief Returns the next message in the queue without removing it.
176 * @pre A message must be waiting in the queue for this function to work
177 * or it would return garbage. The correct way to use this macro is
178 * to use @p chMBGetUsedCountI() and then use this macro, all within
179 * a lock state.
180 *
181 * @param[in] mbp the pointer to an initialized @p mailbox_t object
182 * @return The next message in queue.
183 *
184 * @iclass
185 */
186static inline msg_t chMBPeekI(const mailbox_t *mbp) {
187
188 chDbgCheckClassI();
189
190 return *mbp->rdptr;
191}
192
193/**
194 * @brief Terminates the reset state.
195 *
196 * @param[in] mbp the pointer to an initialized @p mailbox_t object
197 *
198 * @xclass
199 */
200static inline void chMBResumeX(mailbox_t *mbp) {
201
202 mbp->reset = false;
203}
204
205#endif /* CH_CFG_USE_MAILBOXES == TRUE */
206
207#endif /* CHMBOXES_H */
208
209/** @} */
diff --git a/lib/chibios/os/oslib/include/chmemcore.h b/lib/chibios/os/oslib/include/chmemcore.h
new file mode 100644
index 000000000..4004f70b7
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chmemcore.h
@@ -0,0 +1,211 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chmemcore.h
22 * @brief Core memory manager macros and structures.
23 *
24 * @addtogroup oslib_memcore
25 * @{
26 */
27
28#ifndef CHMEMCORE_H
29#define CHMEMCORE_H
30
31#if (CH_CFG_USE_MEMCORE == TRUE) || defined(__DOXYGEN__)
32
33/*===========================================================================*/
34/* Module constants. */
35/*===========================================================================*/
36
37/*===========================================================================*/
38/* Module pre-compile time settings. */
39/*===========================================================================*/
40
41/**
42 * @brief Managed RAM size.
43 * @details Size of the RAM area to be managed by the OS. If set to zero
44 * then the whole available RAM is used. The core memory is made
45 * available to the heap allocator and/or can be used directly through
46 * the simplified core memory allocator.
47 *
48 * @note In order to let the OS manage the whole RAM the linker script must
49 * provide the @p __heap_base__ and @p __heap_end__ symbols.
50 * @note Requires @p CH_CFG_USE_MEMCORE.
51 */
52#if !defined(CH_CFG_MEMCORE_SIZE) || defined(__DOXYGEN__)
53#define CH_CFG_MEMCORE_SIZE 0
54#endif
55
56/*===========================================================================*/
57/* Derived constants and error checks. */
58/*===========================================================================*/
59
60#if CH_CFG_MEMCORE_SIZE < 0
61#error "invalid CH_CFG_MEMCORE_SIZE value specified"
62#endif
63
64/*===========================================================================*/
65/* Module data structures and types. */
66/*===========================================================================*/
67
68/**
69 * @brief Memory get function.
70 */
71typedef void *(*memgetfunc_t)(size_t size, unsigned align);
72
73/**
74 * @brief Enhanced memory get function.
75 */
76typedef void *(*memgetfunc2_t)(size_t size, unsigned align, size_t offset);
77
78/**
79 * @brief Type of memory core object.
80 */
81typedef struct {
82 /**
83 * @brief Next free address.
84 */
85 uint8_t *basemem;
86 /**
87 * @brief Final address.
88 */
89 uint8_t *topmem;
90} memcore_t;
91
92/*===========================================================================*/
93/* Module macros. */
94/*===========================================================================*/
95
96/**
97 * @brief Allocates a memory block.
98 * @note This is a generic form with unspecified allocation position.
99 *
100 * @iclass
101 */
102#define chCoreAllocAlignedWithOffsetI chCoreAllocFromTopI
103
104/**
105 * @brief Allocates a memory block.
106 * @note This is a generic form with unspecified allocation position.
107 *
108 * @api
109 */
110#define chCoreAllocAlignedWithOffset chCoreAllocFromTop
111
112/*===========================================================================*/
113/* External declarations. */
114/*===========================================================================*/
115
116#if !defined(__DOXYGEN__)
117extern memcore_t ch_memcore;
118#endif
119
120#ifdef __cplusplus
121extern "C" {
122#endif
123 void _core_init(void);
124 void *chCoreAllocFromBaseI(size_t size, unsigned align, size_t offset);
125 void *chCoreAllocFromTopI(size_t size, unsigned align, size_t offset);
126 void *chCoreAllocFromBase(size_t size, unsigned align, size_t offset);
127 void *chCoreAllocFromTop(size_t size, unsigned align, size_t offset);
128 size_t chCoreGetStatusX(void);
129#ifdef __cplusplus
130}
131#endif
132
133/*===========================================================================*/
134/* Module inline functions. */
135/*===========================================================================*/
136
137/**
138 * @brief Allocates a memory block.
139 * @details The allocated block is guaranteed to be properly aligned to the
140 * specified alignment.
141 * @note This is a generic form with unspecified allocation position.
142 *
143 * @param[in] size the size of the block to be allocated.
144 * @param[in] align desired memory alignment
145 * @return A pointer to the allocated memory block.
146 * @retval NULL allocation failed, core memory exhausted.
147 *
148 * @iclass
149 */
150static inline void *chCoreAllocAlignedI(size_t size, unsigned align) {
151
152 return chCoreAllocAlignedWithOffsetI(size, align, 0U);
153}
154
155/**
156 * @brief Allocates a memory block.
157 * @details The allocated block is guaranteed to be properly aligned to the
158 * specified alignment.
159 * @note This is a generic form with unspecified allocation position.
160 *
161 * @param[in] size the size of the block to be allocated
162 * @param[in] align desired memory alignment
163 * @return A pointer to the allocated memory block.
164 * @retval NULL allocation failed, core memory exhausted.
165 *
166 * @api
167 */
168static inline void *chCoreAllocAligned(size_t size, unsigned align) {
169
170 return chCoreAllocAlignedWithOffset(size, align, 0U);
171}
172
173/**
174 * @brief Allocates a memory block.
175 * @details The allocated block is guaranteed to be properly aligned for a
176 * pointer data type.
177 * @note This is a generic form with unspecified allocation position.
178 *
179 * @param[in] size the size of the block to be allocated.
180 * @return A pointer to the allocated memory block.
181 * @retval NULL allocation failed, core memory exhausted.
182 *
183 * @iclass
184 */
185static inline void *chCoreAllocI(size_t size) {
186
187 return chCoreAllocAlignedWithOffsetI(size, PORT_NATURAL_ALIGN, 0U);
188}
189
190/**
191 * @brief Allocates a memory block.
192 * @details The allocated block is guaranteed to be properly aligned for a
193 * pointer data type.
194 * @note This is a generic form with unspecified allocation position.
195 *
196 * @param[in] size the size of the block to be allocated.
197 * @return A pointer to the allocated memory block.
198 * @retval NULL allocation failed, core memory exhausted.
199 *
200 * @api
201 */
202static inline void *chCoreAlloc(size_t size) {
203
204 return chCoreAllocAlignedWithOffset(size, PORT_NATURAL_ALIGN, 0U);
205}
206
207#endif /* CH_CFG_USE_MEMCORE == TRUE */
208
209#endif /* CHMEMCORE_H */
210
211/** @} */
diff --git a/lib/chibios/os/oslib/include/chmemheaps.h b/lib/chibios/os/oslib/include/chmemheaps.h
new file mode 100644
index 000000000..c0c4b97e0
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chmemheaps.h
@@ -0,0 +1,178 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chmemheaps.h
22 * @brief Memory heaps macros and structures.
23 *
24 * @addtogroup oslib_memheaps
25 * @{
26 */
27
28#ifndef CHMEMHEAPS_H
29#define CHMEMHEAPS_H
30
31#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__)
32
33/*===========================================================================*/
34/* Module constants. */
35/*===========================================================================*/
36
37/**
38 * @brief Minimum alignment used for heap.
39 * @note Cannot use the sizeof operator in this macro.
40 */
41#if (SIZEOF_PTR == 4) || defined(__DOXYGEN__)
42#define CH_HEAP_ALIGNMENT 8U
43#elif (SIZEOF_PTR == 2)
44#define CH_HEAP_ALIGNMENT 4U
45#else
46#error "unsupported pointer size"
47#endif
48
49/*===========================================================================*/
50/* Module pre-compile time settings. */
51/*===========================================================================*/
52
53/*===========================================================================*/
54/* Derived constants and error checks. */
55/*===========================================================================*/
56
57#if CH_CFG_USE_MEMCORE == FALSE
58#error "CH_CFG_USE_HEAP requires CH_CFG_USE_MEMCORE"
59#endif
60
61#if (CH_CFG_USE_MUTEXES == FALSE) && (CH_CFG_USE_SEMAPHORES == FALSE)
62#error "CH_CFG_USE_HEAP requires CH_CFG_USE_MUTEXES and/or CH_CFG_USE_SEMAPHORES"
63#endif
64
65/*===========================================================================*/
66/* Module data structures and types. */
67/*===========================================================================*/
68
69/**
70 * @brief Type of a memory heap.
71 */
72typedef struct memory_heap memory_heap_t;
73
74/**
75 * @brief Type of a memory heap header.
76 */
77typedef union heap_header heap_header_t;
78
79/**
80 * @brief Memory heap block header.
81 */
82union heap_header {
83 struct {
84 heap_header_t *next; /**< @brief Next block in free list. */
85 size_t pages; /**< @brief Size of the area in pages. */
86 } free;
87 struct {
88 memory_heap_t *heap; /**< @brief Block owner heap. */
89 size_t size; /**< @brief Size of the area in bytes. */
90 } used;
91};
92
93/**
94 * @brief Structure describing a memory heap.
95 */
96struct memory_heap {
97 memgetfunc2_t provider; /**< @brief Memory blocks provider for
98 this heap. */
99 heap_header_t header; /**< @brief Free blocks list header. */
100#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
101 mutex_t mtx; /**< @brief Heap access mutex. */
102#else
103 semaphore_t sem; /**< @brief Heap access semaphore. */
104#endif
105};
106
107/*===========================================================================*/
108/* Module macros. */
109/*===========================================================================*/
110
111/**
112 * @brief Allocation of an aligned static heap buffer.
113 */
114#define CH_HEAP_AREA(name, size) \
115 ALIGNED_VAR(CH_HEAP_ALIGNMENT) \
116 uint8_t name[MEM_ALIGN_NEXT((size), CH_HEAP_ALIGNMENT)]
117
118/*===========================================================================*/
119/* External declarations. */
120/*===========================================================================*/
121
122#ifdef __cplusplus
123extern "C" {
124#endif
125 void _heap_init(void);
126 void chHeapObjectInit(memory_heap_t *heapp, void *buf, size_t size);
127 void *chHeapAllocAligned(memory_heap_t *heapp, size_t size, unsigned align);
128 void chHeapFree(void *p);
129 size_t chHeapStatus(memory_heap_t *heapp, size_t *totalp, size_t *largestp);
130#ifdef __cplusplus
131}
132#endif
133
134/*===========================================================================*/
135/* Module inline functions. */
136/*===========================================================================*/
137
138/**
139 * @brief Allocates a block of memory from the heap by using the first-fit
140 * algorithm.
141 * @details The allocated block is guaranteed to be properly aligned for a
142 * pointer data type.
143 *
144 * @param[in] heapp pointer to a heap descriptor or @p NULL in order to
145 * access the default heap.
146 * @param[in] size the size of the block to be allocated. Note that the
147 * allocated block may be a bit bigger than the requested
148 * size for alignment and fragmentation reasons.
149 * @return A pointer to the allocated block.
150 * @retval NULL if the block cannot be allocated.
151 *
152 * @api
153 */
154static inline void *chHeapAlloc(memory_heap_t *heapp, size_t size) {
155
156 return chHeapAllocAligned(heapp, size, CH_HEAP_ALIGNMENT);
157}
158
159/**
160 * @brief Returns the size of an allocated block.
161 * @note The returned value is the requested size, the real size is the
162 * same value aligned to the next @p CH_HEAP_ALIGNMENT multiple.
163 *
164 * @param[in] p pointer to the memory block
165 * @return Size of the block.
166 *
167 * @api
168 */
169static inline size_t chHeapGetSize(const void *p) {
170
171 return ((heap_header_t *)p - 1U)->used.size;
172}
173
174#endif /* CH_CFG_USE_HEAP == TRUE */
175
176#endif /* CHMEMHEAPS_H */
177
178/** @} */
diff --git a/lib/chibios/os/oslib/include/chmempools.h b/lib/chibios/os/oslib/include/chmempools.h
new file mode 100644
index 000000000..52f78e004
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chmempools.h
@@ -0,0 +1,385 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chmempools.h
22 * @brief Memory Pools macros and structures.
23 *
24 * @addtogroup oslib_mempools
25 * @{
26 */
27
28#ifndef CHMEMPOOLS_H
29#define CHMEMPOOLS_H
30
31#if (CH_CFG_USE_MEMPOOLS == TRUE) || defined(__DOXYGEN__)
32
33/*===========================================================================*/
34/* Module constants. */
35/*===========================================================================*/
36
37/*===========================================================================*/
38/* Module pre-compile time settings. */
39/*===========================================================================*/
40
41/*===========================================================================*/
42/* Derived constants and error checks. */
43/*===========================================================================*/
44
45#if CH_CFG_USE_MEMCORE == FALSE
46#error "CH_CFG_USE_MEMPOOLS requires CH_CFG_USE_MEMCORE"
47#endif
48
49/*===========================================================================*/
50/* Module data structures and types. */
51/*===========================================================================*/
52
53/**
54 * @brief Memory pool free object header.
55 */
56struct pool_header {
57 struct pool_header *next; /**< @brief Pointer to the next pool
58 header in the list. */
59};
60
61/**
62 * @brief Memory pool descriptor.
63 */
64typedef struct {
65 struct pool_header *next; /**< @brief Pointer to the header. */
66 size_t object_size; /**< @brief Memory pool objects
67 size. */
68 unsigned align; /**< @brief Required alignment. */
69 memgetfunc_t provider; /**< @brief Memory blocks provider
70 for this pool. */
71} memory_pool_t;
72
73#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
74/**
75 * @brief Guarded memory pool descriptor.
76 */
77typedef struct {
78 semaphore_t sem; /**< @brief Counter semaphore guarding
79 the memory pool. */
80 memory_pool_t pool; /**< @brief The memory pool itself. */
81} guarded_memory_pool_t;
82#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
83
84/*===========================================================================*/
85/* Module macros. */
86/*===========================================================================*/
87
88/**
89 * @brief Data part of a static memory pool initializer.
90 * @details This macro should be used when statically initializing a
91 * memory pool that is part of a bigger structure.
92 *
93 * @param[in] name the name of the memory pool variable
94 * @param[in] size size of the memory pool contained objects
95 * @param[in] align required memory alignment
96 * @param[in] provider memory provider function for the memory pool
97 */
98#define _MEMORYPOOL_DATA(name, size, align, provider) \
99 {NULL, size, align, provider}
100
101/**
102 * @brief Static memory pool initializer.
103 * @details Statically initialized memory pools require no explicit
104 * initialization using @p chPoolInit().
105 *
106 * @param[in] name the name of the memory pool variable
107 * @param[in] size size of the memory pool contained objects
108 * @param[in] align required memory alignment
109 * @param[in] provider memory provider function for the memory pool or @p NULL
110 * if the pool is not allowed to grow automatically
111 */
112#define MEMORYPOOL_DECL(name, size, align, provider) \
113 memory_pool_t name = _MEMORYPOOL_DATA(name, size, align, provider)
114
115#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
116/**
117 * @brief Data part of a static guarded memory pool initializer.
118 * @details This macro should be used when statically initializing a
119 * memory pool that is part of a bigger structure.
120 *
121 * @param[in] name the name of the memory pool variable
122 * @param[in] size size of the memory pool contained objects
123 * @param[in] align required memory alignment
124 */
125#define _GUARDEDMEMORYPOOL_DATA(name, size, align) { \
126 _SEMAPHORE_DATA(name.sem, (cnt_t)0), \
127 _MEMORYPOOL_DATA(NULL, size, align, NULL) \
128}
129
130/**
131 * @brief Static guarded memory pool initializer.
132 * @details Statically initialized guarded memory pools require no explicit
133 * initialization using @p chGuardedPoolInit().
134 *
135 * @param[in] name the name of the guarded memory pool variable
136 * @param[in] size size of the memory pool contained objects
137 * @param[in] align required memory alignment
138 */
139#define GUARDEDMEMORYPOOL_DECL(name, size, align) \
140 guarded_memory_pool_t name = _GUARDEDMEMORYPOOL_DATA(name, size, align)
141#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
142
143/*===========================================================================*/
144/* External declarations. */
145/*===========================================================================*/
146
147#ifdef __cplusplus
148extern "C" {
149#endif
150 void chPoolObjectInitAligned(memory_pool_t *mp, size_t size,
151 unsigned align, memgetfunc_t provider);
152 void chPoolLoadArray(memory_pool_t *mp, void *p, size_t n);
153 void *chPoolAllocI(memory_pool_t *mp);
154 void *chPoolAlloc(memory_pool_t *mp);
155 void chPoolFreeI(memory_pool_t *mp, void *objp);
156 void chPoolFree(memory_pool_t *mp, void *objp);
157#if CH_CFG_USE_SEMAPHORES == TRUE
158 void chGuardedPoolObjectInitAligned(guarded_memory_pool_t *gmp,
159 size_t size,
160 unsigned align);
161 void chGuardedPoolLoadArray(guarded_memory_pool_t *gmp, void *p, size_t n);
162 void *chGuardedPoolAllocTimeoutS(guarded_memory_pool_t *gmp,
163 sysinterval_t timeout);
164 void *chGuardedPoolAllocTimeout(guarded_memory_pool_t *gmp,
165 sysinterval_t timeout);
166 void chGuardedPoolFree(guarded_memory_pool_t *gmp, void *objp);
167#endif
168#ifdef __cplusplus
169}
170#endif
171
172/*===========================================================================*/
173/* Module inline functions. */
174/*===========================================================================*/
175
176/**
177 * @brief Initializes an empty memory pool.
178 *
179 * @param[out] mp pointer to a @p memory_pool_t structure
180 * @param[in] size the size of the objects contained in this memory pool,
181 * the minimum accepted size is the size of a pointer to
182 * void.
183 * @param[in] provider memory provider function for the memory pool or
184 * @p NULL if the pool is not allowed to grow
185 * automatically
186 *
187 * @init
188 */
189static inline void chPoolObjectInit(memory_pool_t *mp,
190 size_t size,
191 memgetfunc_t provider) {
192
193 chPoolObjectInitAligned(mp, size, PORT_NATURAL_ALIGN, provider);
194}
195
196/**
197 * @brief Adds an object to a memory pool.
198 * @pre The memory pool must be already been initialized.
199 * @pre The added object must be of the right size for the specified
200 * memory pool.
201 * @pre The added object must be properly aligned.
202 * @note This function is just an alias for @p chPoolFree() and has been
203 * added for clarity.
204 *
205 * @param[in] mp pointer to a @p memory_pool_t structure
206 * @param[in] objp the pointer to the object to be added
207 *
208 * @api
209 */
210static inline void chPoolAdd(memory_pool_t *mp, void *objp) {
211
212 chPoolFree(mp, objp);
213}
214
215/**
216 * @brief Adds an object to a memory pool.
217 * @pre The memory pool must be already been initialized.
218 * @pre The added object must be of the right size for the specified
219 * memory pool.
220 * @pre The added object must be properly aligned.
221 * @note This function is just an alias for @p chPoolFreeI() and has been
222 * added for clarity.
223 *
224 * @param[in] mp pointer to a @p memory_pool_t structure
225 * @param[in] objp the pointer to the object to be added
226 *
227 * @iclass
228 */
229static inline void chPoolAddI(memory_pool_t *mp, void *objp) {
230
231 chPoolFreeI(mp, objp);
232}
233
234#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
235/**
236 * @brief Initializes an empty guarded memory pool.
237 *
238 * @param[out] gmp pointer to a @p guarded_memory_pool_t structure
239 * @param[in] size the size of the objects contained in this guarded
240 * memory pool, the minimum accepted size is the size
241 * of a pointer to void.
242 *
243 * @init
244 */
245static inline void chGuardedPoolObjectInit(guarded_memory_pool_t *gmp,
246 size_t size) {
247
248 chGuardedPoolObjectInitAligned(gmp, size, PORT_NATURAL_ALIGN);
249}
250
251/**
252 * @brief Gets the count of objects in a guarded memory pool.
253 * @pre The guarded memory pool must be already been initialized.
254 *
255 * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
256 * @return The counter of the guard semaphore.
257 *
258 * @iclass
259 */
260static inline cnt_t chGuardedPoolGetCounterI(guarded_memory_pool_t *gmp) {
261
262 return chSemGetCounterI(&gmp->sem);
263}
264
265/**
266 * @brief Allocates an object from a guarded memory pool.
267 * @pre The guarded memory pool must be already been initialized.
268 *
269 * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
270 * @return The pointer to the allocated object.
271 * @retval NULL if the pool is empty.
272 *
273 * @iclass
274 */
275static inline void *chGuardedPoolAllocI(guarded_memory_pool_t *gmp) {
276 void *p;
277
278 p = chPoolAllocI(&gmp->pool);
279 if (p != NULL) {
280 chSemFastWaitI(&gmp->sem);
281 chDbgAssert(chSemGetCounterI(&gmp->sem) >= (cnt_t)0,
282 "semaphore out of sync");
283 }
284 return p;
285}
286
287/**
288 * @brief Releases an object into a guarded memory pool.
289 * @pre The guarded memory pool must already be initialized.
290 * @pre The freed object must be of the right size for the specified
291 * guarded memory pool.
292 * @pre The added object must be properly aligned.
293 *
294 * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
295 * @param[in] objp the pointer to the object to be released
296 *
297 * @iclass
298 */
299static inline void chGuardedPoolFreeI(guarded_memory_pool_t *gmp, void *objp) {
300
301 chPoolFreeI(&gmp->pool, objp);
302 chSemSignalI(&gmp->sem);
303}
304
305/**
306 * @brief Releases an object into a guarded memory pool.
307 * @pre The guarded memory pool must already be initialized.
308 * @pre The freed object must be of the right size for the specified
309 * guarded memory pool.
310 * @pre The added object must be properly aligned.
311 *
312 * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
313 * @param[in] objp the pointer to the object to be released
314 *
315 * @sclass
316 */
317static inline void chGuardedPoolFreeS(guarded_memory_pool_t *gmp, void *objp) {
318
319 chGuardedPoolFreeI(gmp, objp);
320 chSchRescheduleS();
321}
322
323/**
324 * @brief Adds an object to a guarded memory pool.
325 * @pre The guarded memory pool must be already been initialized.
326 * @pre The added object must be of the right size for the specified
327 * guarded memory pool.
328 * @pre The added object must be properly aligned.
329 * @note This function is just an alias for @p chGuardedPoolFree() and
330 * has been added for clarity.
331 *
332 * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
333 * @param[in] objp the pointer to the object to be added
334 *
335 * @api
336 */
337static inline void chGuardedPoolAdd(guarded_memory_pool_t *gmp, void *objp) {
338
339 chGuardedPoolFree(gmp, objp);
340}
341
342/**
343 * @brief Adds an object to a guarded memory pool.
344 * @pre The guarded memory pool must be already been initialized.
345 * @pre The added object must be of the right size for the specified
346 * guarded memory pool.
347 * @pre The added object must be properly aligned.
348 * @note This function is just an alias for @p chGuardedPoolFreeI() and
349 * has been added for clarity.
350 *
351 * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
352 * @param[in] objp the pointer to the object to be added
353 *
354 * @iclass
355 */
356static inline void chGuardedPoolAddI(guarded_memory_pool_t *gmp, void *objp) {
357
358 chGuardedPoolFreeI(gmp, objp);
359}
360
361/**
362 * @brief Adds an object to a guarded memory pool.
363 * @pre The guarded memory pool must be already been initialized.
364 * @pre The added object must be of the right size for the specified
365 * guarded memory pool.
366 * @pre The added object must be properly aligned.
367 * @note This function is just an alias for @p chGuardedPoolFreeI() and
368 * has been added for clarity.
369 *
370 * @param[in] gmp pointer to a @p guarded_memory_pool_t structure
371 * @param[in] objp the pointer to the object to be added
372 *
373 * @sclass
374 */
375static inline void chGuardedPoolAddS(guarded_memory_pool_t *gmp, void *objp) {
376
377 chGuardedPoolFreeS(gmp, objp);
378}
379#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
380
381#endif /* CH_CFG_USE_MEMPOOLS == TRUE */
382
383#endif /* CHMEMPOOLS_H */
384
385/** @} */
diff --git a/lib/chibios/os/oslib/include/chobjcaches.h b/lib/chibios/os/oslib/include/chobjcaches.h
new file mode 100644
index 000000000..9d8768e21
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chobjcaches.h
@@ -0,0 +1,304 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chobjcaches.h
22 * @brief Objects Caches macros and structures.
23 *
24 * @addtogroup oslib_objchaches
25 * @{
26 */
27
28#ifndef CHOBJCACHES_H
29#define CHOBJCACHES_H
30
31#if (CH_CFG_USE_OBJ_CACHES == TRUE) || defined(__DOXYGEN__)
32
33/*===========================================================================*/
34/* Module constants. */
35/*===========================================================================*/
36
37/**
38 * @name Cached objects flags
39 * @{
40 */
41#define OC_FLAG_INLRU 0x00000001U
42#define OC_FLAG_INHASH 0x00000002U
43#define OC_FLAG_SHARED 0x00000004U
44#define OC_FLAG_NOTSYNC 0x00000008U
45#define OC_FLAG_LAZYWRITE 0x00000010U
46#define OC_FLAG_FORGET 0x00000020U
47/** @} */
48
49/*===========================================================================*/
50/* Module pre-compile time settings. */
51/*===========================================================================*/
52
53/*===========================================================================*/
54/* Derived constants and error checks. */
55/*===========================================================================*/
56
57/*===========================================================================*/
58/* Module data structures and types. */
59/*===========================================================================*/
60
61/**
62 * @brief Flags of cached objects.
63 */
64typedef uint32_t oc_flags_t;
65
66/**
67 * @brief Type of an hash element header.
68 */
69typedef struct ch_oc_hash_header oc_hash_header_t;
70
71/**
72 * @brief Type of an LRU element header.
73 */
74typedef struct ch_oc_lru_header oc_lru_header_t;
75
76/**
77 * @brief Type of a cached object.
78 */
79typedef struct ch_oc_object oc_object_t;
80
81/**
82 * @brief Type of a cache object.
83 */
84typedef struct ch_objects_cache objects_cache_t;
85
86/**
87 * @brief Object read function.
88 *
89 * @param[in] ocp pointer to the @p objects_cache_t structure
90 * @param[in] async requests an asynchronous operation if supported, the
91 * function is then responsible for releasing the
92 * object
93 */
94typedef bool (*oc_readf_t)(objects_cache_t *ocp,
95 oc_object_t *objp,
96 bool async);
97
98/**
99 * @brief Object write function.
100 *
101 * @param[in] ocp pointer to the @p objects_cache_t structure
102 * @param[in] async requests an asynchronous operation if supported, the
103 * function is then responsible for releasing the
104 * object
105 */
106typedef bool (*oc_writef_t)(objects_cache_t *ocp,
107 oc_object_t *objp,
108 bool async);
109
110/**
111 * @brief Structure representing an hash table element.
112 */
113struct ch_oc_hash_header {
114 /**
115 * @brief Next in the collisions list.
116 */
117 oc_object_t *hash_next;
118 /**
119 * @brief Previous in the collisions list.
120 */
121 oc_object_t *hash_prev;
122};
123
124/**
125 * @brief Structure representing an hash table element.
126 */
127struct ch_oc_lru_header {
128 /**
129 * @brief Next in the collisions list.
130 */
131 oc_object_t *hash_next;
132 /**
133 * @brief Previous in the collisions list.
134 */
135 oc_object_t *hash_prev;
136 /**
137 * @brief Next in the LRU list.
138 */
139 oc_object_t *lru_next;
140 /**
141 * @brief Previous in the LRU list.
142 */
143 oc_object_t *lru_prev;
144};
145
146/**
147 * @brief Structure representing a cached object.
148 */
149struct ch_oc_object {
150 /**
151 * @brief Next in the collisions list.
152 */
153 oc_object_t *hash_next;
154 /**
155 * @brief Previous in the collisions list.
156 */
157 oc_object_t *hash_prev;
158 /**
159 * @brief Next in the LRU list.
160 */
161 oc_object_t *lru_next;
162 /**
163 * @brief Previous in the LRU list.
164 */
165 oc_object_t *lru_prev;
166 /**
167 * @brief Object group.
168 */
169 uint32_t obj_group;
170 /**
171 * @brief Object key.
172 */
173 uint32_t obj_key;
174 /**
175 * @brief Semaphore for object access.
176 */
177 semaphore_t obj_sem;
178 /**
179 * @brief Object flags.
180 */
181 oc_flags_t obj_flags;
182 /**
183 * @brief User pointer.
184 * @note This pointer can be used to refer to external buffers,
185 * @p chCacheObjectInit() initializes it to @p NULL.
186 */
187 void *dptr;
188};
189
190/**
191 * @brief Structure representing a cache object.
192 */
193struct ch_objects_cache {
194 /**
195 * @brief Number of elements in the hash table.
196 */
197 ucnt_t hashn;
198 /**
199 * @brief Pointer to the hash table.
200 */
201 oc_hash_header_t *hashp;
202 /**
203 * @brief Number of elements in the objects table.
204 */
205 ucnt_t objn;
206 /**
207 * @brief Size of elements in the objects table.
208 */
209 size_t objsz;
210 /**
211 * @brief Pointer to the objects table.
212 */
213 void *objvp;
214 /**
215 * @brief LRU list header.
216 */
217 oc_lru_header_t lru;
218 /**
219 * @brief Semaphore for cache access.
220 */
221 semaphore_t cache_sem;
222 /**
223 * @brief Semaphore for LRU access.
224 */
225 semaphore_t lru_sem;
226 /**
227 * @brief Reader functions for cached objects.
228 */
229 oc_readf_t readf;
230 /**
231 * @brief Writer functions for cached objects.
232 */
233 oc_writef_t writef;
234};
235
236/*===========================================================================*/
237/* Module macros. */
238/*===========================================================================*/
239
240/*===========================================================================*/
241/* External declarations. */
242/*===========================================================================*/
243
244#ifdef __cplusplus
245extern "C" {
246#endif
247 void chCacheObjectInit(objects_cache_t *ocp,
248 ucnt_t hashn,
249 oc_hash_header_t *hashp,
250 ucnt_t objn,
251 size_t objsz,
252 void *objvp,
253 oc_readf_t readf,
254 oc_writef_t writef);
255 oc_object_t *chCacheGetObject(objects_cache_t *ocp,
256 uint32_t group,
257 uint32_t key);
258 void chCacheReleaseObjectI(objects_cache_t *ocp,
259 oc_object_t *objp);
260 bool chCacheReadObject(objects_cache_t *ocp,
261 oc_object_t *objp,
262 bool async);
263 bool chCacheWriteObject(objects_cache_t *ocp,
264 oc_object_t *objp,
265 bool async);
266#ifdef __cplusplus
267}
268#endif
269
270/*===========================================================================*/
271/* Module inline functions. */
272/*===========================================================================*/
273
274/**
275 * @brief Releases an object into the cache.
276 * @note This function gives a meaning to the following flags:
277 * - @p OC_FLAG_INLRU must be cleared.
278 * - @p OC_FLAG_INHASH must be set.
279 * - @p OC_FLAG_SHARED must be cleared.
280 * - @p OC_FLAG_NOTSYNC invalidates the object and queues it on
281 * the LRU tail.
282 * - @p OC_FLAG_LAZYWRITE is ignored and kept, a write will occur
283 * when the object is removed from the LRU list (lazy write).
284 * .
285 *
286 * @param[in] ocp pointer to the @p objects_cache_t structure
287 * @param[in] objp pointer to the @p oc_object_t structure
288 *
289 * @api
290 */
291static inline void chCacheReleaseObject(objects_cache_t *ocp,
292 oc_object_t *objp) {
293
294 chSysLock();
295 chCacheReleaseObjectI(ocp, objp);
296 chSchRescheduleS();
297 chSysUnlock();
298}
299
300#endif /* CH_CFG_USE_OBJ_CACHES == TRUE */
301
302#endif /* CHOBJCACHES_H */
303
304/** @} */
diff --git a/lib/chibios/os/oslib/include/chobjfifos.h b/lib/chibios/os/oslib/include/chobjfifos.h
new file mode 100644
index 000000000..56cec3634
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chobjfifos.h
@@ -0,0 +1,430 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chobjfifos.h
22 * @brief Objects FIFO structures and macros.
23 * @details This module implements a generic FIFO queue of objects by
24 * coupling a Guarded Memory Pool (for objects storage) and
25 * a MailBox.<br>
26 * On the sender side free objects are taken from the pool, filled
27 * and then sent to the receiver, on the receiver side objects are
28 * fetched, used and then returned to the pool.
29 * Operations defined for object FIFOs:
30 * - <b>Take</b>: An object is taken from the pool of the free
31 * objects, can be blocking.
32 * - <b>Return</b>: An object is returned to the pool of the
33 * free objects, it is guaranteed to be non-blocking.
34 * - <b>Send</b>: An object is sent through the mailbox, it is
35 * guaranteed to be non-blocking
36 * - <b>Receive</b>: An object is received from the mailbox,
37 * can be blocking.
38 * .
39 *
40 * @addtogroup oslib_objects_fifos
41 * @{
42 */
43
44#ifndef CHOBJFIFOS_H
45#define CHOBJFIFOS_H
46
47#if (CH_CFG_USE_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
48
49/*===========================================================================*/
50/* Module constants. */
51/*===========================================================================*/
52
53/*===========================================================================*/
54/* Module pre-compile time settings. */
55/*===========================================================================*/
56
57/*===========================================================================*/
58/* Derived constants and error checks. */
59/*===========================================================================*/
60
61#if CH_CFG_USE_MEMPOOLS == FALSE
62#error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_MEMPOOLS"
63#endif
64
65#if CH_CFG_USE_SEMAPHORES == FALSE
66#error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_SEMAPHORES"
67#endif
68
69#if CH_CFG_USE_MAILBOXES == FALSE
70#error "CH_CFG_USE_OBJ_FIFOS requires CH_CFG_USE_MAILBOXES"
71#endif
72
73/*===========================================================================*/
74/* Module data structures and types. */
75/*===========================================================================*/
76
77/**
78 * @brief Type of an objects FIFO.
79 */
80typedef struct ch_objects_fifo {
81 /**
82 * @brief Pool of the free objects.
83 */
84 guarded_memory_pool_t free;
85 /**
86 * @brief Mailbox of the sent objects.
87 */
88 mailbox_t mbx;
89} objects_fifo_t;
90
91/*===========================================================================*/
92/* Module macros. */
93/*===========================================================================*/
94
95/*===========================================================================*/
96/* External declarations. */
97/*===========================================================================*/
98
99#ifdef __cplusplus
100extern "C" {
101#endif
102
103#ifdef __cplusplus
104}
105#endif
106
107/*===========================================================================*/
108/* Module inline functions. */
109/*===========================================================================*/
110
111/**
112 * @brief Initializes a FIFO object.
113 * @pre The messages size must be a multiple of the alignment
114 * requirement.
115 *
116 * @param[out] ofp pointer to a @p objects_fifo_t structure
117 * @param[in] objsize size of objects
118 * @param[in] objn number of objects available
119 * @param[in] objalign required objects alignment
120 * @param[in] objbuf pointer to the buffer of objects, it must be able
121 * to hold @p objn objects of @p objsize size with
122 * @p objalign alignment
123 * @param[in] msgbuf pointer to the buffer of messages, it must be able
124 * to hold @p objn messages
125 *
126 * @init
127 */
128static inline void chFifoObjectInitAligned(objects_fifo_t *ofp, size_t objsize,
129 size_t objn, unsigned objalign,
130 void *objbuf, msg_t *msgbuf) {
131
132 chDbgCheck((objsize >= objalign) && ((objsize % objalign) == 0U));
133
134 chGuardedPoolObjectInitAligned(&ofp->free, objsize, objalign);
135 chGuardedPoolLoadArray(&ofp->free, objbuf, objn);
136 chMBObjectInit(&ofp->mbx, msgbuf, objn);
137}
138
139/**
140 * @brief Initializes a FIFO object.
141 * @pre The messages size must be a multiple of the alignment
142 * requirement.
143 *
144 * @param[out] ofp pointer to a @p objects_fifo_t structure
145 * @param[in] objsize size of objects
146 * @param[in] objn number of objects available
147 * @param[in] objbuf pointer to the buffer of objects, it must be able
148 * to hold @p objn objects of @p objsize size
149 * @param[in] msgbuf pointer to the buffer of messages, it must be able
150 * to hold @p objn messages
151 *
152 * @init
153 */
154static inline void chFifoObjectInit(objects_fifo_t *ofp, size_t objsize,
155 size_t objn, void *objbuf,
156 msg_t *msgbuf) {
157
158 chFifoObjectInitAligned(ofp, objsize, objn,
159 PORT_NATURAL_ALIGN,
160 objbuf, msgbuf);
161}
162
163/**
164 * @brief Allocates a free object.
165 *
166 * @param[in] ofp pointer to a @p objects_fifo_t structure
167 * @return The pointer to the allocated object.
168 * @retval NULL if an object is not immediately available.
169 *
170 * @iclass
171 */
172static inline void *chFifoTakeObjectI(objects_fifo_t *ofp) {
173
174 return chGuardedPoolAllocI(&ofp->free);
175}
176
177/**
178 * @brief Allocates a free object.
179 *
180 * @param[in] ofp pointer to a @p objects_fifo_t structure
181 * @param[in] timeout the number of ticks before the operation timeouts,
182 * the following special values are allowed:
183 * - @a TIME_IMMEDIATE immediate timeout.
184 * - @a TIME_INFINITE no timeout.
185 * .
186 * @return The pointer to the allocated object.
187 * @retval NULL if an object is not available within the specified
188 * timeout.
189 *
190 * @sclass
191 */
192static inline void *chFifoTakeObjectTimeoutS(objects_fifo_t *ofp,
193 sysinterval_t timeout) {
194
195 return chGuardedPoolAllocTimeoutS(&ofp->free, timeout);
196}
197
198/**
199 * @brief Allocates a free object.
200 *
201 * @param[in] ofp pointer to a @p objects_fifo_t structure
202 * @param[in] timeout the number of ticks before the operation timeouts,
203 * the following special values are allowed:
204 * - @a TIME_IMMEDIATE immediate timeout.
205 * - @a TIME_INFINITE no timeout.
206 * .
207 * @return The pointer to the allocated object.
208 * @retval NULL if an object is not available within the specified
209 * timeout.
210 *
211 * @api
212 */
213static inline void *chFifoTakeObjectTimeout(objects_fifo_t *ofp,
214 sysinterval_t timeout) {
215
216 return chGuardedPoolAllocTimeout(&ofp->free, timeout);
217}
218
219/**
220 * @brief Releases a fetched object.
221 *
222 * @param[in] ofp pointer to a @p objects_fifo_t structure
223 * @param[in] objp pointer to the object to be released
224 *
225 * @iclass
226 */
227static inline void chFifoReturnObjectI(objects_fifo_t *ofp,
228 void *objp) {
229
230 chGuardedPoolFreeI(&ofp->free, objp);
231}
232
233/**
234 * @brief Releases a fetched object.
235 *
236 * @param[in] ofp pointer to a @p objects_fifo_t structure
237 * @param[in] objp pointer to the object to be released
238 *
239 * @sclass
240 */
241static inline void chFifoReturnObjectS(objects_fifo_t *ofp,
242 void *objp) {
243
244 chGuardedPoolFreeS(&ofp->free, objp);
245}
246
247/**
248 * @brief Releases a fetched object.
249 *
250 * @param[in] ofp pointer to a @p objects_fifo_t structure
251 * @param[in] objp pointer to the object to be released
252 *
253 * @api
254 */
255static inline void chFifoReturnObject(objects_fifo_t *ofp,
256 void *objp) {
257
258 chGuardedPoolFree(&ofp->free, objp);
259}
260
261/**
262 * @brief Posts an object.
263 * @note By design the object can be always immediately posted.
264 *
265 * @param[in] ofp pointer to a @p objects_fifo_t structure
266 * @param[in] objp pointer to the object to be posted
267 *
268 * @iclass
269 */
270static inline void chFifoSendObjectI(objects_fifo_t *ofp,
271 void *objp) {
272 msg_t msg;
273
274 msg = chMBPostI(&ofp->mbx, (msg_t)objp);
275 chDbgAssert(msg == MSG_OK, "post failed");
276}
277
278/**
279 * @brief Posts an object.
280 * @note By design the object can be always immediately posted.
281 *
282 * @param[in] ofp pointer to a @p objects_fifo_t structure
283 * @param[in] objp pointer to the object to be posted
284 *
285 * @sclass
286 */
287static inline void chFifoSendObjectS(objects_fifo_t *ofp,
288 void *objp) {
289 msg_t msg;
290
291 msg = chMBPostTimeoutS(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE);
292 chDbgAssert(msg == MSG_OK, "post failed");
293}
294
295/**
296 * @brief Posts an object.
297 * @note By design the object can be always immediately posted.
298 *
299 * @param[in] ofp pointer to a @p objects_fifo_t structure
300 * @param[in] objp pointer to the object to be released
301 *
302 * @api
303 */
304static inline void chFifoSendObject(objects_fifo_t *ofp, void *objp) {
305
306 msg_t msg;
307
308 msg = chMBPostTimeout(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE);
309 chDbgAssert(msg == MSG_OK, "post failed");
310}
311
312/**
313 * @brief Posts an high priority object.
314 * @note By design the object can be always immediately posted.
315 *
316 * @param[in] ofp pointer to a @p objects_fifo_t structure
317 * @param[in] objp pointer to the object to be posted
318 *
319 * @iclass
320 */
321static inline void chFifoSendObjectAheadI(objects_fifo_t *ofp,
322 void *objp) {
323 msg_t msg;
324
325 msg = chMBPostAheadI(&ofp->mbx, (msg_t)objp);
326 chDbgAssert(msg == MSG_OK, "post failed");
327}
328
329/**
330 * @brief Posts an high priority object.
331 * @note By design the object can be always immediately posted.
332 *
333 * @param[in] ofp pointer to a @p objects_fifo_t structure
334 * @param[in] objp pointer to the object to be posted
335 *
336 * @sclass
337 */
338static inline void chFifoSendObjectAheadS(objects_fifo_t *ofp,
339 void *objp) {
340 msg_t msg;
341
342 msg = chMBPostAheadTimeoutS(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE);
343 chDbgAssert(msg == MSG_OK, "post failed");
344}
345
346/**
347 * @brief Posts an high priority object.
348 * @note By design the object can be always immediately posted.
349 *
350 * @param[in] ofp pointer to a @p objects_fifo_t structure
351 * @param[in] objp pointer to the object to be released
352 *
353 * @api
354 */
355static inline void chFifoSendObjectAhead(objects_fifo_t *ofp, void *objp) {
356
357 msg_t msg;
358
359 msg = chMBPostAheadTimeout(&ofp->mbx, (msg_t)objp, TIME_IMMEDIATE);
360 chDbgAssert(msg == MSG_OK, "post failed");
361}
362
363/**
364 * @brief Fetches an object.
365 *
366 * @param[in] ofp pointer to a @p objects_fifo_t structure
367 * @param[in] objpp pointer to the fetched object reference
368 * @return The operation status.
369 * @retval MSG_OK if an object has been correctly fetched.
370 * @retval MSG_TIMEOUT if the FIFO is empty and a message cannot be fetched.
371 *
372 * @iclass
373 */
374static inline msg_t chFifoReceiveObjectI(objects_fifo_t *ofp,
375 void **objpp) {
376
377 return chMBFetchI(&ofp->mbx, (msg_t *)objpp);
378}
379
380/**
381 * @brief Fetches an object.
382 *
383 * @param[in] ofp pointer to a @p objects_fifo_t structure
384 * @param[in] objpp pointer to the fetched object reference
385 * @param[in] timeout the number of ticks before the operation timeouts,
386 * the following special values are allowed:
387 * - @a TIME_IMMEDIATE immediate timeout.
388 * - @a TIME_INFINITE no timeout.
389 * .
390 * @return The operation status.
391 * @retval MSG_OK if an object has been correctly fetched.
392 * @retval MSG_TIMEOUT if the operation has timed out.
393 *
394 * @sclass
395 */
396static inline msg_t chFifoReceiveObjectTimeoutS(objects_fifo_t *ofp,
397 void **objpp,
398 sysinterval_t timeout) {
399
400 return chMBFetchTimeoutS(&ofp->mbx, (msg_t *)objpp, timeout);
401}
402
403/**
404 * @brief Fetches an object.
405 *
406 * @param[in] ofp pointer to a @p objects_fifo_t structure
407 * @param[in] objpp pointer to the fetched object reference
408 * @param[in] timeout the number of ticks before the operation timeouts,
409 * the following special values are allowed:
410 * - @a TIME_IMMEDIATE immediate timeout.
411 * - @a TIME_INFINITE no timeout.
412 * .
413 * @return The operation status.
414 * @retval MSG_OK if an object has been correctly fetched.
415 * @retval MSG_TIMEOUT if the operation has timed out.
416 *
417 * @api
418 */
419static inline msg_t chFifoReceiveObjectTimeout(objects_fifo_t *ofp,
420 void **objpp,
421 sysinterval_t timeout) {
422
423 return chMBFetchTimeout(&ofp->mbx, (msg_t *)objpp, timeout);
424}
425
426#endif /* CH_CFG_USE_OBJ_FIFOS == TRUE */
427
428#endif /* CHOBJFIFOS_H */
429
430/** @} */
diff --git a/lib/chibios/os/oslib/include/chpipes.h b/lib/chibios/os/oslib/include/chpipes.h
new file mode 100644
index 000000000..66fb70284
--- /dev/null
+++ b/lib/chibios/os/oslib/include/chpipes.h
@@ -0,0 +1,208 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chpipes.h
22 * @brief Pipes macros and structures.
23 *
24 * @addtogroup oslib_pipes
25 * @{
26 */
27
28#ifndef CHPIPES_H
29#define CHPIPES_H
30
31#if (CH_CFG_USE_PIPES == TRUE) || defined(__DOXYGEN__)
32
33/*===========================================================================*/
34/* Module constants. */
35/*===========================================================================*/
36
37/*===========================================================================*/
38/* Module pre-compile time settings. */
39/*===========================================================================*/
40
41/*===========================================================================*/
42/* Derived constants and error checks. */
43/*===========================================================================*/
44
45/*===========================================================================*/
46/* Module data structures and types. */
47/*===========================================================================*/
48
49/**
50 * @brief Structure representing a pipe object.
51 */
52typedef struct {
53 uint8_t *buffer; /**< @brief Pointer to the pipe
54 buffer. */
55 uint8_t *top; /**< @brief Pointer to the location
56 after the buffer. */
57 uint8_t *wrptr; /**< @brief Write pointer. */
58 uint8_t *rdptr; /**< @brief Read pointer. */
59 size_t cnt; /**< @brief Bytes in the pipe. */
60 bool reset; /**< @brief True if in reset state. */
61 thread_reference_t wtr; /**< @brief Waiting writer. */
62 thread_reference_t rtr; /**< @brief Waiting reader. */
63#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
64 mutex_t cmtx; /**< @brief Common access mutex. */
65 mutex_t wmtx; /**< @brief Write access mutex. */
66 mutex_t rmtx; /**< @brief Read access mutex. */
67#else
68 semaphore_t csem; /**< @brief Common access semaphore.*/
69 semaphore_t wsem; /**< @brief Write access semaphore. */
70 semaphore_t rsem; /**< @brief Read access semaphore. */
71#endif
72} pipe_t;
73
74/*===========================================================================*/
75/* Module macros. */
76/*===========================================================================*/
77
78/**
79 * @brief Data part of a static pipe initializer.
80 * @details This macro should be used when statically initializing a
81 * pipe that is part of a bigger structure.
82 *
83 * @param[in] name the name of the pipe variable
84 * @param[in] buffer pointer to the pipe buffer array of @p uint8_t
85 * @param[in] size number of @p uint8_t elements in the buffer array
86 */
87#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
88#define _PIPE_DATA(name, buffer, size) { \
89 (uint8_t *)(buffer), \
90 (uint8_t *)(buffer) + size, \
91 (uint8_t *)(buffer), \
92 (uint8_t *)(buffer), \
93 (size_t)0, \
94 false, \
95 NULL, \
96 NULL, \
97 _MUTEX_DATA(name.cmtx), \
98 _MUTEX_DATA(name.wmtx), \
99 _MUTEX_DATA(name.rmtx), \
100}
101#else /* CH_CFG_USE_MUTEXES == FALSE */
102#define _PIPE_DATA(name, buffer, size) { \
103 (uint8_t *)(buffer), \
104 (uint8_t *)(buffer) + size, \
105 (uint8_t *)(buffer), \
106 (uint8_t *)(buffer), \
107 (size_t)0, \
108 false, \
109 NULL, \
110 NULL, \
111 _SEMAPHORE_DATA(name.csem, (cnt_t)1), \
112 _SEMAPHORE_DATA(name.wsem, (cnt_t)1), \
113 _SEMAPHORE_DATA(name.rsem, (cnt_t)1), \
114}
115#endif /* CH_CFG_USE_MUTEXES == FALSE */
116
117/**
118 * @brief Static pipe initializer.
119 * @details Statically initialized pipes require no explicit
120 * initialization using @p chPipeObjectInit().
121 *
122 * @param[in] name the name of the pipe variable
123 * @param[in] buffer pointer to the pipe buffer array of @p uint8_t
124 * @param[in] size number of @p uint8_t elements in the buffer array
125 */
126#define PIPE_DECL(name, buffer, size) \
127 pipe_t name = _PIPE_DATA(name, buffer, size)
128
129/*===========================================================================*/
130/* External declarations. */
131/*===========================================================================*/
132
133#ifdef __cplusplus
134extern "C" {
135#endif
136 void chPipeObjectInit(pipe_t *pp, uint8_t *buf, size_t n);
137 void chPipeReset(pipe_t *pp);
138 size_t chPipeWriteTimeout(pipe_t *pp, const uint8_t *bp,
139 size_t n, sysinterval_t timeout);
140 size_t chPipeReadTimeout(pipe_t *pp, uint8_t *bp,
141 size_t n, sysinterval_t timeout);
142#ifdef __cplusplus
143}
144#endif
145
146/*===========================================================================*/
147/* Module inline functions. */
148/*===========================================================================*/
149
150/**
151 * @brief Returns the pipe buffer size as number of bytes.
152 *
153 * @param[in] pp the pointer to an initialized @p pipe_t object
154 * @return The size of the pipe.
155 *
156 * @api
157 */
158static inline size_t chPipeGetSize(const pipe_t *pp) {
159
160 /*lint -save -e9033 [10.8] Perfectly safe pointers
161 arithmetic.*/
162 return (size_t)(pp->top - pp->buffer);
163 /*lint -restore*/
164}
165
166/**
167 * @brief Returns the number of used byte slots into a pipe.
168 *
169 * @param[in] pp the pointer to an initialized @p pipe_t object
170 * @return The number of queued bytes.
171 *
172 * @api
173 */
174static inline size_t chPipeGetUsedCount(const pipe_t *pp) {
175
176 return pp->cnt;
177}
178
179/**
180 * @brief Returns the number of free byte slots into a pipe.
181 *
182 * @param[in] pp the pointer to an initialized @p pipe_t object
183 * @return The number of empty byte slots.
184 *
185 * @api
186 */
187static inline size_t chPipeGetFreeCount(const pipe_t *pp) {
188
189 return chPipeGetSize(pp) - chPipeGetUsedCount(pp);
190}
191
192/**
193 * @brief Terminates the reset state.
194 *
195 * @param[in] pp the pointer to an initialized @p pipe_t object
196 *
197 * @api
198 */
199static inline void chPipeResume(pipe_t *pp) {
200
201 pp->reset = false;
202}
203
204#endif /* CH_CFG_USE_PIPES == TRUE */
205
206#endif /* CHPIPES_H */
207
208/** @} */
diff --git a/lib/chibios/os/oslib/oslib.mk b/lib/chibios/os/oslib/oslib.mk
new file mode 100644
index 000000000..e9fe2db9c
--- /dev/null
+++ b/lib/chibios/os/oslib/oslib.mk
@@ -0,0 +1,57 @@
1# List of all the ChibiOS/LIB files, there is no need to remove the files
2# from this list, you can disable parts of the kernel by editing chlibconf.h.
3ifeq ($(USE_SMART_BUILD),yes)
4
5# Configuration files directory
6ifeq ($(CHCONFDIR),)
7 ifeq ($(CONFDIR),)
8 CHCONFDIR = .
9 else
10 CHCONFDIR := $(CONFDIR)
11 endif
12endif
13
14CHLIBCONF := $(strip $(shell cat $(CHCONFDIR)/chconf.h | egrep -e "\#define"))
15
16LIBSRC :=
17ifneq ($(findstring CH_CFG_USE_MAILBOXES TRUE,$(CHLIBCONF)),)
18LIBSRC += $(CHIBIOS)/os/oslib/src/chmboxes.c
19endif
20ifneq ($(findstring CH_CFG_USE_MEMCORE TRUE,$(CHLIBCONF)),)
21LIBSRC += $(CHIBIOS)/os/oslib/src/chmemcore.c
22endif
23ifneq ($(findstring CH_CFG_USE_HEAP TRUE,$(CHLIBCONF)),)
24LIBSRC += $(CHIBIOS)/os/oslib/src/chmemheaps.c
25endif
26ifneq ($(findstring CH_CFG_USE_MEMPOOLS TRUE,$(CHLIBCONF)),)
27LIBSRC += $(CHIBIOS)/os/oslib/src/chmempools.c
28endif
29ifneq ($(findstring CH_CFG_USE_PIPES TRUE,$(CHLIBCONF)),)
30LIBSRC += $(CHIBIOS)/os/oslib/src/chpipes.c
31endif
32ifneq ($(findstring CH_CFG_USE_OBJ_CACHES TRUE,$(CHLIBCONF)),)
33LIBSRC += $(CHIBIOS)/os/oslib/src/chobjcaches.c
34endif
35ifneq ($(findstring CH_CFG_USE_DELEGATES TRUE,$(CHLIBCONF)),)
36LIBSRC += $(CHIBIOS)/os/oslib/src/chdelegates.c
37endif
38ifneq ($(findstring CH_CFG_USE_FACTORY TRUE,$(CHLIBCONF)),)
39LIBSRC += $(CHIBIOS)/os/oslib/src/chfactory.c
40endif
41else
42LIBSRC := $(CHIBIOS)/os/oslib/src/chmboxes.c \
43 $(CHIBIOS)/os/oslib/src/chmemcore.c \
44 $(CHIBIOS)/os/oslib/src/chmemheaps.c \
45 $(CHIBIOS)/os/oslib/src/chmempools.c \
46 $(CHIBIOS)/os/oslib/src/chpipes.c \
47 $(CHIBIOS)/os/oslib/src/chobjcaches.c \
48 $(CHIBIOS)/os/oslib/src/chdelegates.c \
49 $(CHIBIOS)/os/oslib/src/chfactory.c
50endif
51
52# Required include directories
53LIBINC := $(CHIBIOS)/os/oslib/include
54
55# Shared variables
56ALLCSRC += $(LIBSRC)
57ALLINC += $(LIBINC)
diff --git a/lib/chibios/os/oslib/readme.txt b/lib/chibios/os/oslib/readme.txt
new file mode 100644
index 000000000..ec43d5af2
--- /dev/null
+++ b/lib/chibios/os/oslib/readme.txt
@@ -0,0 +1,2 @@
1All the code contained under ./os/lib are high level RTOS extension modules
2compatible with both RT and NIL. \ No newline at end of file
diff --git a/lib/chibios/os/oslib/src/chdelegates.c b/lib/chibios/os/oslib/src/chdelegates.c
new file mode 100644
index 000000000..648276eb6
--- /dev/null
+++ b/lib/chibios/os/oslib/src/chdelegates.c
@@ -0,0 +1,239 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/src/chdelegates.c
22 * @brief Delegate threads code.
23 * @details Delegate threads.
24 * <h2>Operation mode</h2>
25 * A delegate thread is a thread performing function calls triggered
26 * by other threads. This functionality is especially useful when
27 * encapsulating a library not designed for threading into a
28 * delegate thread. Other threads have access to the library without
29 * having to worry about mutual exclusion.
30 * @pre In order to use the pipes APIs the @p CH_CFG_USE_DELEGATES
31 * option must be enabled in @p chconf.h.
32 * @note Compatible with RT and NIL.
33 *
34 * @addtogroup oslib_delegates
35 * @{
36 */
37
38#include "ch.h"
39
40#if (CH_CFG_USE_DELEGATES == TRUE) || defined(__DOXYGEN__)
41
42/*===========================================================================*/
43/* Module local definitions. */
44/*===========================================================================*/
45
46/*===========================================================================*/
47/* Module exported variables. */
48/*===========================================================================*/
49
50/*===========================================================================*/
51/* Module local types. */
52/*===========================================================================*/
53
54/**
55 * @brief Type of a structure representing a delegate call.
56 */
57typedef struct {
58 /**
59 * @brief The delegate veneer function.
60 */
61 delegate_veneer_t veneer;
62 /**
63 * @brief Pointer to the caller @p va_list object.
64 */
65 va_list *argsp;
66} call_message_t;
67
68/*===========================================================================*/
69/* Module local variables. */
70/*===========================================================================*/
71
72/*===========================================================================*/
73/* Module local functions. */
74/*===========================================================================*/
75
76/*===========================================================================*/
77/* Module exported functions. */
78/*===========================================================================*/
79
80/*lint -save -e586 [17.1] Required by design.*/
81
82/**
83 * @brief Veneer for functions with no parameters.
84 *
85 * @param[in] argsp the list of arguments
86 * @return The function return value.
87 */
88msg_t __ch_delegate_fn0(va_list *argsp) {
89 delegate_fn0_t fn0 = (delegate_fn0_t)va_arg(*argsp, delegate_fn0_t);
90 return fn0();
91}
92
93/**
94 * @brief Veneer for functions with one parameter.
95 *
96 * @param[in] argsp the list of arguments
97 * @return The function return value.
98 */
99msg_t __ch_delegate_fn1(va_list *argsp) {
100 delegate_fn1_t fn1 = (delegate_fn1_t)va_arg(*argsp, delegate_fn1_t);
101 msg_t p1 = (msg_t)va_arg(*argsp, msg_t);
102 return fn1(p1);
103}
104
105/**
106 * @brief Veneer for functions with two parameters.
107 *
108 * @param[in] argsp the list of arguments
109 * @return The function return value.
110 */
111msg_t __ch_delegate_fn2(va_list *argsp) {
112 delegate_fn2_t fn2 = (delegate_fn2_t)va_arg(*argsp, delegate_fn2_t);
113 msg_t p1 = (msg_t)va_arg(*argsp, msg_t);
114 msg_t p2 = (msg_t)va_arg(*argsp, msg_t);
115 return fn2(p1, p2);
116}
117
118/**
119 * @brief Veneer for functions with three parameters.
120 *
121 * @param[in] argsp the list of arguments
122 * @return The function return value.
123 */
124msg_t __ch_delegate_fn3(va_list *argsp) {
125 delegate_fn3_t fn3 = (delegate_fn3_t)va_arg(*argsp, delegate_fn3_t);
126 msg_t p1 = (msg_t)va_arg(*argsp, msg_t);
127 msg_t p2 = (msg_t)va_arg(*argsp, msg_t);
128 msg_t p3 = (msg_t)va_arg(*argsp, msg_t);
129 return fn3(p1, p2, p3);
130}
131
132/**
133 * @brief Veneer for functions with four parameters.
134 *
135 * @param[in] argsp the list of arguments
136 * @return The function return value.
137 */
138msg_t __ch_delegate_fn4(va_list *argsp) {
139 delegate_fn4_t fn4 = (delegate_fn4_t)va_arg(*argsp, delegate_fn4_t);
140 msg_t p1 = (msg_t)va_arg(*argsp, msg_t);
141 msg_t p2 = (msg_t)va_arg(*argsp, msg_t);
142 msg_t p3 = (msg_t)va_arg(*argsp, msg_t);
143 msg_t p4 = (msg_t)va_arg(*argsp, msg_t);
144 return fn4(p1, p2, p3, p4);
145}
146
147/**
148 * @brief Triggers a function call on a delegate thread.
149 * @note The thread must be executing @p chDelegateDispatchTimeout() in
150 * order to have the functions called.
151 *
152 * @param[in] tp pointer to the delegate thread
153 * @param[in] veneer pointer to the veneer function to be called
154 * @param[in] ... variable number of parameters
155 * @return The function return value casted to msg_t. It is
156 * garbage for functions returning @p void.
157 */
158msg_t chDelegateCallVeneer(thread_t *tp, delegate_veneer_t veneer, ...) {
159 va_list args;
160 call_message_t cm;
161 msg_t msg;
162
163 va_start(args, veneer);
164
165 /* Preparing the call message.*/
166 cm.veneer = veneer;
167 cm.argsp = &args;
168 (void)cm; /* Suppresses a lint warning.*/
169
170 /* Sending the message to the dispatcher thread, the return value is
171 contained in the returned message.*/
172 msg = chMsgSend(tp, (msg_t)&cm);
173
174 va_end(args);
175
176 return msg;
177}
178
179/*lint -restore*/
180
181/**
182 * @brief Call messages dispatching.
183 * @details The function awaits for an incoming call messages and calls the
184 * specified functions, then it returns. In case multiple threads
185 * are sending messages then the requests are served in priority
186 * order.
187 *
188 * @api
189 */
190void chDelegateDispatch(void) {
191 thread_t *tp;
192 const call_message_t *cmp;
193 msg_t ret;
194
195 tp = chMsgWait();
196 cmp = (const call_message_t *)chMsgGet(tp);
197 ret = cmp->veneer(cmp->argsp);
198
199 chMsgRelease(tp, ret);
200}
201
202/**
203 * @brief Call messages dispatching with timeout.
204 * @details The function awaits for an incoming call messages and calls the
205 * specified functions, then it returns. In case multiple threads
206 * are sending messages then the requests are served in priority
207 * order.
208 *
209 * @param[in] timeout the number of ticks before the operation timeouts,
210 * the following special values are allowed:
211 * - @a TIME_INFINITE no timeout.
212 * .
213 * @return The function outcome.
214 * @retval MSG_OK if a function has been called.
215 * @retval MSG_TIMEOUT if a timeout occurred.
216 *
217 * @api
218 */
219msg_t chDelegateDispatchTimeout(sysinterval_t timeout) {
220 thread_t *tp;
221 const call_message_t *cmp;
222 msg_t ret;
223
224 tp = chMsgWaitTimeout(timeout);
225 if (tp == NULL) {
226 return MSG_TIMEOUT;
227 }
228
229 cmp = (const call_message_t *)chMsgGet(tp);
230 ret = cmp->veneer(cmp->argsp);
231
232 chMsgRelease(tp, ret);
233
234 return MSG_OK;
235}
236
237#endif /* CH_CFG_USE_DELEGATES == TRUE */
238
239/** @} */
diff --git a/lib/chibios/os/oslib/src/chfactory.c b/lib/chibios/os/oslib/src/chfactory.c
new file mode 100644
index 000000000..9351ab151
--- /dev/null
+++ b/lib/chibios/os/oslib/src/chfactory.c
@@ -0,0 +1,829 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/src/chfactory.c
22 * @brief ChibiOS objects factory and registry code.
23 *
24 * @addtogroup oslib_objects_factory
25 * @details The object factory is a subsystem that allows to:
26 * - Register static objects by name.
27 * - Dynamically create objects and assign them a name.
28 * - Retrieve existing objects by name.
29 * - Free objects by reference.
30 * .
31 * Allocated OS objects are handled using a reference counter, only
32 * when all references have been released then the object memory is
33 * freed in a pool.<br>
34 * @pre This subsystem requires the @p CH_CFG_USE_MEMCORE and
35 * @p CH_CFG_USE_MEMPOOLS options to be set to @p TRUE. The
36 * option @p CH_CFG_USE_HEAP is also required if the support
37 * for variable length objects is enabled.
38 * @note Compatible with RT and NIL.
39 * @{
40 */
41
42#include <string.h>
43
44#include "ch.h"
45
46#if (CH_CFG_USE_FACTORY == TRUE) || defined(__DOXYGEN__)
47
48/*===========================================================================*/
49/* Module local definitions. */
50/*===========================================================================*/
51
52/*
53 * Defaults on the best synchronization mechanism available.
54 */
55#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
56#define F_LOCK() chMtxLock(&ch_factory.mtx)
57#define F_UNLOCK() chMtxUnlock(&ch_factory.mtx)
58#else
59#define F_LOCK() (void) chSemWait(&ch_factory.sem)
60#define F_UNLOCK() chSemSignal(&ch_factory.sem)
61#endif
62
63/*===========================================================================*/
64/* Module exported variables. */
65/*===========================================================================*/
66
67/**
68 * @brief Factory object static instance.
69 * @note It is a global object because it could be accessed through
70 * a specific debugger plugin.
71 */
72objects_factory_t ch_factory;
73
74/*===========================================================================*/
75/* Module local types. */
76/*===========================================================================*/
77
78/*===========================================================================*/
79/* Module local variables. */
80/*===========================================================================*/
81
82/*===========================================================================*/
83/* Module local functions. */
84/*===========================================================================*/
85
86static void copy_name(const char *sp, char *dp) {
87 unsigned i;
88 char c;
89
90 i = CH_CFG_FACTORY_MAX_NAMES_LENGTH;
91 do {
92 c = *sp++;
93 *dp++ = c;
94 i--;
95 } while ((c != (char)0) && (i > 0U));
96}
97
98static inline void dyn_list_init(dyn_list_t *dlp) {
99
100 dlp->next = (dyn_element_t *)dlp;
101}
102
103static dyn_element_t *dyn_list_find(const char *name, dyn_list_t *dlp) {
104 dyn_element_t *p = dlp->next;
105
106 while (p != (dyn_element_t *)dlp) {
107 if (strncmp(p->name, name, CH_CFG_FACTORY_MAX_NAMES_LENGTH) == 0) {
108 return p;
109 }
110 p = p->next;
111 }
112
113 return NULL;
114}
115
116static dyn_element_t *dyn_list_unlink(dyn_element_t *element,
117 dyn_list_t *dlp) {
118 dyn_element_t *prev = (dyn_element_t *)dlp;
119
120 /* Scanning the list.*/
121 while (prev->next != (dyn_element_t *)dlp) {
122 if (prev->next == element) {
123 /* Found.*/
124 prev->next = element->next;
125 return element;
126 }
127
128 /* Next element in the list.*/
129 prev = prev->next;
130 }
131
132 return NULL;
133}
134
135#if CH_FACTORY_REQUIRES_HEAP || defined(__DOXYGEN__)
136static dyn_element_t *dyn_create_object_heap(const char *name,
137 dyn_list_t *dlp,
138 size_t size,
139 unsigned align) {
140 dyn_element_t *dep;
141
142 chDbgCheck(name != NULL);
143
144 /* Checking if an object with this name has already been created.*/
145 dep = dyn_list_find(name, dlp);
146 if (dep != NULL) {
147 return NULL;
148 }
149
150 /* Allocating space for the new buffer object.*/
151 dep = (dyn_element_t *)chHeapAllocAligned(NULL, size, align);
152 if (dep == NULL) {
153 return NULL;
154 }
155
156 /* Initializing object list element.*/
157 copy_name(name, dep->name);
158 dep->refs = (ucnt_t)1;
159 dep->next = dlp->next;
160
161 /* Updating factory list.*/
162 dlp->next = dep;
163
164 return dep;
165}
166
167static void dyn_release_object_heap(dyn_element_t *dep,
168 dyn_list_t *dlp) {
169
170 chDbgCheck(dep != NULL);
171 chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number");
172
173 dep->refs--;
174 if (dep->refs == (ucnt_t)0) {
175 dep = dyn_list_unlink(dep, dlp);
176 chHeapFree((void *)dep);
177 }
178}
179#endif /* CH_FACTORY_REQUIRES_HEAP */
180
181#if CH_FACTORY_REQUIRES_POOLS || defined(__DOXYGEN__)
182static dyn_element_t *dyn_create_object_pool(const char *name,
183 dyn_list_t *dlp,
184 memory_pool_t *mp) {
185 dyn_element_t *dep;
186
187 chDbgCheck(name != NULL);
188
189 /* Checking if an object object with this name has already been created.*/
190 dep = dyn_list_find(name, dlp);
191 if (dep != NULL) {
192 return NULL;
193 }
194
195 /* Allocating space for the new object.*/
196 dep = (dyn_element_t *)chPoolAlloc(mp);
197 if (dep == NULL) {
198 return NULL;
199 }
200
201 /* Initializing object list element.*/
202 copy_name(name, dep->name);
203 dep->refs = (ucnt_t)1;
204 dep->next = dlp->next;
205
206 /* Updating factory list.*/
207 dlp->next = (dyn_element_t *)dep;
208
209 return dep;
210}
211
212static void dyn_release_object_pool(dyn_element_t *dep,
213 dyn_list_t *dlp,
214 memory_pool_t *mp) {
215
216 chDbgCheck(dep != NULL);
217 chDbgAssert(dep->refs > (ucnt_t)0, "invalid references number");
218
219 dep->refs--;
220 if (dep->refs == (ucnt_t)0) {
221 dep = dyn_list_unlink(dep, dlp);
222 chPoolFree(mp, (void *)dep);
223 }
224}
225#endif /* CH_FACTORY_REQUIRES_POOLS */
226
227static dyn_element_t *dyn_find_object(const char *name, dyn_list_t *dlp) {
228 dyn_element_t *dep;
229
230 chDbgCheck(name != NULL);
231
232 /* Checking if an object with this name has already been created.*/
233 dep = dyn_list_find(name, dlp);
234 if (dep != NULL) {
235 /* Increasing references counter.*/
236 dep->refs++;
237 }
238
239 return dep;
240}
241
242/*===========================================================================*/
243/* Module exported functions. */
244/*===========================================================================*/
245
246/**
247 * @brief Initializes the objects factory.
248 *
249 * @init
250 */
251void _factory_init(void) {
252
253#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
254 chMtxObjectInit(&ch_factory.mtx);
255#else
256 chSemObjectInit(&ch_factory.sem, (cnt_t)1);
257#endif
258
259#if CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE
260 dyn_list_init(&ch_factory.obj_list);
261 chPoolObjectInit(&ch_factory.obj_pool,
262 sizeof (registered_object_t),
263 chCoreAllocAlignedI);
264#endif
265#if CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE
266 dyn_list_init(&ch_factory.buf_list);
267#endif
268#if CH_CFG_FACTORY_SEMAPHORES == TRUE
269 dyn_list_init(&ch_factory.sem_list);
270 chPoolObjectInit(&ch_factory.sem_pool,
271 sizeof (dyn_semaphore_t),
272 chCoreAllocAlignedI);
273#endif
274#if CH_CFG_FACTORY_MAILBOXES == TRUE
275 dyn_list_init(&ch_factory.mbx_list);
276#endif
277#if CH_CFG_FACTORY_OBJ_FIFOS == TRUE
278 dyn_list_init(&ch_factory.fifo_list);
279#endif
280#if CH_CFG_FACTORY_PIPES == TRUE
281 dyn_list_init(&ch_factory.pipe_list);
282#endif
283}
284
285#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXIGEN__)
286/**
287 * @brief Registers a generic object.
288 * @post A reference to the registered object is returned and the
289 * reference counter is initialized to one.
290 *
291 * @param[in] name name to be assigned to the registered object
292 * @param[in] objp pointer to the object to be registered
293 *
294 * @return The reference to the registered object.
295 * @retval NULL if the object to be registered cannot be allocated or
296 * a registered object with the same name exists.
297 *
298 * @api
299 */
300registered_object_t *chFactoryRegisterObject(const char *name,
301 void *objp) {
302 registered_object_t *rop;
303
304 F_LOCK();
305
306 rop = (registered_object_t *)dyn_create_object_pool(name,
307 &ch_factory.obj_list,
308 &ch_factory.obj_pool);
309 if (rop != NULL) {
310 /* Initializing registered object data.*/
311 rop->objp = objp;
312 }
313
314 F_UNLOCK();
315
316 return rop;
317}
318
319/**
320 * @brief Retrieves a registered object.
321 * @post A reference to the registered object is returned with the
322 * reference counter increased by one.
323 *
324 * @param[in] name name of the registered object
325 *
326 * @return The reference to the found registered object.
327 * @retval NULL if a registered object with the specified name
328 * does not exist.
329 *
330 * @api
331 */
332registered_object_t *chFactoryFindObject(const char *name) {
333 registered_object_t *rop;
334
335 F_LOCK();
336
337 rop = (registered_object_t *)dyn_find_object(name, &ch_factory.obj_list);
338
339 F_UNLOCK();
340
341 return rop;
342}
343
344/**
345 * @brief Retrieves a registered object by pointer.
346 * @post A reference to the registered object is returned with the
347 * reference counter increased by one.
348 *
349 * @param[in] objp pointer to the object to be retrieved
350 *
351 * @return The reference to the found registered object.
352 * @retval NULL if a registered object with the specified pointer
353 * does not exist.
354 *
355 * @api
356 */
357registered_object_t *chFactoryFindObjectByPointer(void *objp) {
358 registered_object_t *rop = (registered_object_t *)ch_factory.obj_list.next;
359
360 F_LOCK();
361
362 while ((void *)rop != (void *)&ch_factory.obj_list) {
363 if (rop->objp == objp) {
364 rop->element.refs++;
365
366 F_UNLOCK();
367
368 return rop;
369 }
370 rop = (registered_object_t *)rop->element.next;
371 }
372
373 F_UNLOCK();
374
375 return NULL;
376}
377
378/**
379 * @brief Releases a registered object.
380 * @details The reference counter of the registered object is decreased
381 * by one, if reaches zero then the registered object memory
382 * is freed.
383 * @note The object itself is not freed, it could be static, only the
384 * allocated list element is freed.
385 *
386 * @param[in] rop registered object reference
387 *
388 * @api
389 */
390void chFactoryReleaseObject(registered_object_t *rop) {
391
392 F_LOCK();
393
394 dyn_release_object_pool(&rop->element,
395 &ch_factory.obj_list,
396 &ch_factory.obj_pool);
397
398 F_UNLOCK();
399}
400#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
401
402#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXIGEN__)
403/**
404 * @brief Creates a generic dynamic buffer object.
405 * @post A reference to the dynamic buffer object is returned and the
406 * reference counter is initialized to one.
407 * @post The dynamic buffer object is filled with zeros.
408 *
409 * @param[in] name name to be assigned to the new dynamic buffer object
410 * @param[in] size payload size of the dynamic buffer object to be created
411 *
412 * @return The reference to the created dynamic buffer object.
413 * @retval NULL if the dynamic buffer object cannot be allocated or
414 * a dynamic buffer object with the same name exists.
415 *
416 * @api
417 */
418dyn_buffer_t *chFactoryCreateBuffer(const char *name, size_t size) {
419 dyn_buffer_t *dbp;
420
421 F_LOCK();
422
423 dbp = (dyn_buffer_t *)dyn_create_object_heap(name,
424 &ch_factory.buf_list,
425 sizeof (dyn_buffer_t) + size,
426 CH_HEAP_ALIGNMENT);
427 if (dbp != NULL) {
428 /* Initializing buffer object data.*/
429 memset((void *)(dbp + 1), 0, size);
430 }
431
432 F_UNLOCK();
433
434 return dbp;
435}
436
437/**
438 * @brief Retrieves a dynamic buffer object.
439 * @post A reference to the dynamic buffer object is returned with the
440 * reference counter increased by one.
441 *
442 * @param[in] name name of the dynamic buffer object
443 *
444 * @return The reference to the found dynamic buffer object.
445 * @retval NULL if a dynamic buffer object with the specified name
446 * does not exist.
447 *
448 * @api
449 */
450dyn_buffer_t *chFactoryFindBuffer(const char *name) {
451 dyn_buffer_t *dbp;
452
453 F_LOCK();
454
455 dbp = (dyn_buffer_t *)dyn_find_object(name, &ch_factory.buf_list);
456
457 F_UNLOCK();
458
459 return dbp;
460}
461
462/**
463 * @brief Releases a dynamic buffer object.
464 * @details The reference counter of the dynamic buffer object is decreased
465 * by one, if reaches zero then the dynamic buffer object memory
466 * is freed.
467 *
468 * @param[in] dbp dynamic buffer object reference
469 *
470 * @api
471 */
472void chFactoryReleaseBuffer(dyn_buffer_t *dbp) {
473
474 F_LOCK();
475
476 dyn_release_object_heap(&dbp->element, &ch_factory.buf_list);
477
478 F_UNLOCK();
479}
480#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS = TRUE */
481
482#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXIGEN__)
483/**
484 * @brief Creates a dynamic semaphore object.
485 * @post A reference to the dynamic semaphore object is returned and the
486 * reference counter is initialized to one.
487 * @post The dynamic semaphore object is initialized and ready to use.
488 *
489 * @param[in] name name to be assigned to the new dynamic semaphore object
490 * @param[in] n dynamic semaphore object counter initialization value
491 *
492 * @return The reference to the created dynamic semaphore object.
493 * @retval NULL if the dynamic semaphore object cannot be allocated or
494 * a dynamic semaphore with the same name exists.
495 *
496 * @api
497 */
498dyn_semaphore_t *chFactoryCreateSemaphore(const char *name, cnt_t n) {
499 dyn_semaphore_t *dsp;
500
501 F_LOCK();
502
503 dsp = (dyn_semaphore_t *)dyn_create_object_pool(name,
504 &ch_factory.sem_list,
505 &ch_factory.sem_pool);
506 if (dsp != NULL) {
507 /* Initializing semaphore object dataa.*/
508 chSemObjectInit(&dsp->sem, n);
509 }
510
511 F_UNLOCK();
512
513 return dsp;
514}
515
516/**
517 * @brief Retrieves a dynamic semaphore object.
518 * @post A reference to the dynamic semaphore object is returned with the
519 * reference counter increased by one.
520 *
521 * @param[in] name name of the dynamic semaphore object
522 *
523 * @return The reference to the found dynamic semaphore object.
524 * @retval NULL if a dynamic semaphore object with the specified name
525 * does not exist.
526 *
527 * @api
528 */
529dyn_semaphore_t *chFactoryFindSemaphore(const char *name) {
530 dyn_semaphore_t *dsp;
531
532 F_LOCK();
533
534 dsp = (dyn_semaphore_t *)dyn_find_object(name, &ch_factory.sem_list);
535
536 F_UNLOCK();
537
538 return dsp;
539}
540
541/**
542 * @brief Releases a dynamic semaphore object.
543 * @details The reference counter of the dynamic semaphore object is decreased
544 * by one, if reaches zero then the dynamic semaphore object memory
545 * is freed.
546 *
547 * @param[in] dsp dynamic semaphore object reference
548 *
549 * @api
550 */
551void chFactoryReleaseSemaphore(dyn_semaphore_t *dsp) {
552
553 F_LOCK();
554
555 dyn_release_object_pool(&dsp->element,
556 &ch_factory.sem_list,
557 &ch_factory.sem_pool);
558
559 F_UNLOCK();
560}
561#endif /* CH_CFG_FACTORY_SEMAPHORES = TRUE */
562
563#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXIGEN__)
564/**
565 * @brief Creates a dynamic mailbox object.
566 * @post A reference to the dynamic mailbox object is returned and the
567 * reference counter is initialized to one.
568 * @post The dynamic mailbox object is initialized and ready to use.
569 *
570 * @param[in] name name to be assigned to the new dynamic mailbox object
571 * @param[in] n mailbox buffer size as number of messages
572 *
573 * @return The reference to the created dynamic mailbox object.
574 * @retval NULL if the dynamic mailbox object cannot be allocated or
575 * a dynamic mailbox object with the same name exists.
576 *
577 * @api
578 */
579dyn_mailbox_t *chFactoryCreateMailbox(const char *name, size_t n) {
580 dyn_mailbox_t *dmp;
581
582 F_LOCK();
583
584 dmp = (dyn_mailbox_t *)dyn_create_object_heap(name,
585 &ch_factory.mbx_list,
586 sizeof (dyn_mailbox_t) +
587 (n * sizeof (msg_t)),
588 CH_HEAP_ALIGNMENT);
589 if (dmp != NULL) {
590 /* Initializing mailbox object data.*/
591 chMBObjectInit(&dmp->mbx, (msg_t *)(dmp + 1), n);
592 }
593
594 F_UNLOCK();
595
596 return dmp;
597}
598
599/**
600 * @brief Retrieves a dynamic mailbox object.
601 * @post A reference to the dynamic mailbox object is returned with the
602 * reference counter increased by one.
603 *
604 * @param[in] name name of the dynamic mailbox object
605 *
606 * @return The reference to the found dynamic mailbox object.
607 * @retval NULL if a dynamic mailbox object with the specified name
608 * does not exist.
609 *
610 * @api
611 */
612dyn_mailbox_t *chFactoryFindMailbox(const char *name) {
613 dyn_mailbox_t *dmp;
614
615 F_LOCK();
616
617 dmp = (dyn_mailbox_t *)dyn_find_object(name, &ch_factory.mbx_list);
618
619 F_UNLOCK();
620
621 return dmp;
622}
623
624/**
625 * @brief Releases a dynamic mailbox object.
626 * @details The reference counter of the dynamic mailbox object is decreased
627 * by one, if reaches zero then the dynamic mailbox object memory
628 * is freed.
629 *
630 * @param[in] dmp dynamic mailbox object reference
631 *
632 * @api
633 */
634void chFactoryReleaseMailbox(dyn_mailbox_t *dmp) {
635
636 F_LOCK();
637
638 dyn_release_object_heap(&dmp->element, &ch_factory.mbx_list);
639
640 F_UNLOCK();
641}
642#endif /* CH_CFG_FACTORY_MAILBOXES = TRUE */
643
644#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXIGEN__)
645/**
646 * @brief Creates a dynamic "objects FIFO" object.
647 * @post A reference to the dynamic "objects FIFO" object is returned and
648 * the reference counter is initialized to one.
649 * @post The dynamic "objects FIFO" object is initialized and ready to use.
650 *
651 * @param[in] name name to be assigned to the new dynamic "objects FIFO"
652 * object
653 * @param[in] objsize size of objects
654 * @param[in] objn number of objects available
655 * @param[in] objalign required objects alignment
656 * @return The reference to the created dynamic "objects FIFO"
657 * object.
658 * @retval NULL if the dynamic "objects FIFO" object cannot be
659 * allocated or a dynamic "objects FIFO" object with
660 * the same name exists.
661 *
662 * @api
663 */
664dyn_objects_fifo_t *chFactoryCreateObjectsFIFO(const char *name,
665 size_t objsize,
666 size_t objn,
667 unsigned objalign) {
668 size_t size1, size2;
669 dyn_objects_fifo_t *dofp;
670
671 F_LOCK();
672
673 /* Enforcing alignment for the objects array.*/
674 objsize = MEM_ALIGN_NEXT(objsize, objalign);
675 size1 = MEM_ALIGN_NEXT(sizeof (dyn_objects_fifo_t) + (objn * sizeof (msg_t)),
676 objalign);
677 size2 = objn * objsize;
678
679 /* Allocating the FIFO object with messages buffer and objects buffer.*/
680 dofp = (dyn_objects_fifo_t *)dyn_create_object_heap(name,
681 &ch_factory.fifo_list,
682 size1 + size2,
683 objalign);
684 if (dofp != NULL) {
685 msg_t *msgbuf = (msg_t *)(dofp + 1);
686 uint8_t *objbuf = (uint8_t *)dofp + size1;
687
688 /* Initializing mailbox object data.*/
689 chFifoObjectInitAligned(&dofp->fifo, objsize, objn, objalign,
690 (void *)objbuf, msgbuf);
691 }
692
693 F_UNLOCK();
694
695 return dofp;
696}
697
698/**
699 * @brief Retrieves a dynamic "objects FIFO" object.
700 * @post A reference to the dynamic "objects FIFO" object is returned with
701 * the reference counter increased by one.
702 *
703 * @param[in] name name of the dynamic "objects FIFO" object
704 *
705 * @return The reference to the found dynamic "objects FIFO"
706 * object.
707 * @retval NULL if a dynamic "objects FIFO" object with the specified
708 * name does not exist.
709 *
710 * @api
711 */
712dyn_objects_fifo_t *chFactoryFindObjectsFIFO(const char *name) {
713 dyn_objects_fifo_t *dofp;
714
715 F_LOCK();
716
717 dofp = (dyn_objects_fifo_t *)dyn_find_object(name, &ch_factory.fifo_list);
718
719 F_UNLOCK();
720
721 return dofp;
722}
723
724/**
725 * @brief Releases a dynamic "objects FIFO" object.
726 * @details The reference counter of the dynamic "objects FIFO" object is
727 * decreased by one, if reaches zero then the dynamic "objects FIFO"
728 * object memory is freed.
729 *
730 * @param[in] dofp dynamic "objects FIFO" object reference
731 *
732 * @api
733 */
734void chFactoryReleaseObjectsFIFO(dyn_objects_fifo_t *dofp) {
735
736 F_LOCK();
737
738 dyn_release_object_heap(&dofp->element, &ch_factory.fifo_list);
739
740 F_UNLOCK();
741}
742#endif /* CH_CFG_FACTORY_OBJ_FIFOS = TRUE */
743
744#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXIGEN__)
745/**
746 * @brief Creates a dynamic pipe object.
747 * @post A reference to the dynamic pipe object is returned and
748 * the reference counter is initialized to one.
749 * @post The dynamic pipe object is initialized and ready to use.
750 *
751 * @param[in] name name to be assigned to the new dynamic pipe
752 * object
753 * @param[in] size pipe buffer size
754 * @return The reference to the created dynamic pipe
755 * object.
756 * @retval NULL if the dynamic pipe object cannot be
757 * allocated or a dynamic pipe object with
758 * the same name exists.
759 *
760 * @api
761 */
762dyn_pipe_t *chFactoryCreatePipe(const char *name, size_t size) {
763 dyn_pipe_t *dpp;
764
765 F_LOCK();
766
767 dpp = (dyn_pipe_t *)dyn_create_object_heap(name,
768 &ch_factory.pipe_list,
769 sizeof (dyn_pipe_t) + size,
770 CH_HEAP_ALIGNMENT);
771 if (dpp != NULL) {
772 /* Initializing mailbox object data.*/
773 chPipeObjectInit(&dpp->pipe, (uint8_t *)(dpp + 1), size);
774 }
775
776 F_UNLOCK();
777
778 return dpp;
779}
780
781/**
782 * @brief Retrieves a dynamic pipe object.
783 * @post A reference to the dynamic pipe object is returned with
784 * the reference counter increased by one.
785 *
786 * @param[in] name name of the pipe object
787 *
788 * @return The reference to the found dynamic pipe
789 * object.
790 * @retval NULL if a dynamic pipe object with the specified
791 * name does not exist.
792 *
793 * @api
794 */
795dyn_pipe_t *chFactoryFindPipe(const char *name) {
796 dyn_pipe_t *dpp;
797
798 F_LOCK();
799
800 dpp = (dyn_pipe_t *)dyn_find_object(name, &ch_factory.pipe_list);
801
802 F_UNLOCK();
803
804 return dpp;
805}
806
807/**
808 * @brief Releases a dynamic pipe object.
809 * @details The reference counter of the dynamic pipe object is
810 * decreased by one, if reaches zero then the dynamic pipe
811 * object memory is freed.
812 *
813 * @param[in] dpp dynamic pipe object reference
814 *
815 * @api
816 */
817void chFactoryReleasePipe(dyn_pipe_t *dpp) {
818
819 F_LOCK();
820
821 dyn_release_object_heap(&dpp->element, &ch_factory.pipe_list);
822
823 F_UNLOCK();
824}
825#endif /* CH_CFG_FACTORY_PIPES = TRUE */
826
827#endif /* CH_CFG_USE_FACTORY == TRUE */
828
829/** @} */
diff --git a/lib/chibios/os/oslib/src/chmboxes.c b/lib/chibios/os/oslib/src/chmboxes.c
new file mode 100644
index 000000000..a9f738109
--- /dev/null
+++ b/lib/chibios/os/oslib/src/chmboxes.c
@@ -0,0 +1,522 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/src/chmboxes.c
22 * @brief Mailboxes code.
23 *
24 * @addtogroup oslib_mailboxes
25 * @details Asynchronous messages.
26 * <h2>Operation mode</h2>
27 * A mailbox is an asynchronous communication mechanism.<br>
28 * Operations defined for mailboxes:
29 * - <b>Post</b>: Posts a message on the mailbox in FIFO order.
30 * - <b>Post Ahead</b>: Posts a message on the mailbox with urgent
31 * priority.
32 * - <b>Fetch</b>: A message is fetched from the mailbox and removed
33 * from the queue.
34 * - <b>Reset</b>: The mailbox is emptied and all the stored messages
35 * are lost.
36 * .
37 * A message is a variable of type msg_t that is guaranteed to have
38 * the same size of and be compatible with (data) pointers (anyway an
39 * explicit cast is needed).
40 * If larger messages need to be exchanged then a pointer to a
41 * structure can be posted in the mailbox but the posting side has
42 * no predefined way to know when the message has been processed. A
43 * possible approach is to allocate memory (from a memory pool for
44 * example) from the posting side and free it on the fetching side.
45 * Another approach is to set a "done" flag into the structure pointed
46 * by the message.
47 * @pre In order to use the mailboxes APIs the @p CH_CFG_USE_MAILBOXES
48 * option must be enabled in @p chconf.h.
49 * @note Compatible with RT and NIL.
50 * @{
51 */
52
53#include "ch.h"
54
55#if (CH_CFG_USE_MAILBOXES == TRUE) || defined(__DOXYGEN__)
56
57/*===========================================================================*/
58/* Module exported variables. */
59/*===========================================================================*/
60
61/*===========================================================================*/
62/* Module local types. */
63/*===========================================================================*/
64
65/*===========================================================================*/
66/* Module local variables. */
67/*===========================================================================*/
68
69/*===========================================================================*/
70/* Module local functions. */
71/*===========================================================================*/
72
73/*===========================================================================*/
74/* Module exported functions. */
75/*===========================================================================*/
76
77/**
78 * @brief Initializes a @p mailbox_t object.
79 *
80 * @param[out] mbp the pointer to the @p mailbox_t structure to be
81 * initialized
82 * @param[in] buf pointer to the messages buffer as an array of @p msg_t
83 * @param[in] n number of elements in the buffer array
84 *
85 * @init
86 */
87void chMBObjectInit(mailbox_t *mbp, msg_t *buf, size_t n) {
88
89 chDbgCheck((mbp != NULL) && (buf != NULL) && (n > (size_t)0));
90
91 mbp->buffer = buf;
92 mbp->rdptr = buf;
93 mbp->wrptr = buf;
94 mbp->top = &buf[n];
95 mbp->cnt = (size_t)0;
96 mbp->reset = false;
97 chThdQueueObjectInit(&mbp->qw);
98 chThdQueueObjectInit(&mbp->qr);
99}
100
101/**
102 * @brief Resets a @p mailbox_t object.
103 * @details All the waiting threads are resumed with status @p MSG_RESET and
104 * the queued messages are lost.
105 * @post The mailbox is in reset state, all operations will fail and
106 * return @p MSG_RESET until the mailbox is enabled again using
107 * @p chMBResumeX().
108 *
109 * @param[in] mbp the pointer to an initialized @p mailbox_t object
110 *
111 * @api
112 */
113void chMBReset(mailbox_t *mbp) {
114
115 chSysLock();
116 chMBResetI(mbp);
117 chSchRescheduleS();
118 chSysUnlock();
119}
120
121/**
122 * @brief Resets a @p mailbox_t object.
123 * @details All the waiting threads are resumed with status @p MSG_RESET and
124 * the queued messages are lost.
125 * @post The mailbox is in reset state, all operations will fail and
126 * return @p MSG_RESET until the mailbox is enabled again using
127 * @p chMBResumeX().
128 *
129 * @param[in] mbp the pointer to an initialized @p mailbox_t object
130 *
131 * @api
132 */
133void chMBResetI(mailbox_t *mbp) {
134
135 chDbgCheckClassI();
136 chDbgCheck(mbp != NULL);
137
138 mbp->wrptr = mbp->buffer;
139 mbp->rdptr = mbp->buffer;
140 mbp->cnt = (size_t)0;
141 mbp->reset = true;
142 chThdDequeueAllI(&mbp->qw, MSG_RESET);
143 chThdDequeueAllI(&mbp->qr, MSG_RESET);
144}
145
146/**
147 * @brief Posts a message into a mailbox.
148 * @details The invoking thread waits until a empty slot in the mailbox becomes
149 * available or the specified time runs out.
150 *
151 * @param[in] mbp the pointer to an initialized @p mailbox_t object
152 * @param[in] msg the message to be posted on the mailbox
153 * @param[in] timeout the number of ticks before the operation timeouts,
154 * the following special values are allowed:
155 * - @a TIME_IMMEDIATE immediate timeout.
156 * - @a TIME_INFINITE no timeout.
157 * .
158 * @return The operation status.
159 * @retval MSG_OK if a message has been correctly posted.
160 * @retval MSG_RESET if the mailbox has been reset.
161 * @retval MSG_TIMEOUT if the operation has timed out.
162 *
163 * @api
164 */
165msg_t chMBPostTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout) {
166 msg_t rdymsg;
167
168 chSysLock();
169 rdymsg = chMBPostTimeoutS(mbp, msg, timeout);
170 chSysUnlock();
171
172 return rdymsg;
173}
174
175/**
176 * @brief Posts a message into a mailbox.
177 * @details The invoking thread waits until a empty slot in the mailbox becomes
178 * available or the specified time runs out.
179 *
180 * @param[in] mbp the pointer to an initialized @p mailbox_t object
181 * @param[in] msg the message to be posted on the mailbox
182 * @param[in] timeout the number of ticks before the operation timeouts,
183 * the following special values are allowed:
184 * - @a TIME_IMMEDIATE immediate timeout.
185 * - @a TIME_INFINITE no timeout.
186 * .
187 * @return The operation status.
188 * @retval MSG_OK if a message has been correctly posted.
189 * @retval MSG_RESET if the mailbox has been reset.
190 * @retval MSG_TIMEOUT if the operation has timed out.
191 *
192 * @sclass
193 */
194msg_t chMBPostTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout) {
195 msg_t rdymsg;
196
197 chDbgCheckClassS();
198 chDbgCheck(mbp != NULL);
199
200 do {
201 /* If the mailbox is in reset state then returns immediately.*/
202 if (mbp->reset) {
203 return MSG_RESET;
204 }
205
206 /* Is there a free message slot in queue? if so then post.*/
207 if (chMBGetFreeCountI(mbp) > (size_t)0) {
208 *mbp->wrptr++ = msg;
209 if (mbp->wrptr >= mbp->top) {
210 mbp->wrptr = mbp->buffer;
211 }
212 mbp->cnt++;
213
214 /* If there is a reader waiting then makes it ready.*/
215 chThdDequeueNextI(&mbp->qr, MSG_OK);
216 chSchRescheduleS();
217
218 return MSG_OK;
219 }
220
221 /* No space in the queue, waiting for a slot to become available.*/
222 rdymsg = chThdEnqueueTimeoutS(&mbp->qw, timeout);
223 } while (rdymsg == MSG_OK);
224
225 return rdymsg;
226}
227
228/**
229 * @brief Posts a message into a mailbox.
230 * @details This variant is non-blocking, the function returns a timeout
231 * condition if the queue is full.
232 *
233 * @param[in] mbp the pointer to an initialized @p mailbox_t object
234 * @param[in] msg the message to be posted on the mailbox
235 * @return The operation status.
236 * @retval MSG_OK if a message has been correctly posted.
237 * @retval MSG_RESET if the mailbox has been reset.
238 * @retval MSG_TIMEOUT if the mailbox is full and the message cannot be
239 * posted.
240 *
241 * @iclass
242 */
243msg_t chMBPostI(mailbox_t *mbp, msg_t msg) {
244
245 chDbgCheckClassI();
246 chDbgCheck(mbp != NULL);
247
248 /* If the mailbox is in reset state then returns immediately.*/
249 if (mbp->reset) {
250 return MSG_RESET;
251 }
252
253 /* Is there a free message slot in queue? if so then post.*/
254 if (chMBGetFreeCountI(mbp) > (size_t)0) {
255 *mbp->wrptr++ = msg;
256 if (mbp->wrptr >= mbp->top) {
257 mbp->wrptr = mbp->buffer;
258 }
259 mbp->cnt++;
260
261 /* If there is a reader waiting then makes it ready.*/
262 chThdDequeueNextI(&mbp->qr, MSG_OK);
263
264 return MSG_OK;
265 }
266
267 /* No space, immediate timeout.*/
268 return MSG_TIMEOUT;
269}
270
271/**
272 * @brief Posts an high priority message into a mailbox.
273 * @details The invoking thread waits until a empty slot in the mailbox becomes
274 * available or the specified time runs out.
275 *
276 * @param[in] mbp the pointer to an initialized @p mailbox_t object
277 * @param[in] msg the message to be posted on the mailbox
278 * @param[in] timeout the number of ticks before the operation timeouts,
279 * the following special values are allowed:
280 * - @a TIME_IMMEDIATE immediate timeout.
281 * - @a TIME_INFINITE no timeout.
282 * .
283 * @return The operation status.
284 * @retval MSG_OK if a message has been correctly posted.
285 * @retval MSG_RESET if the mailbox has been reset.
286 * @retval MSG_TIMEOUT if the operation has timed out.
287 *
288 * @api
289 */
290msg_t chMBPostAheadTimeout(mailbox_t *mbp, msg_t msg, sysinterval_t timeout) {
291 msg_t rdymsg;
292
293 chSysLock();
294 rdymsg = chMBPostAheadTimeoutS(mbp, msg, timeout);
295 chSysUnlock();
296
297 return rdymsg;
298}
299
300/**
301 * @brief Posts an high priority message into a mailbox.
302 * @details The invoking thread waits until a empty slot in the mailbox becomes
303 * available or the specified time runs out.
304 *
305 * @param[in] mbp the pointer to an initialized @p mailbox_t object
306 * @param[in] msg the message to be posted on the mailbox
307 * @param[in] timeout the number of ticks before the operation timeouts,
308 * the following special values are allowed:
309 * - @a TIME_IMMEDIATE immediate timeout.
310 * - @a TIME_INFINITE no timeout.
311 * .
312 * @return The operation status.
313 * @retval MSG_OK if a message has been correctly posted.
314 * @retval MSG_RESET if the mailbox has been reset.
315 * @retval MSG_TIMEOUT if the operation has timed out.
316 *
317 * @sclass
318 */
319msg_t chMBPostAheadTimeoutS(mailbox_t *mbp, msg_t msg, sysinterval_t timeout) {
320 msg_t rdymsg;
321
322 chDbgCheckClassS();
323 chDbgCheck(mbp != NULL);
324
325 do {
326 /* If the mailbox is in reset state then returns immediately.*/
327 if (mbp->reset) {
328 return MSG_RESET;
329 }
330
331 /* Is there a free message slot in queue? if so then post.*/
332 if (chMBGetFreeCountI(mbp) > (size_t)0) {
333 if (--mbp->rdptr < mbp->buffer) {
334 mbp->rdptr = mbp->top - 1;
335 }
336 *mbp->rdptr = msg;
337 mbp->cnt++;
338
339 /* If there is a reader waiting then makes it ready.*/
340 chThdDequeueNextI(&mbp->qr, MSG_OK);
341 chSchRescheduleS();
342
343 return MSG_OK;
344 }
345
346 /* No space in the queue, waiting for a slot to become available.*/
347 rdymsg = chThdEnqueueTimeoutS(&mbp->qw, timeout);
348 } while (rdymsg == MSG_OK);
349
350 return rdymsg;
351}
352
353/**
354 * @brief Posts an high priority message into a mailbox.
355 * @details This variant is non-blocking, the function returns a timeout
356 * condition if the queue is full.
357 *
358 * @param[in] mbp the pointer to an initialized @p mailbox_t object
359 * @param[in] msg the message to be posted on the mailbox
360 * @return The operation status.
361 * @retval MSG_OK if a message has been correctly posted.
362 * @retval MSG_RESET if the mailbox has been reset.
363 * @retval MSG_TIMEOUT if the mailbox is full and the message cannot be
364 * posted.
365 *
366 * @iclass
367 */
368msg_t chMBPostAheadI(mailbox_t *mbp, msg_t msg) {
369
370 chDbgCheckClassI();
371 chDbgCheck(mbp != NULL);
372
373 /* If the mailbox is in reset state then returns immediately.*/
374 if (mbp->reset) {
375 return MSG_RESET;
376 }
377
378 /* Is there a free message slot in queue? if so then post.*/
379 if (chMBGetFreeCountI(mbp) > (size_t)0) {
380 if (--mbp->rdptr < mbp->buffer) {
381 mbp->rdptr = mbp->top - 1;
382 }
383 *mbp->rdptr = msg;
384 mbp->cnt++;
385
386 /* If there is a reader waiting then makes it ready.*/
387 chThdDequeueNextI(&mbp->qr, MSG_OK);
388
389 return MSG_OK;
390 }
391
392 /* No space, immediate timeout.*/
393 return MSG_TIMEOUT;
394}
395
396/**
397 * @brief Retrieves a message from a mailbox.
398 * @details The invoking thread waits until a message is posted in the mailbox
399 * or the specified time runs out.
400 *
401 * @param[in] mbp the pointer to an initialized @p mailbox_t object
402 * @param[out] msgp pointer to a message variable for the received message
403 * @param[in] timeout the number of ticks before the operation timeouts,
404 * the following special values are allowed:
405 * - @a TIME_IMMEDIATE immediate timeout.
406 * - @a TIME_INFINITE no timeout.
407 * .
408 * @return The operation status.
409 * @retval MSG_OK if a message has been correctly fetched.
410 * @retval MSG_RESET if the mailbox has been reset.
411 * @retval MSG_TIMEOUT if the operation has timed out.
412 *
413 * @api
414 */
415msg_t chMBFetchTimeout(mailbox_t *mbp, msg_t *msgp, sysinterval_t timeout) {
416 msg_t rdymsg;
417
418 chSysLock();
419 rdymsg = chMBFetchTimeoutS(mbp, msgp, timeout);
420 chSysUnlock();
421
422 return rdymsg;
423}
424
425/**
426 * @brief Retrieves a message from a mailbox.
427 * @details The invoking thread waits until a message is posted in the mailbox
428 * or the specified time runs out.
429 *
430 * @param[in] mbp the pointer to an initialized @p mailbox_t object
431 * @param[out] msgp pointer to a message variable for the received message
432 * @param[in] timeout the number of ticks before the operation timeouts,
433 * the following special values are allowed:
434 * - @a TIME_IMMEDIATE immediate timeout.
435 * - @a TIME_INFINITE no timeout.
436 * .
437 * @return The operation status.
438 * @retval MSG_OK if a message has been correctly fetched.
439 * @retval MSG_RESET if the mailbox has been reset.
440 * @retval MSG_TIMEOUT if the operation has timed out.
441 *
442 * @sclass
443 */
444msg_t chMBFetchTimeoutS(mailbox_t *mbp, msg_t *msgp, sysinterval_t timeout) {
445 msg_t rdymsg;
446
447 chDbgCheckClassS();
448 chDbgCheck((mbp != NULL) && (msgp != NULL));
449
450 do {
451 /* If the mailbox is in reset state then returns immediately.*/
452 if (mbp->reset) {
453 return MSG_RESET;
454 }
455
456 /* Is there a message in queue? if so then fetch.*/
457 if (chMBGetUsedCountI(mbp) > (size_t)0) {
458 *msgp = *mbp->rdptr++;
459 if (mbp->rdptr >= mbp->top) {
460 mbp->rdptr = mbp->buffer;
461 }
462 mbp->cnt--;
463
464 /* If there is a writer waiting then makes it ready.*/
465 chThdDequeueNextI(&mbp->qw, MSG_OK);
466 chSchRescheduleS();
467
468 return MSG_OK;
469 }
470
471 /* No message in the queue, waiting for a message to become available.*/
472 rdymsg = chThdEnqueueTimeoutS(&mbp->qr, timeout);
473 } while (rdymsg == MSG_OK);
474
475 return rdymsg;
476}
477
478/**
479 * @brief Retrieves a message from a mailbox.
480 * @details This variant is non-blocking, the function returns a timeout
481 * condition if the queue is empty.
482 *
483 * @param[in] mbp the pointer to an initialized @p mailbox_t object
484 * @param[out] msgp pointer to a message variable for the received message
485 * @return The operation status.
486 * @retval MSG_OK if a message has been correctly fetched.
487 * @retval MSG_RESET if the mailbox has been reset.
488 * @retval MSG_TIMEOUT if the mailbox is empty and a message cannot be
489 * fetched.
490 *
491 * @iclass
492 */
493msg_t chMBFetchI(mailbox_t *mbp, msg_t *msgp) {
494
495 chDbgCheckClassI();
496 chDbgCheck((mbp != NULL) && (msgp != NULL));
497
498 /* If the mailbox is in reset state then returns immediately.*/
499 if (mbp->reset) {
500 return MSG_RESET;
501 }
502
503 /* Is there a message in queue? if so then fetch.*/
504 if (chMBGetUsedCountI(mbp) > (size_t)0) {
505 *msgp = *mbp->rdptr++;
506 if (mbp->rdptr >= mbp->top) {
507 mbp->rdptr = mbp->buffer;
508 }
509 mbp->cnt--;
510
511 /* If there is a writer waiting then makes it ready.*/
512 chThdDequeueNextI(&mbp->qw, MSG_OK);
513
514 return MSG_OK;
515 }
516
517 /* No message, immediate timeout.*/
518 return MSG_TIMEOUT;
519}
520#endif /* CH_CFG_USE_MAILBOXES == TRUE */
521
522/** @} */
diff --git a/lib/chibios/os/oslib/src/chmemcore.c b/lib/chibios/os/oslib/src/chmemcore.c
new file mode 100644
index 000000000..0c081aa48
--- /dev/null
+++ b/lib/chibios/os/oslib/src/chmemcore.c
@@ -0,0 +1,227 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/src/chmemcore.c
22 * @brief Core memory manager code.
23 *
24 * @addtogroup oslib_memcore
25 * @details Core Memory Manager related APIs and services.
26 * <h2>Operation mode</h2>
27 * The core memory manager is a simplified allocator that only
28 * allows to allocate memory blocks without the possibility to
29 * free them.<br>
30 * This allocator is meant as a memory blocks provider for the
31 * other allocators such as:
32 * - C-Runtime allocator (through a compiler specific adapter module).
33 * - Heap allocator (see @ref oslib_memheaps).
34 * - Memory pools allocator (see @ref oslib_mempools).
35 * .
36 * By having a centralized memory provider the various allocators
37 * can coexist and share the main memory.<br>
38 * This allocator, alone, is also useful for very simple
39 * applications that just require a simple way to get memory
40 * blocks.
41 * @pre In order to use the core memory manager APIs the @p CH_CFG_USE_MEMCORE
42 * option must be enabled in @p chconf.h.
43 * @note Compatible with RT and NIL.
44 * @{
45 */
46
47#include "ch.h"
48
49#if (CH_CFG_USE_MEMCORE == TRUE) || defined(__DOXYGEN__)
50
51/*===========================================================================*/
52/* Module exported variables. */
53/*===========================================================================*/
54
55/**
56 * @brief Memory core descriptor.
57 */
58memcore_t ch_memcore;
59
60/*===========================================================================*/
61/* Module local types. */
62/*===========================================================================*/
63
64/*===========================================================================*/
65/* Module local variables. */
66/*===========================================================================*/
67
68/*===========================================================================*/
69/* Module local functions. */
70/*===========================================================================*/
71
72/*===========================================================================*/
73/* Module exported functions. */
74/*===========================================================================*/
75
76/**
77 * @brief Low level memory manager initialization.
78 *
79 * @notapi
80 */
81void _core_init(void) {
82#if CH_CFG_MEMCORE_SIZE == 0
83 extern uint8_t __heap_base__[];
84 extern uint8_t __heap_end__[];
85
86 /*lint -save -e9033 [10.8] Required cast operations.*/
87 ch_memcore.basemem = __heap_base__;
88 ch_memcore.topmem = __heap_end__;
89 /*lint restore*/
90#else
91 static uint8_t static_heap[CH_CFG_MEMCORE_SIZE];
92
93 ch_memcore.basemem = &static_heap[0];
94 ch_memcore.topmem = &static_heap[CH_CFG_MEMCORE_SIZE];
95#endif
96}
97
98/**
99 * @brief Allocates a memory block starting from the lowest address upward.
100 * @details This function allocates a block of @p offset + @p size bytes. The
101 * returned pointer has @p offset bytes before its address and
102 * @p size bytes after.
103 *
104 * @param[in] size the size of the block to be allocated.
105 * @param[in] align desired memory alignment
106 * @param[in] offset aligned pointer offset
107 * @return A pointer to the allocated memory block.
108 * @retval NULL allocation failed, core memory exhausted.
109 *
110 * @iclass
111 */
112void *chCoreAllocFromBaseI(size_t size, unsigned align, size_t offset) {
113 uint8_t *p, *next;
114
115 chDbgCheckClassI();
116 chDbgCheck(MEM_IS_VALID_ALIGNMENT(align));
117
118 p = (uint8_t *)MEM_ALIGN_NEXT(ch_memcore.basemem + offset, align);
119 next = p + size;
120
121 /* Considering also the case where there is numeric overflow.*/
122 if ((next > ch_memcore.topmem) || (next < ch_memcore.basemem)) {
123 return NULL;
124 }
125
126 ch_memcore.basemem = next;
127
128 return p;
129}
130
131/**
132 * @brief Allocates a memory block starting from the top address downward.
133 * @details This function allocates a block of @p offset + @p size bytes. The
134 * returned pointer has @p offset bytes before its address and
135 * @p size bytes after.
136 *
137 * @param[in] size the size of the block to be allocated.
138 * @param[in] align desired memory alignment
139 * @param[in] offset aligned pointer offset
140 * @return A pointer to the allocated memory block.
141 * @retval NULL allocation failed, core memory exhausted.
142 *
143 * @iclass
144 */
145void *chCoreAllocFromTopI(size_t size, unsigned align, size_t offset) {
146 uint8_t *p, *prev;
147
148 chDbgCheckClassI();
149 chDbgCheck(MEM_IS_VALID_ALIGNMENT(align));
150
151 p = (uint8_t *)MEM_ALIGN_PREV(ch_memcore.topmem - size, align);
152 prev = p - offset;
153
154 /* Considering also the case where there is numeric overflow.*/
155 if ((prev < ch_memcore.basemem) || (prev > ch_memcore.topmem)) {
156 return NULL;
157 }
158
159 ch_memcore.topmem = prev;
160
161 return p;
162}
163
164/**
165 * @brief Allocates a memory block starting from the lowest address upward.
166 * @details This function allocates a block of @p offset + @p size bytes. The
167 * returned pointer has @p offset bytes before its address and
168 * @p size bytes after.
169 *
170 * @param[in] size the size of the block to be allocated.
171 * @param[in] align desired memory alignment
172 * @param[in] offset aligned pointer offset
173 * @return A pointer to the allocated memory block.
174 * @retval NULL allocation failed, core memory exhausted.
175 *
176 * @api
177 */
178void *chCoreAllocFromBase(size_t size, unsigned align, size_t offset) {
179 void *p;
180
181 chSysLock();
182 p = chCoreAllocFromBaseI(size, align, offset);
183 chSysUnlock();
184
185 return p;
186}
187
188/**
189 * @brief Allocates a memory block starting from the top address downward.
190 * @details This function allocates a block of @p offset + @p size bytes. The
191 * returned pointer has @p offset bytes before its address and
192 * @p size bytes after.
193 *
194 * @param[in] size the size of the block to be allocated.
195 * @param[in] align desired memory alignment
196 * @param[in] offset aligned pointer offset
197 * @return A pointer to the allocated memory block.
198 * @retval NULL allocation failed, core memory exhausted.
199 *
200 * @api
201 */
202void *chCoreAllocFromTop(size_t size, unsigned align, size_t offset) {
203 void *p;
204
205 chSysLock();
206 p = chCoreAllocFromTopI(size, align, offset);
207 chSysUnlock();
208
209 return p;
210}
211
212/**
213 * @brief Core memory status.
214 *
215 * @return The size, in bytes, of the free core memory.
216 *
217 * @xclass
218 */
219size_t chCoreGetStatusX(void) {
220
221 /*lint -save -e9033 [10.8] The cast is safe.*/
222 return (size_t)(ch_memcore.topmem - ch_memcore.basemem);
223 /*lint -restore*/
224}
225#endif /* CH_CFG_USE_MEMCORE == TRUE */
226
227/** @} */
diff --git a/lib/chibios/os/oslib/src/chmemheaps.c b/lib/chibios/os/oslib/src/chmemheaps.c
new file mode 100644
index 000000000..d5d272317
--- /dev/null
+++ b/lib/chibios/os/oslib/src/chmemheaps.c
@@ -0,0 +1,399 @@
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/src/chmemheaps.c
22 * @brief Memory heaps code.
23 *
24 * @addtogroup oslib_memheaps
25 * @details Heap Allocator related APIs.
26 * <h2>Operation mode</h2>
27 * The heap allocator implements a first-fit strategy and its APIs
28 * are functionally equivalent to the usual @p malloc() and @p free()
29 * library functions. The main difference is that the OS heap APIs
30 * are guaranteed to be thread safe and there is the ability to
31 * return memory blocks aligned to arbitrary powers of two.<br>
32 * @pre In order to use the heap APIs the @p CH_CFG_USE_HEAP option must
33 * be enabled in @p chconf.h.
34 * @note Compatible with RT and NIL.
35 * @{
36 */
37
38#include "ch.h"
39
40#if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__)
41
42/*===========================================================================*/
43/* Module local definitions. */
44/*===========================================================================*/
45
46/*
47 * Defaults on the best synchronization mechanism available.
48 */
49#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
50#define H_LOCK(h) chMtxLock(&(h)->mtx)
51#define H_UNLOCK(h) chMtxUnlock(&(h)->mtx)
52#else
53#define H_LOCK(h) (void) chSemWait(&(h)->sem)
54#define H_UNLOCK(h) chSemSignal(&(h)->sem)
55#endif
56
57#define H_BLOCK(hp) ((hp) + 1U)
58
59#define H_LIMIT(hp) (H_BLOCK(hp) + H_PAGES(hp))
60
61#define H_NEXT(hp) ((hp)->free.next)
62
63#define H_PAGES(hp) ((hp)->free.pages)
64
65#define H_HEAP(hp) ((hp)->used.heap)
66
67#define H_SIZE(hp) ((hp)->used.size)
68
69/*
70 * Number of pages between two pointers in a MISRA-compatible way.
71 */
72#define NPAGES(p1, p2) \
73 /*lint -save -e9033 [10.8] The cast is safe.*/ \
74 ((size_t)((p1) - (p2))) \
75 /*lint -restore*/
76
77/*===========================================================================*/
78/* Module exported variables. */
79/*===========================================================================*/
80
81/*===========================================================================*/
82/* Module local types. */
83/*===========================================================================*/
84
85/*===========================================================================*/
86/* Module local variables. */
87/*===========================================================================*/
88
89/**
90 * @brief Default heap descriptor.
91 */
92static memory_heap_t default_heap;
93
94/*===========================================================================*/
95/* Module local functions. */
96/*===========================================================================*/
97
98/*===========================================================================*/
99/* Module exported functions. */
100/*===========================================================================*/
101
102/**
103 * @brief Initializes the default heap.
104 *
105 * @notapi
106 */
107void _heap_init(void) {
108
109 default_heap.provider = chCoreAllocAlignedWithOffset;
110 H_NEXT(&default_heap.header) = NULL;
111 H_PAGES(&default_heap.header) = 0;
112#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
113 chMtxObjectInit(&default_heap.mtx);
114#else
115 chSemObjectInit(&default_heap.sem, (cnt_t)1);
116#endif
117}
118
119/**
120 * @brief Initializes a memory heap from a static memory area.
121 * @note The heap buffer base and size are adjusted if the passed buffer
122 * is not aligned to @p CH_HEAP_ALIGNMENT. This mean that the
123 * effective heap size can be less than @p size.
124 *
125 * @param[out] heapp pointer to the memory heap descriptor to be initialized
126 * @param[in] buf heap buffer base
127 * @param[in] size heap size
128 *
129 * @init
130 */
131void chHeapObjectInit(memory_heap_t *heapp, void *buf, size_t size) {
132 heap_header_t *hp = (heap_header_t *)MEM_ALIGN_NEXT(buf, CH_HEAP_ALIGNMENT);
133
134 chDbgCheck((heapp != NULL) && (size > 0U));
135
136 /* Adjusting the size in case the initial block was not correctly
137 aligned.*/
138 /*lint -save -e9033 [10.8] Required cast operations.*/
139 size -= (size_t)((uint8_t *)hp - (uint8_t *)buf);
140 /*lint restore*/
141
142 /* Initializing the heap header.*/
143 heapp->provider = NULL;
144 H_NEXT(&heapp->header) = hp;
145 H_PAGES(&heapp->header) = 0;
146 H_NEXT(hp) = NULL;
147 H_PAGES(hp) = (size - sizeof (heap_header_t)) / CH_HEAP_ALIGNMENT;
148#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
149 chMtxObjectInit(&heapp->mtx);
150#else
151 chSemObjectInit(&heapp->sem, (cnt_t)1);
152#endif
153}
154
155/**
156 * @brief Allocates a block of memory from the heap by using the first-fit
157 * algorithm.
158 * @details The allocated block is guaranteed to be properly aligned to the
159 * specified alignment.
160 *
161 * @param[in] heapp pointer to a heap descriptor or @p NULL in order to
162 * access the default heap.
163 * @param[in] size the size of the block to be allocated. Note that the
164 * allocated block may be a bit bigger than the requested
165 * size for alignment and fragmentation reasons.
166 * @param[in] align desired memory alignment
167 * @return A pointer to the aligned allocated block.
168 * @retval NULL if the block cannot be allocated.
169 *
170 * @api
171 */
172void *chHeapAllocAligned(memory_heap_t *heapp, size_t size, unsigned align) {
173 heap_header_t *qp, *hp, *ahp;
174 size_t pages;
175
176 chDbgCheck((size > 0U) && MEM_IS_VALID_ALIGNMENT(align));
177
178 /* If an heap is not specified then the default system header is used.*/
179 if (heapp == NULL) {
180 heapp = &default_heap;
181 }
182
183 /* Minimum alignment is constrained by the heap header structure size.*/
184 if (align < CH_HEAP_ALIGNMENT) {
185 align = CH_HEAP_ALIGNMENT;
186 }
187
188 /* Size is converted in number of elementary allocation units.*/
189 pages = MEM_ALIGN_NEXT(size, CH_HEAP_ALIGNMENT) / CH_HEAP_ALIGNMENT;
190
191 /* Taking heap mutex/semaphore.*/
192 H_LOCK(heapp);
193
194 /* Start of the free blocks list.*/
195 qp = &heapp->header;
196 while (H_NEXT(qp) != NULL) {
197
198 /* Next free block.*/
199 hp = H_NEXT(qp);
200
201 /* Pointer aligned to the requested alignment.*/
202 ahp = (heap_header_t *)MEM_ALIGN_NEXT(H_BLOCK(hp), align) - 1U;
203
204 if ((ahp < H_LIMIT(hp)) && (pages <= NPAGES(H_LIMIT(hp), ahp + 1U))) {
205 /* The block is large enough to contain a correctly aligned area
206 of sufficient size.*/
207
208 if (ahp > hp) {
209 /* The block is not properly aligned, must split it.*/
210 size_t bpages;
211
212 bpages = NPAGES(H_LIMIT(hp), H_BLOCK(ahp));
213 H_PAGES(hp) = NPAGES(ahp, H_BLOCK(hp));
214 if (bpages > pages) {
215 /* The block is bigger than required, must split the excess.*/
216 heap_header_t *fp;
217
218 /* Creating the excess block.*/
219 fp = H_BLOCK(ahp) + pages;
220 H_PAGES(fp) = (bpages - pages) - 1U;
221
222 /* Linking the excess block.*/
223 H_NEXT(fp) = H_NEXT(hp);
224 H_NEXT(hp) = fp;
225 }
226
227 hp = ahp;
228 }
229 else {
230 /* The block is already properly aligned.*/
231
232 if (H_PAGES(hp) == pages) {
233 /* Exact size, getting the whole block.*/
234 H_NEXT(qp) = H_NEXT(hp);
235 }
236 else {
237 /* The block is bigger than required, must split the excess.*/
238 heap_header_t *fp;
239
240 fp = H_BLOCK(hp) + pages;
241 H_NEXT(fp) = H_NEXT(hp);
242 H_PAGES(fp) = NPAGES(H_LIMIT(hp), H_BLOCK(fp));
243 H_NEXT(qp) = fp;
244 }
245 }
246
247 /* Setting in the block owner heap and size.*/
248 H_SIZE(hp) = size;
249 H_HEAP(hp) = heapp;
250
251 /* Releasing heap mutex/semaphore.*/
252 H_UNLOCK(heapp);
253
254 /*lint -save -e9087 [11.3] Safe cast.*/
255 return (void *)H_BLOCK(hp);
256 /*lint -restore*/
257 }
258
259 /* Next in the free blocks list.*/
260 qp = hp;
261 }
262
263 /* Releasing heap mutex/semaphore.*/
264 H_UNLOCK(heapp);
265
266 /* More memory is required, tries to get it from the associated provider
267 else fails.*/
268 if (heapp->provider != NULL) {
269 ahp = heapp->provider(pages * CH_HEAP_ALIGNMENT,
270 align,
271 sizeof (heap_header_t));
272 if (ahp != NULL) {
273 hp = ahp - 1U;
274 H_HEAP(hp) = heapp;
275 H_SIZE(hp) = size;
276
277 /*lint -save -e9087 [11.3] Safe cast.*/
278 return (void *)ahp;
279 /*lint -restore*/
280 }
281 }
282
283 return NULL;
284}
285
286/**
287 * @brief Frees a previously allocated memory block.
288 *
289 * @param[in] p pointer to the memory block to be freed
290 *
291 * @api
292 */
293void chHeapFree(void *p) {
294 heap_header_t *qp, *hp;
295 memory_heap_t *heapp;
296
297 chDbgCheck((p != NULL) && MEM_IS_ALIGNED(p, CH_HEAP_ALIGNMENT));
298
299 /*lint -save -e9087 [11.3] Safe cast.*/
300 hp = (heap_header_t *)p - 1U;
301 /*lint -restore*/
302 heapp = H_HEAP(hp);
303 qp = &heapp->header;
304
305 /* Size is converted in number of elementary allocation units.*/
306 H_PAGES(hp) = MEM_ALIGN_NEXT(H_SIZE(hp),
307 CH_HEAP_ALIGNMENT) / CH_HEAP_ALIGNMENT;
308
309 /* Taking heap mutex/semaphore.*/
310 H_LOCK(heapp);