aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios/os/hal/osal
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios/os/hal/osal')
-rw-r--r--lib/chibios/os/hal/osal/lib/osal_vt.c168
-rw-r--r--lib/chibios/os/hal/osal/lib/osal_vt.h123
-rw-r--r--lib/chibios/os/hal/osal/os-less/ARMCMx/osal.c467
-rw-r--r--lib/chibios/os/hal/osal/os-less/ARMCMx/osal.h754
-rw-r--r--lib/chibios/os/hal/osal/os-less/ARMCMx/osal.mk11
-rw-r--r--lib/chibios/os/hal/osal/os-less/AVR/osal.c467
-rw-r--r--lib/chibios/os/hal/osal/os-less/AVR/osal.h677
-rw-r--r--lib/chibios/os/hal/osal/os-less/AVR/osal.mk9
-rw-r--r--lib/chibios/os/hal/osal/rt-nil/osal.c51
-rw-r--r--lib/chibios/os/hal/osal/rt-nil/osal.h1092
-rw-r--r--lib/chibios/os/hal/osal/rt-nil/osal.mk9
11 files changed, 3828 insertions, 0 deletions
diff --git a/lib/chibios/os/hal/osal/lib/osal_vt.c b/lib/chibios/os/hal/osal/lib/osal_vt.c
new file mode 100644
index 000000000..29f60dfb5
--- /dev/null
+++ b/lib/chibios/os/hal/osal/lib/osal_vt.c
@@ -0,0 +1,168 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file osal_vt.c
19 * @brief OSAL Virtual Timers module code.
20 * @details This module can be used in an OSAL implementation whenever an
21 * underlying RTOS is unable to provide timeout services or there
22 * is no underlying RTOS.
23 *
24 * @addtogroup OSAL_VT
25 * @{
26 */
27
28#include "osal.h"
29#include "osal_vt.h"
30
31/*===========================================================================*/
32/* Module local definitions. */
33/*===========================================================================*/
34
35/*===========================================================================*/
36/* Module exported variables. */
37/*===========================================================================*/
38
39/**
40 * @brief Virtual timers delta list header.
41 */
42virtual_timers_list_t vtlist;
43
44/*===========================================================================*/
45/* Module local types. */
46/*===========================================================================*/
47
48/*===========================================================================*/
49/* Module local variables. */
50/*===========================================================================*/
51
52/*===========================================================================*/
53/* Module local functions. */
54/*===========================================================================*/
55
56/*===========================================================================*/
57/* Module exported functions. */
58/*===========================================================================*/
59
60/**
61 * @brief Timers initialization.
62 *
63 * @init
64 */
65void vtInit(void) {
66
67 /* Virtual Timers initialization.*/
68 vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist;
69 vtlist.vt_delta = (sysinterval_t)-1;
70 vtlist.vt_systime = 0;
71}
72
73/**
74 * @brief Returns @p TRUE if the specified timer is armed.
75 *
76 * @param[out] vtp the @p virtual_timer_t structure pointer
77 *
78 * @iclass
79 */
80bool vtIsArmedI(virtual_timer_t *vtp) {
81
82 return vtp->vt_func != NULL;
83}
84
85/**
86 * @brief Virtual timers ticker.
87 * @note The system lock is released before entering the callback and
88 * re-acquired immediately after. It is callback's responsibility
89 * to acquire the lock if needed. This is done in order to reduce
90 * interrupts jitter when many timers are in use.
91 *
92 * @iclass
93 */
94void vtDoTickI(void) {
95
96 vtlist.vt_systime++;
97 if (&vtlist != (virtual_timers_list_t *)vtlist.vt_next) {
98 virtual_timer_t *vtp;
99
100 --vtlist.vt_next->vt_delta;
101 while (!(vtp = vtlist.vt_next)->vt_delta) {
102 vtfunc_t fn = vtp->vt_func;
103 vtp->vt_func = (vtfunc_t)NULL;
104 vtp->vt_next->vt_prev = (void *)&vtlist;
105 (&vtlist)->vt_next = vtp->vt_next;
106 osalSysUnlockFromISR();
107 fn(vtp->vt_par);
108 osalSysLockFromISR();
109 }
110 }
111}
112
113/**
114 * @brief Enables a virtual timer.
115 * @note The associated function is invoked from interrupt context.
116 *
117 * @param[out] vtp the @p virtual_timer_t structure pointer
118 * @param[in] timeout the number of ticks before the operation timeouts, the
119 * special values are handled as follow:
120 * - @a TIME_INFINITE is allowed but interpreted as a
121 * normal time specification.
122 * - @a TIME_IMMEDIATE this value is not allowed.
123 * .
124 * @param[in] vtfunc the timer callback function. After invoking the
125 * callback the timer is disabled and the structure can
126 * be disposed or reused.
127 * @param[in] par a parameter that will be passed to the callback
128 * function
129 *
130 * @iclass
131 */
132void vtSetI(virtual_timer_t *vtp, sysinterval_t timeout,
133 vtfunc_t vtfunc, void *par) {
134 virtual_timer_t *p;
135
136 vtp->vt_par = par;
137 vtp->vt_func = vtfunc;
138 p = vtlist.vt_next;
139 while (p->vt_delta < timeout) {
140 timeout -= p->vt_delta;
141 p = p->vt_next;
142 }
143
144 vtp->vt_prev = (vtp->vt_next = p)->vt_prev;
145 vtp->vt_prev->vt_next = p->vt_prev = vtp;
146 vtp->vt_delta = timeout;
147 if (p != (void *)&vtlist)
148 p->vt_delta -= timeout;
149}
150
151/**
152 * @brief Disables a Virtual Timer.
153 * @note The timer MUST be active when this function is invoked.
154 *
155 * @param[in] vtp the @p virtual_timer_t structure pointer
156 *
157 * @iclass
158 */
159void vtResetI(virtual_timer_t *vtp) {
160
161 if (vtp->vt_next != (void *)&vtlist)
162 vtp->vt_next->vt_delta += vtp->vt_delta;
163 vtp->vt_prev->vt_next = vtp->vt_next;
164 vtp->vt_next->vt_prev = vtp->vt_prev;
165 vtp->vt_func = (vtfunc_t)NULL;
166}
167
168/** @} */
diff --git a/lib/chibios/os/hal/osal/lib/osal_vt.h b/lib/chibios/os/hal/osal/lib/osal_vt.h
new file mode 100644
index 000000000..41373418b
--- /dev/null
+++ b/lib/chibios/os/hal/osal/lib/osal_vt.h
@@ -0,0 +1,123 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file osal_vt.h
19 * @brief OSAL Virtual Timers module header.
20 *
21 * @addtogroup OSAL_VT
22 * @{
23 */
24
25#ifndef _OSAL_VT_H_
26#define _OSAL_VT_H_
27
28/*===========================================================================*/
29/* Module constants. */
30/*===========================================================================*/
31
32/*===========================================================================*/
33/* Module pre-compile time settings. */
34/*===========================================================================*/
35
36/*===========================================================================*/
37/* Derived constants and error checks. */
38/*===========================================================================*/
39
40/*===========================================================================*/
41/* Module data structures and types. */
42/*===========================================================================*/
43
44/**
45 * @brief Type of a Virtual Timer callback function.
46 */
47typedef void (*vtfunc_t)(void *);
48
49/**
50 * @brief Type of a Virtual Timer structure.
51 */
52typedef struct virtual_timer virtual_timer_t;
53
54/**
55 * @brief Virtual timers list header.
56 * @note The content of this structure is not part of the API and should
57 * not be relied upon. Implementers may define this structure in
58 * an entirely different way.
59 * @note The delta list is implemented as a double link bidirectional list
60 * in order to make the unlink time constant, the reset of a virtual
61 * timer is often used in the code.
62 */
63typedef struct {
64 virtual_timer_t *vt_next; /**< @brief Next timer in the timers
65 list. */
66 virtual_timer_t *vt_prev; /**< @brief Last timer in the timers
67 list. */
68 sysinterval_t vt_delta; /**< @brief Must be initialized to -1. */
69 volatile systime_t vt_systime; /**< @brief System Time counter. */
70} virtual_timers_list_t;
71
72/**
73 * @extends virtual_timers_list_t
74 *
75 * @brief Virtual Timer descriptor structure.
76 * @note The content of this structure is not part of the API and should
77 * not be relied upon. Implementers may define this structure in
78 * an entirely different way.
79 */
80struct virtual_timer {
81 virtual_timer_t *vt_next; /**< @brief Next timer in the timers
82 list. */
83 virtual_timer_t *vt_prev; /**< @brief Previous timer in the timers
84 list. */
85 sysinterval_t vt_delta; /**< @brief Time delta before timeout. */
86 vtfunc_t vt_func; /**< @brief Timer callback function
87 pointer. */
88 void *vt_par; /**< @brief Timer callback function
89 parameter. */
90};
91
92/*===========================================================================*/
93/* Module macros. */
94/*===========================================================================*/
95
96/*===========================================================================*/
97/* External declarations. */
98/*===========================================================================*/
99
100#if !defined(__DOXYGEN__)
101extern virtual_timers_list_t vtlist;
102#endif
103
104#ifdef __cplusplus
105extern "C" {
106#endif
107 void vtInit(void);
108 bool vtIsArmedI(virtual_timer_t *vtp);
109 void vtDoTickI(void);
110 void vtSetI(virtual_timer_t *vtp, sysinterval_t timeout,
111 vtfunc_t vtfunc, void *par);
112 void vtResetI(virtual_timer_t *vtp);
113#ifdef __cplusplus
114}
115#endif
116
117/*===========================================================================*/
118/* Module inline functions. */
119/*===========================================================================*/
120
121#endif /* _OSAL_VT_H_ */
122
123/** @} */
diff --git a/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.c b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.c
new file mode 100644
index 000000000..a4cb7aabf
--- /dev/null
+++ b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.c
@@ -0,0 +1,467 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file osal.c
19 * @brief OSAL module code.
20 *
21 * @addtogroup OSAL
22 * @{
23 */
24
25#include "osal.h"
26#include "osal_vt.h"
27
28/*===========================================================================*/
29/* Module local definitions. */
30/*===========================================================================*/
31
32/*===========================================================================*/
33/* Module exported variables. */
34/*===========================================================================*/
35
36/**
37 * @brief Pointer to a halt error message.
38 * @note The message is meant to be retrieved by the debugger after the
39 * system halt caused by an unexpected error.
40 */
41const char *osal_halt_msg;
42
43/*===========================================================================*/
44/* Module local types. */
45/*===========================================================================*/
46
47/*===========================================================================*/
48/* Module local variables. */
49/*===========================================================================*/
50
51/*===========================================================================*/
52/* Module local functions. */
53/*===========================================================================*/
54
55static void callback_timeout(void *p) {
56 osalSysLockFromISR();
57 osalThreadResumeI((thread_reference_t *)p, MSG_TIMEOUT);
58 osalSysUnlockFromISR();
59}
60
61/*===========================================================================*/
62/* Module exported functions. */
63/*===========================================================================*/
64
65/**
66 * @brief OSAL module initialization.
67 *
68 * @api
69 */
70void osalInit(void) {
71
72 vtInit();
73
74 OSAL_INIT_HOOK();
75}
76
77/**
78 * @brief System halt with error message.
79 *
80 * @param[in] reason the halt message pointer
81 *
82 * @api
83 */
84#if !defined(__DOXYGEN__)
85__attribute__((weak, noreturn))
86#endif
87void osalSysHalt(const char *reason) {
88
89 osalSysDisable();
90 osal_halt_msg = reason;
91 while (true) {
92 }
93}
94
95/**
96 * @brief Polled delay.
97 * @note The real delay is always few cycles in excess of the specified
98 * value.
99 *
100 * @param[in] cycles number of cycles
101 *
102 * @xclass
103 */
104void osalSysPolledDelayX(rtcnt_t cycles) {
105
106 (void)cycles;
107}
108
109/**
110 * @brief System timer handler.
111 * @details The handler is used for scheduling and Virtual Timers management.
112 *
113 * @iclass
114 */
115void osalOsTimerHandlerI(void) {
116
117 osalDbgCheckClassI();
118
119 vtDoTickI();
120}
121
122/**
123 * @brief Checks if a reschedule is required and performs it.
124 * @note I-Class functions invoked from thread context must not reschedule
125 * by themselves, an explicit reschedule using this function is
126 * required in this scenario.
127 * @note Not implemented in this simplified OSAL.
128 *
129 * @sclass
130 */
131void osalOsRescheduleS(void) {
132
133}
134
135/**
136 * @brief Current system time.
137 * @details Returns the number of system ticks since the @p osalInit()
138 * invocation.
139 * @note The counter can reach its maximum and then restart from zero.
140 * @note This function can be called from any context but its atomicity
141 * is not guaranteed on architectures whose word size is less than
142 * @p systime_t size.
143 *
144 * @return The system time in ticks.
145 *
146 * @xclass
147 */
148systime_t osalOsGetSystemTimeX(void) {
149
150 return vtlist.vt_systime;
151}
152
153/**
154 * @brief Suspends the invoking thread for the specified time.
155 *
156 * @param[in] time the delay in system ticks, the special values are
157 * handled as follow:
158 * - @a TIME_INFINITE is allowed but interpreted as a
159 * normal time specification.
160 * - @a TIME_IMMEDIATE this value is not allowed.
161 * .
162 *
163 * @sclass
164 */
165void osalThreadSleepS(sysinterval_t time) {
166 virtual_timer_t vt;
167 thread_reference_t tr;
168
169 tr = NULL;
170 vtSetI(&vt, time, callback_timeout, (void *)&tr);
171 osalThreadSuspendS(&tr);
172}
173
174/**
175 * @brief Suspends the invoking thread for the specified time.
176 *
177 * @param[in] time the delay in system ticks, the special values are
178 * handled as follow:
179 * - @a TIME_INFINITE is allowed but interpreted as a
180 * normal time specification.
181 * - @a TIME_IMMEDIATE this value is not allowed.
182 * .
183 *
184 * @api
185 */
186void osalThreadSleep(sysinterval_t time) {
187
188 osalSysLock();
189 osalThreadSleepS(time);
190 osalSysUnlock();
191}
192
193/**
194 * @brief Sends the current thread sleeping and sets a reference variable.
195 * @note This function must reschedule, it can only be called from thread
196 * context.
197 *
198 * @param[in] trp a pointer to a thread reference object
199 * @return The wake up message.
200 *
201 * @sclass
202 */
203msg_t osalThreadSuspendS(thread_reference_t *trp) {
204 thread_t self = {MSG_WAIT};
205
206 osalDbgCheck(trp != NULL);
207
208 *trp = &self;
209 while (self.message == MSG_WAIT) {
210 osalSysUnlock();
211 /* A state-changing interrupt could occur here and cause the loop to
212 terminate, an hook macro is executed while waiting.*/
213 OSAL_IDLE_HOOK();
214 osalSysLock();
215 }
216
217 return self.message;
218}
219
220/**
221 * @brief Sends the current thread sleeping and sets a reference variable.
222 * @note This function must reschedule, it can only be called from thread
223 * context.
224 *
225 * @param[in] trp a pointer to a thread reference object
226 * @param[in] timeout the timeout in system ticks, the special values are
227 * handled as follow:
228 * - @a TIME_INFINITE the thread enters an infinite sleep
229 * state.
230 * - @a TIME_IMMEDIATE the thread is not enqueued and
231 * the function returns @p MSG_TIMEOUT as if a timeout
232 * occurred.
233 * .
234 * @return The wake up message.
235 * @retval MSG_TIMEOUT if the operation timed out.
236 *
237 * @sclass
238 */
239msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout) {
240 msg_t msg;
241 virtual_timer_t vt;
242
243 osalDbgCheck(trp != NULL);
244
245 if (TIME_INFINITE == timeout)
246 return osalThreadSuspendS(trp);
247
248 vtSetI(&vt, timeout, callback_timeout, (void *)trp);
249 msg = osalThreadSuspendS(trp);
250 if (vtIsArmedI(&vt))
251 vtResetI(&vt);
252
253 return msg;
254}
255
256/**
257 * @brief Wakes up a thread waiting on a thread reference object.
258 * @note This function must not reschedule because it can be called from
259 * ISR context.
260 *
261 * @param[in] trp a pointer to a thread reference object
262 * @param[in] msg the message code
263 *
264 * @iclass
265 */
266void osalThreadResumeI(thread_reference_t *trp, msg_t msg) {
267
268 osalDbgCheck(trp != NULL);
269
270 if (*trp != NULL) {
271 (*trp)->message = msg;
272 *trp = NULL;
273 }
274}
275
276/**
277 * @brief Wakes up a thread waiting on a thread reference object.
278 * @note This function must reschedule, it can only be called from thread
279 * context.
280 *
281 * @param[in] trp a pointer to a thread reference object
282 * @param[in] msg the message code
283 *
284 * @iclass
285 */
286void osalThreadResumeS(thread_reference_t *trp, msg_t msg) {
287
288 osalDbgCheck(trp != NULL);
289
290 if (*trp != NULL) {
291 (*trp)->message = msg;
292 *trp = NULL;
293 }
294}
295
296/**
297 * @brief Enqueues the caller thread.
298 * @details The caller thread is enqueued and put to sleep until it is
299 * dequeued or the specified timeouts expires.
300 *
301 * @param[in] tqp pointer to the threads queue object
302 * @param[in] timeout the timeout in system ticks, the special values are
303 * handled as follow:
304 * - @a TIME_INFINITE the thread enters an infinite sleep
305 * state.
306 * - @a TIME_IMMEDIATE the thread is not enqueued and
307 * the function returns @p MSG_TIMEOUT as if a timeout
308 * occurred.
309 * .
310 * @return The message from @p osalQueueWakeupOneI() or
311 * @p osalQueueWakeupAllI() functions.
312 * @retval MSG_TIMEOUT if the thread has not been dequeued within the
313 * specified timeout or if the function has been
314 * invoked with @p TIME_IMMEDIATE as timeout
315 * specification.
316 *
317 * @sclass
318 */
319msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) {
320 msg_t msg;
321 virtual_timer_t vt;
322
323 osalDbgCheck(tqp != NULL);
324
325 if (TIME_IMMEDIATE == timeout)
326 return MSG_TIMEOUT;
327
328 tqp->tr = NULL;
329
330 if (TIME_INFINITE == timeout)
331 return osalThreadSuspendS(&tqp->tr);
332
333 vtSetI(&vt, timeout, callback_timeout, (void *)&tqp->tr);
334 msg = osalThreadSuspendS(&tqp->tr);
335 if (vtIsArmedI(&vt))
336 vtResetI(&vt);
337
338 return msg;
339}
340
341/**
342 * @brief Dequeues and wakes up one thread from the queue, if any.
343 *
344 * @param[in] tqp pointer to the threads queue object
345 * @param[in] msg the message code
346 *
347 * @iclass
348 */
349void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) {
350
351 osalDbgCheck(tqp != NULL);
352
353 osalThreadResumeI(&tqp->tr, msg);
354}
355
356/**
357 * @brief Dequeues and wakes up all threads from the queue.
358 *
359 * @param[in] tqp pointer to the threads queue object
360 * @param[in] msg the message code
361 *
362 * @iclass
363 */
364void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) {
365
366 osalDbgCheck(tqp != NULL);
367
368 osalThreadResumeI(&tqp->tr, msg);
369}
370
371/**
372 * @brief Add flags to an event source object.
373 *
374 * @param[in] esp pointer to the event flags object
375 * @param[in] flags flags to be ORed to the flags mask
376 *
377 * @iclass
378 */
379void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags) {
380
381 osalDbgCheck(esp != NULL);
382
383 esp->flags |= flags;
384 if (esp->cb != NULL) {
385 esp->cb(esp);
386 }
387}
388
389/**
390 * @brief Add flags to an event source object.
391 *
392 * @param[in] esp pointer to the event flags object
393 * @param[in] flags flags to be ORed to the flags mask
394 *
395 * @iclass
396 */
397void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags) {
398
399 osalDbgCheck(esp != NULL);
400
401 osalSysLock();
402 osalEventBroadcastFlagsI(esp, flags);
403 osalSysUnlock();
404}
405
406/**
407 * @brief Event callback setup.
408 * @note The callback is invoked from ISR context and can
409 * only invoke I-Class functions. The callback is meant
410 * to wakeup the task that will handle the event by
411 * calling @p osalEventGetAndClearFlagsI().
412 * @note This function is not part of the OSAL API and is provided
413 * exclusively as an example and for convenience.
414 *
415 * @param[in] esp pointer to the event flags object
416 * @param[in] cb pointer to the callback function
417 * @param[in] param parameter to be passed to the callback function
418 *
419 * @api
420 */
421void osalEventSetCallback(event_source_t *esp,
422 eventcallback_t cb,
423 void *param) {
424
425 osalDbgCheck(esp != NULL);
426
427 esp->cb = cb;
428 esp->param = param;
429}
430
431/**
432 * @brief Locks the specified mutex.
433 * @post The mutex is locked and inserted in the per-thread stack of owned
434 * mutexes.
435 *
436 * @param[in,out] mp pointer to the @p mutex_t object
437 *
438 * @api
439 */
440void osalMutexLock(mutex_t *mp) {
441
442 osalDbgCheck(mp != NULL);
443
444 *mp = 1;
445}
446
447/**
448 * @brief Unlocks the specified mutex.
449 * @note The HAL guarantees to release mutex in reverse lock order. The
450 * mutex being unlocked is guaranteed to be the last locked mutex
451 * by the invoking thread.
452 * The implementation can rely on this behavior and eventually
453 * ignore the @p mp parameter which is supplied in order to support
454 * those OSes not supporting a stack of the owned mutexes.
455 *
456 * @param[in,out] mp pointer to the @p mutex_t object
457 *
458 * @api
459 */
460void osalMutexUnlock(mutex_t *mp) {
461
462 osalDbgCheck(mp != NULL);
463
464 *mp = 0;
465}
466
467/** @} */
diff --git a/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.h b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.h
new file mode 100644
index 000000000..0ec4ee199
--- /dev/null
+++ b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.h
@@ -0,0 +1,754 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file osal.h
19 * @brief OSAL module header.
20 *
21 * @addtogroup OSAL
22 * @{
23 */
24
25#ifndef OSAL_H
26#define OSAL_H
27
28#include <stddef.h>
29#include <stdint.h>
30#include <stdbool.h>
31
32#include "cmparams.h"
33
34#include "osalconf.h"
35
36/*===========================================================================*/
37/* Module constants. */
38/*===========================================================================*/
39
40/**
41 * @name Common constants
42 * @{
43 */
44#if !defined(FALSE) || defined(__DOXYGEN__)
45#define FALSE 0
46#endif
47
48#if !defined(TRUE) || defined(__DOXYGEN__)
49#define TRUE 1
50#endif
51
52#define OSAL_SUCCESS false
53#define OSAL_FAILED true
54/** @} */
55
56/**
57 * @name Messages
58 * @{
59 */
60#define MSG_OK (msg_t)0
61#define MSG_RESET (msg_t)-1
62#define MSG_TIMEOUT (msg_t)-2
63#define MSG_WAIT (msg_t)-10
64/** @} */
65
66/**
67 * @name Special time constants
68 * @{
69 */
70#define TIME_IMMEDIATE ((sysinterval_t)0)
71#define TIME_INFINITE ((sysinterval_t)-1)
72/** @} */
73
74/**
75 * @name Systick modes.
76 * @{
77 */
78#define OSAL_ST_MODE_NONE 0
79#define OSAL_ST_MODE_PERIODIC 1
80#define OSAL_ST_MODE_FREERUNNING 2
81/** @} */
82
83/**
84 * @name Systick parameters.
85 * @{
86 */
87/**
88 * @brief Size in bits of the @p systick_t type.
89 */
90#define OSAL_ST_RESOLUTION 32
91
92/**
93 * @brief Systick mode required by the underlying OS.
94 */
95#define OSAL_ST_MODE OSAL_ST_MODE_PERIODIC
96/** @} */
97
98/**
99 * @name IRQ-related constants
100 * @{
101 */
102/**
103 * @brief Total priority levels.
104 */
105#define OSAL_IRQ_PRIORITY_LEVELS (1U << CORTEX_PRIORITY_BITS)
106
107/**
108 * @brief Highest IRQ priority for HAL drivers.
109 */
110#if (CORTEX_MODEL == 0) || defined(__DOXYGEN__)
111#define OSAL_IRQ_MAXIMUM_PRIORITY 0
112#else
113#define OSAL_IRQ_MAXIMUM_PRIORITY 1
114#endif
115
116/**
117 * @brief Converts from numeric priority to BASEPRI register value.
118 */
119#define OSAL_BASEPRI(priority) ((priority) << (8U - CORTEX_PRIORITY_BITS))
120/** @} */
121
122/*===========================================================================*/
123/* Module pre-compile time settings. */
124/*===========================================================================*/
125
126/**
127 * @brief Frequency in Hertz of the system tick.
128 */
129#if !defined(OSAL_ST_FREQUENCY) || defined(__DOXYGEN__)
130#define OSAL_ST_FREQUENCY 1000
131#endif
132
133/**
134 * @brief Enables OSAL assertions.
135 */
136#if !defined(OSAL_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
137#define OSAL_DBG_ENABLE_ASSERTS FALSE
138#endif
139
140/**
141 * @brief Enables OSAL functions parameters checks.
142 */
143#if !defined(OSAL_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
144#define OSAL_DBG_ENABLE_CHECKS FALSE
145#endif
146
147/**
148 * @brief OSAL initialization hook.
149 */
150#if !defined(OSAL_INIT_HOOK) || defined(__DOXYGEN__)
151#define OSAL_INIT_HOOK()
152#endif
153
154/**
155 * @brief Idle loop hook macro.
156 */
157#if !defined(OSAL_IDLE_HOOK) || defined(__DOXYGEN__)
158#define OSAL_IDLE_HOOK()
159#endif
160
161/*===========================================================================*/
162/* Derived constants and error checks. */
163/*===========================================================================*/
164
165/*===========================================================================*/
166/* Module data structures and types. */
167/*===========================================================================*/
168
169/**
170 * @brief Type of a system status word.
171 */
172typedef uint32_t syssts_t;
173
174/**
175 * @brief Type of a message.
176 */
177typedef int32_t msg_t;
178
179/**
180 * @brief Type of system time counter.
181 */
182typedef uint32_t systime_t;
183
184/**
185 * @brief Type of system time interval.
186 */
187typedef uint32_t sysinterval_t;
188
189/**
190 * @brief Type of realtime counter.
191 */
192typedef uint32_t rtcnt_t;
193
194/**
195 * @brief Type of a thread.
196 * @note The content of this structure is not part of the API and should
197 * not be relied upon. Implementers may define this structure in
198 * an entirely different way.
199 */
200typedef struct {
201 volatile msg_t message;
202} thread_t;
203
204/**
205 * @brief Type of a thread reference.
206 */
207typedef thread_t * thread_reference_t;
208
209/**
210 * @brief Type of an event flags mask.
211 */
212typedef uint32_t eventflags_t;
213
214/**
215 * @brief Type of an event flags object.
216 * @note The content of this structure is not part of the API and should
217 * not be relied upon. Implementers may define this structure in
218 * an entirely different way.
219 * @note Retrieval and clearing of the flags are not defined in this
220 * API and are implementation-dependent.
221 */
222typedef struct event_source event_source_t;
223
224/**
225 * @brief Type of an event source callback.
226 * @note This type is not part of the OSAL API and is provided
227 * exclusively as an example and for convenience.
228 */
229typedef void (*eventcallback_t)(event_source_t *esp);
230
231/**
232 * @brief Events source object.
233 * @note The content of this structure is not part of the API and should
234 * not be relied upon. Implementers may define this structure in
235 * an entirely different way.
236 * @note Retrieval and clearing of the flags are not defined in this
237 * API and are implementation-dependent.
238 */
239struct event_source {
240 volatile eventflags_t flags; /**< @brief Stored event flags. */
241 eventcallback_t cb; /**< @brief Event source callback. */
242 void *param; /**< @brief User defined field. */
243};
244
245/**
246 * @brief Type of a mutex.
247 * @note If the OS does not support mutexes or there is no OS then them
248 * mechanism can be simulated.
249 */
250typedef uint32_t mutex_t;
251
252/**
253 * @brief Type of a thread queue.
254 * @details A thread queue is a queue of sleeping threads, queued threads
255 * can be dequeued one at time or all together.
256 * @note If the OSAL is implemented on a bare metal machine without RTOS
257 * then the queue can be implemented as a single thread reference.
258 */
259typedef struct {
260 thread_reference_t tr;
261} threads_queue_t;
262
263/*===========================================================================*/
264/* Module macros. */
265/*===========================================================================*/
266
267/**
268 * @name Debug related macros
269 * @{
270 */
271/**
272 * @brief Condition assertion.
273 * @details If the condition check fails then the OSAL panics with a
274 * message and halts.
275 * @note The condition is tested only if the @p OSAL_ENABLE_ASSERTIONS
276 * switch is enabled.
277 * @note The remark string is not currently used except for putting a
278 * comment in the code about the assertion.
279 *
280 * @param[in] c the condition to be verified to be true
281 * @param[in] remark a remark string
282 *
283 * @api
284 */
285#define osalDbgAssert(c, remark) do { \
286 /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
287 if (OSAL_DBG_ENABLE_ASSERTS != FALSE) { \
288 if (!(c)) { \
289 /*lint -restore*/ \
290 osalSysHalt(__func__); \
291 } \
292 } \
293} while (false)
294
295/**
296 * @brief Function parameters check.
297 * @details If the condition check fails then the OSAL panics and halts.
298 * @note The condition is tested only if the @p OSAL_ENABLE_CHECKS switch
299 * is enabled.
300 *
301 * @param[in] c the condition to be verified to be true
302 *
303 * @api
304 */
305#define osalDbgCheck(c) do { \
306 /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
307 if (OSAL_DBG_ENABLE_CHECKS != FALSE) { \
308 if (!(c)) { \
309 /*lint -restore*/ \
310 osalSysHalt(__func__); \
311 } \
312 } \
313} while (false)
314
315/**
316 * @brief I-Class state check.
317 * @note Implementation is optional.
318 */
319#define osalDbgCheckClassI()
320
321/**
322 * @brief S-Class state check.
323 * @note Implementation is optional.
324 */
325#define osalDbgCheckClassS()
326/** @} */
327
328/**
329 * @name IRQ service routines wrappers
330 * @{
331 */
332/**
333 * @brief Priority level verification macro.
334 */
335#define OSAL_IRQ_IS_VALID_PRIORITY(n) \
336 (((n) >= OSAL_IRQ_MAXIMUM_PRIORITY) && ((n) < OSAL_IRQ_PRIORITY_LEVELS))
337
338/**
339 * @brief IRQ prologue code.
340 * @details This macro must be inserted at the start of all IRQ handlers.
341 */
342#define OSAL_IRQ_PROLOGUE()
343
344/**
345 * @brief IRQ epilogue code.
346 * @details This macro must be inserted at the end of all IRQ handlers.
347 */
348#define OSAL_IRQ_EPILOGUE()
349
350/**
351 * @brief IRQ handler function declaration.
352 * @details This macro hides the details of an ISR function declaration.
353 *
354 * @param[in] id a vector name as defined in @p vectors.s
355 */
356#define OSAL_IRQ_HANDLER(id) void id(void)
357/** @} */
358
359/**
360 * @name Time conversion utilities
361 * @{
362 */
363/**
364 * @brief Seconds to system ticks.
365 * @details Converts from seconds to system ticks number.
366 * @note The result is rounded upward to the next tick boundary.
367 *
368 * @param[in] secs number of seconds
369 * @return The number of ticks.
370 *
371 * @api
372 */
373#define OSAL_S2I(secs) \
374 ((sysinterval_t)((uint32_t)(secs) * (uint32_t)OSAL_ST_FREQUENCY))
375
376/**
377 * @brief Milliseconds to system ticks.
378 * @details Converts from milliseconds to system ticks number.
379 * @note The result is rounded upward to the next tick boundary.
380 *
381 * @param[in] msecs number of milliseconds
382 * @return The number of ticks.
383 *
384 * @api
385 */
386#define OSAL_MS2I(msecs) \
387 ((sysinterval_t)((((((uint32_t)(msecs)) * \
388 ((uint32_t)OSAL_ST_FREQUENCY)) - 1UL) / 1000UL) + 1UL))
389
390/**
391 * @brief Microseconds to system ticks.
392 * @details Converts from microseconds to system ticks number.
393 * @note The result is rounded upward to the next tick boundary.
394 *
395 * @param[in] usecs number of microseconds
396 * @return The number of ticks.
397 *
398 * @api
399 */
400#define OSAL_US2I(usecs) \
401 ((sysinterval_t)((((((uint32_t)(usecs)) * \
402 ((uint32_t)OSAL_ST_FREQUENCY)) - 1UL) / 1000000UL) + 1UL))
403/** @} */
404
405/**
406 * @name Time conversion utilities for the realtime counter
407 * @{
408 */
409/**
410 * @brief Seconds to realtime counter.
411 * @details Converts from seconds to realtime counter cycles.
412 * @note The macro assumes that @p freq >= @p 1.
413 *
414 * @param[in] freq clock frequency, in Hz, of the realtime counter
415 * @param[in] sec number of seconds
416 * @return The number of cycles.
417 *
418 * @api
419 */
420#define OSAL_S2RTC(freq, sec) ((freq) * (sec))
421
422/**
423 * @brief Milliseconds to realtime counter.
424 * @details Converts from milliseconds to realtime counter cycles.
425 * @note The result is rounded upward to the next millisecond boundary.
426 * @note The macro assumes that @p freq >= @p 1000.
427 *
428 * @param[in] freq clock frequency, in Hz, of the realtime counter
429 * @param[in] msec number of milliseconds
430 * @return The number of cycles.
431 *
432 * @api
433 */
434#define OSAL_MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec))
435
436/**
437 * @brief Microseconds to realtime counter.
438 * @details Converts from microseconds to realtime counter cycles.
439 * @note The result is rounded upward to the next microsecond boundary.
440 * @note The macro assumes that @p freq >= @p 1000000.
441 *
442 * @param[in] freq clock frequency, in Hz, of the realtime counter
443 * @param[in] usec number of microseconds
444 * @return The number of cycles.
445 *
446 * @api
447 */
448#define OSAL_US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec))
449/** @} */
450
451/**
452 * @name Sleep macros using absolute time
453 * @{
454 */
455/**
456 * @brief Delays the invoking thread for the specified number of seconds.
457 * @note The specified time is rounded up to a value allowed by the real
458 * system tick clock.
459 * @note The maximum specifiable value is implementation dependent.
460 *
461 * @param[in] secs time in seconds, must be different from zero
462 *
463 * @api
464 */
465#define osalThreadSleepSeconds(secs) osalThreadSleep(OSAL_S2I(secs))
466
467/**
468 * @brief Delays the invoking thread for the specified number of
469 * milliseconds.
470 * @note The specified time is rounded up to a value allowed by the real
471 * system tick clock.
472 * @note The maximum specifiable value is implementation dependent.
473 *
474 * @param[in] msecs time in milliseconds, must be different from zero
475 *
476 * @api
477 */
478#define osalThreadSleepMilliseconds(msecs) osalThreadSleep(OSAL_MS2I(msecs))
479
480/**
481 * @brief Delays the invoking thread for the specified number of
482 * microseconds.
483 * @note The specified time is rounded up to a value allowed by the real
484 * system tick clock.
485 * @note The maximum specifiable value is implementation dependent.
486 *
487 * @param[in] usecs time in microseconds, must be different from zero
488 *
489 * @api
490 */
491#define osalThreadSleepMicroseconds(usecs) osalThreadSleep(OSAL_US2I(usecs))
492/** @} */
493
494/*===========================================================================*/
495/* External declarations. */
496/*===========================================================================*/
497
498extern const char *osal_halt_msg;
499
500#ifdef __cplusplus
501extern "C" {
502#endif
503 void osalInit(void);
504 void osalSysHalt(const char *reason);
505 void osalSysPolledDelayX(rtcnt_t cycles);
506 void osalOsTimerHandlerI(void);
507 void osalOsRescheduleS(void);
508 systime_t osalOsGetSystemTimeX(void);
509 void osalThreadSleepS(sysinterval_t time);
510 void osalThreadSleep(sysinterval_t time);
511 msg_t osalThreadSuspendS(thread_reference_t *trp);
512 msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout);
513 void osalThreadResumeI(thread_reference_t *trp, msg_t msg);
514 void osalThreadResumeS(thread_reference_t *trp, msg_t msg);
515 msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout);
516 void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg);
517 void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg);
518 void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags);
519 void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags);
520 void osalEventSetCallback(event_source_t *esp,
521 eventcallback_t cb,
522 void *param);
523 void osalMutexLock(mutex_t *mp);
524 void osalMutexUnlock(mutex_t *mp);
525#ifdef __cplusplus
526}
527#endif
528
529/*===========================================================================*/
530/* Module inline functions. */
531/*===========================================================================*/
532
533/**
534 * @brief Disables interrupts globally.
535 *
536 * @special
537 */
538static inline void osalSysDisable(void) {
539
540 __disable_irq();
541}
542
543/**
544 * @brief Enables interrupts globally.
545 *
546 * @special
547 */
548static inline void osalSysEnable(void) {
549
550 __enable_irq();
551}
552
553/**
554 * @brief Enters a critical zone from thread context.
555 * @note This function cannot be used for reentrant critical zones.
556 *
557 * @special
558 */
559static inline void osalSysLock(void) {
560
561#if CORTEX_MODEL == 0
562 __disable_irq();
563#else
564 __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY));
565#endif
566}
567
568/**
569 * @brief Leaves a critical zone from thread context.
570 * @note This function cannot be used for reentrant critical zones.
571 *
572 * @special
573 */
574static inline void osalSysUnlock(void) {
575
576#if CORTEX_MODEL == 0
577 __enable_irq();
578#else
579 __set_BASEPRI(0);
580#endif
581}
582
583/**
584 * @brief Enters a critical zone from ISR context.
585 * @note This function cannot be used for reentrant critical zones.
586 *
587 * @special
588 */
589static inline void osalSysLockFromISR(void) {
590
591#if CORTEX_MODEL == 0
592 __disable_irq();
593#else
594 __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY));
595#endif
596}
597
598/**
599 * @brief Leaves a critical zone from ISR context.
600 * @note This function cannot be used for reentrant critical zones.
601 *
602 * @special
603 */
604static inline void osalSysUnlockFromISR(void) {
605
606#if CORTEX_MODEL == 0
607 __enable_irq();
608#else
609 __set_BASEPRI(0);
610#endif
611}
612
613/**
614 * @brief Returns the execution status and enters a critical zone.
615 * @details This functions enters into a critical zone and can be called
616 * from any context. Because its flexibility it is less efficient
617 * than @p chSysLock() which is preferable when the calling context
618 * is known.
619 * @post The system is in a critical zone.
620 *
621 * @return The previous system status, the encoding of this
622 * status word is architecture-dependent and opaque.
623 *
624 * @xclass
625 */
626static inline syssts_t osalSysGetStatusAndLockX(void) {
627 syssts_t sts;
628
629#if CORTEX_MODEL == 0
630 sts = (syssts_t)__get_PRIMASK();
631 __disable_irq();
632#else
633 sts = (syssts_t)__get_BASEPRI();
634 __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY));
635#endif
636 return sts;
637}
638
639/**
640 * @brief Restores the specified execution status and leaves a critical zone.
641 * @note A call to @p chSchRescheduleS() is automatically performed
642 * if exiting the critical zone and if not in ISR context.
643 *
644 * @param[in] sts the system status to be restored.
645 *
646 * @xclass
647 */
648static inline void osalSysRestoreStatusX(syssts_t sts) {
649
650#if CORTEX_MODEL == 0
651 if ((sts & (syssts_t)1) == (syssts_t)0) {
652 __enable_irq();
653 }
654#else
655 __set_BASEPRI(sts);
656#endif
657}
658
659/**
660 * @brief Adds an interval to a system time returning a system time.
661 *
662 * @param[in] systime base system time
663 * @param[in] interval interval to be added
664 * @return The new system time.
665 *
666 * @xclass
667 */
668static inline systime_t osalTimeAddX(systime_t systime,
669 sysinterval_t interval) {
670
671 return systime + (systime_t)interval;
672}
673
674/**
675 * @brief Subtracts two system times returning an interval.
676 *
677 * @param[in] start first system time
678 * @param[in] end second system time
679 * @return The interval representing the time difference.
680 *
681 * @xclass
682 */
683static inline sysinterval_t osalTimeDiffX(systime_t start, systime_t end) {
684
685 return (sysinterval_t)((systime_t)(end - start));
686}
687
688/**
689 * @brief Checks if the specified time is within the specified time window.
690 * @note When start==end then the function returns always false because the
691 * time window has zero size.
692 * @note This function can be called from any context.
693 *
694 * @param[in] time the time to be verified
695 * @param[in] start the start of the time window (inclusive)
696 * @param[in] end the end of the time window (non inclusive)
697 * @retval true current time within the specified time window.
698 * @retval false current time not within the specified time window.
699 *
700 * @xclass
701 */
702static inline bool osalTimeIsInRangeX(systime_t time,
703 systime_t start,
704 systime_t end) {
705
706 return (bool)((systime_t)((systime_t)time - (systime_t)start) <
707 (systime_t)((systime_t)end - (systime_t)start));
708}
709
710/**
711 * @brief Initializes a threads queue object.
712 *
713 * @param[out] tqp pointer to the threads queue object
714 *
715 * @init
716 */
717static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) {
718
719 osalDbgCheck(tqp != NULL);
720}
721
722/**
723 * @brief Initializes an event source object.
724 *
725 * @param[out] esp pointer to the event source object
726 *
727 * @init
728 */
729static inline void osalEventObjectInit(event_source_t *esp) {
730
731 osalDbgCheck(esp != NULL);
732
733 esp->flags = (eventflags_t)0;
734 esp->cb = NULL;
735 esp->param = NULL;
736}
737
738/**
739 * @brief Initializes s @p mutex_t object.
740 *
741 * @param[out] mp pointer to the @p mutex_t object
742 *
743 * @init
744 */
745static inline void osalMutexObjectInit(mutex_t *mp) {
746
747 osalDbgCheck(mp != NULL);
748
749 *mp = 0;
750}
751
752#endif /* OSAL_H */
753
754/** @} */
diff --git a/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.mk b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.mk
new file mode 100644
index 000000000..60285045b
--- /dev/null
+++ b/lib/chibios/os/hal/osal/os-less/ARMCMx/osal.mk
@@ -0,0 +1,11 @@
1# OSAL files.
2OSALSRC += ${CHIBIOS}/os/hal/osal/os-less/ARMCMx/osal.c \
3 ${CHIBIOS}/os/hal/osal/lib/osal_vt.c
4
5# Required include directories
6OSALINC += ${CHIBIOS}/os/hal/osal/os-less/ARMCMx \
7 ${CHIBIOS}/os/hal/osal/lib
8
9# Shared variables
10ALLCSRC += $(OSALSRC)
11ALLINC += $(OSALINC)
diff --git a/lib/chibios/os/hal/osal/os-less/AVR/osal.c b/lib/chibios/os/hal/osal/os-less/AVR/osal.c
new file mode 100644
index 000000000..4b7e0a9c1
--- /dev/null
+++ b/lib/chibios/os/hal/osal/os-less/AVR/osal.c
@@ -0,0 +1,467 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file osal.c
19 * @brief OSAL module code.
20 *
21 * @addtogroup OSAL
22 * @{
23 */
24
25#include "osal.h"
26#include "osal_vt.h"
27
28/*===========================================================================*/
29/* Module local definitions. */
30/*===========================================================================*/
31
32/*===========================================================================*/
33/* Module exported variables. */
34/*===========================================================================*/
35
36/**
37 * @brief Pointer to a halt error message.
38 * @note The message is meant to be retrieved by the debugger after the
39 * system halt caused by an unexpected error.
40 */
41const char *osal_halt_msg;
42
43/*===========================================================================*/
44/* Module local types. */
45/*===========================================================================*/
46
47/*===========================================================================*/
48/* Module local variables. */
49/*===========================================================================*/
50
51/*===========================================================================*/
52/* Module local functions. */
53/*===========================================================================*/
54
55static void callback_timeout(void *p) {
56 osalSysLockFromISR();
57 osalThreadResumeI((thread_reference_t *)p, MSG_TIMEOUT);
58 osalSysUnlockFromISR();
59}
60
61/*===========================================================================*/
62/* Module exported functions. */
63/*===========================================================================*/
64
65/**
66 * @brief OSAL module initialization.
67 *
68 * @api
69 */
70void osalInit(void) {
71
72 vtInit();
73
74 OSAL_INIT_HOOK();
75}
76
77/**
78 * @brief System halt with error message.
79 *
80 * @param[in] reason the halt message pointer
81 *
82 * @api
83 */
84#if !defined(__DOXYGEN__)
85__attribute__((weak, noreturn))
86#endif
87void osalSysHalt(const char *reason) {
88
89 osalSysDisable();
90 osal_halt_msg = reason;
91 while (true) {
92 }
93}
94
95/**
96 * @brief Polled delay.
97 * @note The real delay is always few cycles in excess of the specified
98 * value.
99 *
100 * @param[in] cycles number of cycles
101 *
102 * @xclass
103 */
104void osalSysPolledDelayX(rtcnt_t cycles) {
105
106 (void)cycles;
107}
108
109/**
110 * @brief System timer handler.
111 * @details The handler is used for scheduling and Virtual Timers management.
112 *
113 * @iclass
114 */
115void osalOsTimerHandlerI(void) {
116
117 osalDbgCheckClassI();
118
119 vtDoTickI();
120}
121
122/**
123 * @brief Checks if a reschedule is required and performs it.
124 * @note I-Class functions invoked from thread context must not reschedule
125 * by themselves, an explicit reschedule using this function is
126 * required in this scenario.
127 * @note Not implemented in this simplified OSAL.
128 *
129 * @sclass
130 */
131void osalOsRescheduleS(void) {
132
133}
134
135/**
136 * @brief Current system time.
137 * @details Returns the number of system ticks since the @p osalInit()
138 * invocation.
139 * @note The counter can reach its maximum and then restart from zero.
140 * @note This function can be called from any context but its atomicity
141 * is not guaranteed on architectures whose word size is less than
142 * @p systime_t size.
143 *
144 * @return The system time in ticks.
145 *
146 * @xclass
147 */
148systime_t osalOsGetSystemTimeX(void) {
149
150 return vtlist.vt_systime;
151}
152
153/**
154 * @brief Suspends the invoking thread for the specified time.
155 *
156 * @param[in] time the delay in system ticks, the special values are
157 * handled as follow:
158 * - @a TIME_INFINITE is allowed but interpreted as a
159 * normal time specification.
160 * - @a TIME_IMMEDIATE this value is not allowed.
161 * .
162 *
163 * @sclass
164 */
165void osalThreadSleepS(systime_t time) {
166 virtual_timer_t vt;
167 thread_reference_t tr;
168
169 tr = NULL;
170 vtSetI(&vt, time, callback_timeout, (void *)&tr);
171 osalThreadSuspendS(&tr);
172}
173
174/**
175 * @brief Suspends the invoking thread for the specified time.
176 *
177 * @param[in] time the delay in system ticks, the special values are
178 * handled as follow:
179 * - @a TIME_INFINITE is allowed but interpreted as a
180 * normal time specification.
181 * - @a TIME_IMMEDIATE this value is not allowed.
182 * .
183 *
184 * @api
185 */
186void osalThreadSleep(systime_t time) {
187
188 osalSysLock();
189 osalThreadSleepS(time);
190 osalSysUnlock();
191}
192
193/**
194 * @brief Sends the current thread sleeping and sets a reference variable.
195 * @note This function must reschedule, it can only be called from thread
196 * context.
197 *
198 * @param[in] trp a pointer to a thread reference object
199 * @return The wake up message.
200 *
201 * @sclass
202 */
203msg_t osalThreadSuspendS(thread_reference_t *trp) {
204 thread_t self = {MSG_WAIT};
205
206 osalDbgCheck(trp != NULL);
207
208 *trp = &self;
209 while (self.message == MSG_WAIT) {
210 osalSysUnlock();
211 /* A state-changing interrupt could occur here and cause the loop to
212 terminate, an hook macro is executed while waiting.*/
213 OSAL_IDLE_HOOK();
214 osalSysLock();
215 }
216
217 return self.message;
218}
219
220/**
221 * @brief Sends the current thread sleeping and sets a reference variable.
222 * @note This function must reschedule, it can only be called from thread
223 * context.
224 *
225 * @param[in] trp a pointer to a thread reference object
226 * @param[in] timeout the timeout in system ticks, the special values are
227 * handled as follow:
228 * - @a TIME_INFINITE the thread enters an infinite sleep
229 * state.
230 * - @a TIME_IMMEDIATE the thread is not enqueued and
231 * the function returns @p MSG_TIMEOUT as if a timeout
232 * occurred.
233 * .
234 * @return The wake up message.
235 * @retval MSG_TIMEOUT if the operation timed out.
236 *
237 * @sclass
238 */
239msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, systime_t timeout) {
240 msg_t msg;
241 virtual_timer_t vt;
242
243 osalDbgCheck(trp != NULL);
244
245 if (TIME_INFINITE == timeout)
246 return osalThreadSuspendS(trp);
247
248 vtSetI(&vt, timeout, callback_timeout, (void *)trp);
249 msg = osalThreadSuspendS(trp);
250 if (vtIsArmedI(&vt))
251 vtResetI(&vt);
252
253 return msg;
254}
255
256/**
257 * @brief Wakes up a thread waiting on a thread reference object.
258 * @note This function must not reschedule because it can be called from
259 * ISR context.
260 *
261 * @param[in] trp a pointer to a thread reference object
262 * @param[in] msg the message code
263 *
264 * @iclass
265 */
266void osalThreadResumeI(thread_reference_t *trp, msg_t msg) {
267
268 osalDbgCheck(trp != NULL);
269
270 if (*trp != NULL) {
271 (*trp)->message = msg;
272 *trp = NULL;
273 }
274}
275
276/**
277 * @brief Wakes up a thread waiting on a thread reference object.
278 * @note This function must reschedule, it can only be called from thread
279 * context.
280 *
281 * @param[in] trp a pointer to a thread reference object
282 * @param[in] msg the message code
283 *
284 * @iclass
285 */
286void osalThreadResumeS(thread_reference_t *trp, msg_t msg) {
287
288 osalDbgCheck(trp != NULL);
289
290 if (*trp != NULL) {
291 (*trp)->message = msg;
292 *trp = NULL;
293 }
294}
295
296/**
297 * @brief Enqueues the caller thread.
298 * @details The caller thread is enqueued and put to sleep until it is
299 * dequeued or the specified timeouts expires.
300 *
301 * @param[in] tqp pointer to the threads queue object
302 * @param[in] timeout the timeout in system ticks, the special values are
303 * handled as follow:
304 * - @a TIME_INFINITE the thread enters an infinite sleep
305 * state.
306 * - @a TIME_IMMEDIATE the thread is not enqueued and
307 * the function returns @p MSG_TIMEOUT as if a timeout
308 * occurred.
309 * .
310 * @return The message from @p osalQueueWakeupOneI() or
311 * @p osalQueueWakeupAllI() functions.
312 * @retval MSG_TIMEOUT if the thread has not been dequeued within the
313 * specified timeout or if the function has been
314 * invoked with @p TIME_IMMEDIATE as timeout
315 * specification.
316 *
317 * @sclass
318 */
319msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, systime_t timeout) {
320 msg_t msg;
321 virtual_timer_t vt;
322
323 osalDbgCheck(tqp != NULL);
324
325 if (TIME_IMMEDIATE == timeout)
326 return MSG_TIMEOUT;
327
328 tqp->tr = NULL;
329
330 if (TIME_INFINITE == timeout)
331 return osalThreadSuspendS(&tqp->tr);
332
333 vtSetI(&vt, timeout, callback_timeout, (void *)&tqp->tr);
334 msg = osalThreadSuspendS(&tqp->tr);
335 if (vtIsArmedI(&vt))
336 vtResetI(&vt);
337
338 return msg;
339}
340
341/**
342 * @brief Dequeues and wakes up one thread from the queue, if any.
343 *
344 * @param[in] tqp pointer to the threads queue object
345 * @param[in] msg the message code
346 *
347 * @iclass
348 */
349void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) {
350
351 osalDbgCheck(tqp != NULL);
352
353 osalThreadResumeI(&tqp->tr, msg);
354}
355
356/**
357 * @brief Dequeues and wakes up all threads from the queue.
358 *
359 * @param[in] tqp pointer to the threads queue object
360 * @param[in] msg the message code
361 *
362 * @iclass
363 */
364void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) {
365
366 osalDbgCheck(tqp != NULL);
367
368 osalThreadResumeI(&tqp->tr, msg);
369}
370
371/**
372 * @brief Add flags to an event source object.
373 *
374 * @param[in] esp pointer to the event flags object
375 * @param[in] flags flags to be ORed to the flags mask
376 *
377 * @iclass
378 */
379void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags) {
380
381 osalDbgCheck(esp != NULL);
382
383 esp->flags |= flags;
384 if (esp->cb != NULL) {
385 esp->cb(esp);
386 }
387}
388
389/**
390 * @brief Add flags to an event source object.
391 *
392 * @param[in] esp pointer to the event flags object
393 * @param[in] flags flags to be ORed to the flags mask
394 *
395 * @iclass
396 */
397void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags) {
398
399 osalDbgCheck(esp != NULL);
400
401 osalSysLock();
402 osalEventBroadcastFlagsI(esp, flags);
403 osalSysUnlock();
404}
405
406/**
407 * @brief Event callback setup.
408 * @note The callback is invoked from ISR context and can
409 * only invoke I-Class functions. The callback is meant
410 * to wakeup the task that will handle the event by
411 * calling @p osalEventGetAndClearFlagsI().
412 * @note This function is not part of the OSAL API and is provided
413 * exclusively as an example and for convenience.
414 *
415 * @param[in] esp pointer to the event flags object
416 * @param[in] cb pointer to the callback function
417 * @param[in] param parameter to be passed to the callback function
418 *
419 * @api
420 */
421void osalEventSetCallback(event_source_t *esp,
422 eventcallback_t cb,
423 void *param) {
424
425 osalDbgCheck(esp != NULL);
426
427 esp->cb = cb;
428 esp->param = param;
429}
430
431/**
432 * @brief Locks the specified mutex.
433 * @post The mutex is locked and inserted in the per-thread stack of owned
434 * mutexes.
435 *
436 * @param[in,out] mp pointer to the @p mutex_t object
437 *
438 * @api
439 */
440void osalMutexLock(mutex_t *mp) {
441
442 osalDbgCheck(mp != NULL);
443
444 *mp = 1;
445}
446
447/**
448 * @brief Unlocks the specified mutex.
449 * @note The HAL guarantees to release mutex in reverse lock order. The
450 * mutex being unlocked is guaranteed to be the last locked mutex
451 * by the invoking thread.
452 * The implementation can rely on this behavior and eventually
453 * ignore the @p mp parameter which is supplied in order to support
454 * those OSes not supporting a stack of the owned mutexes.
455 *
456 * @param[in,out] mp pointer to the @p mutex_t object
457 *
458 * @api
459 */
460void osalMutexUnlock(mutex_t *mp) {
461
462 osalDbgCheck(mp != NULL);
463
464 *mp = 0;
465}
466
467/** @} */
diff --git a/lib/chibios/os/hal/osal/os-less/AVR/osal.h b/lib/chibios/os/hal/osal/os-less/AVR/osal.h
new file mode 100644
index 000000000..833ab9acb
--- /dev/null
+++ b/lib/chibios/os/hal/osal/os-less/AVR/osal.h
@@ -0,0 +1,677 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file osal.h
19 * @brief OSAL module header.
20 *
21 * @addtogroup OSAL
22 * @{
23 */
24
25#ifndef OSAL_H
26#define OSAL_H
27
28#include <stddef.h>
29#include <stdint.h>
30#include <stdbool.h>
31
32#include <avr/io.h>
33#include <avr/interrupt.h>
34
35#include "osalconf.h"
36
37/*===========================================================================*/
38/* Module constants. */
39/*===========================================================================*/
40
41/**
42 * @name Common constants
43 * @{
44 */
45#if !defined(FALSE) || defined(__DOXYGEN__)
46#define FALSE 0
47#endif
48
49#if !defined(TRUE) || defined(__DOXYGEN__)
50#define TRUE 1
51#endif
52
53#define OSAL_SUCCESS false
54#define OSAL_FAILED true
55/** @} */
56
57/**
58 * @name Messages
59 * @{
60 */
61#define MSG_OK (msg_t)0
62#define MSG_RESET (msg_t)-1
63#define MSG_TIMEOUT (msg_t)-2
64#define MSG_WAIT (msg_t)-10
65/** @} */
66
67/**
68 * @name Special time constants
69 * @{
70 */
71#define TIME_IMMEDIATE ((systime_t)0)
72#define TIME_INFINITE ((systime_t)-1)
73/** @} */
74
75/**
76 * @name Systick modes.
77 * @{
78 */
79#define OSAL_ST_MODE_NONE 0
80#define OSAL_ST_MODE_PERIODIC 1
81#define OSAL_ST_MODE_FREERUNNING 2
82/** @} */
83
84/**
85 * @name Systick parameters.
86 * @{
87 */
88/**
89 * @brief Size in bits of the @p systick_t type.
90 */
91#define OSAL_ST_RESOLUTION 32
92
93/**
94 * @brief Systick mode required by the underlying OS.
95 */
96#define OSAL_ST_MODE OSAL_ST_MODE_PERIODIC
97/** @} */
98
99/**
100 * @brief ROM constant modifier.
101 * @note It is set to use the "const" keyword in this port.
102 */
103#define ROMCONST const
104
105/*===========================================================================*/
106/* Module pre-compile time settings. */
107/*===========================================================================*/
108
109/**
110 * @brief Frequency in Hertz of the system tick.
111 */
112#if !defined(OSAL_ST_FREQUENCY) || defined(__DOXYGEN__)
113#define OSAL_ST_FREQUENCY 1000
114#endif
115
116/**
117 * @brief Enables OSAL assertions.
118 */
119#if !defined(OSAL_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
120#define OSAL_DBG_ENABLE_ASSERTS FALSE
121#endif
122
123/**
124 * @brief Enables OSAL functions parameters checks.
125 */
126#if !defined(OSAL_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
127#define OSAL_DBG_ENABLE_CHECKS FALSE
128#endif
129
130/**
131 * @brief OSAL initialization hook.
132 */
133#if !defined(OSAL_INIT_HOOK) || defined(__DOXYGEN__)
134#define OSAL_INIT_HOOK()
135#endif
136
137/**
138 * @brief Idle loop hook macro.
139 */
140#if !defined(OSAL_IDLE_HOOK) || defined(__DOXYGEN__)
141#define OSAL_IDLE_HOOK()
142#endif
143
144/*===========================================================================*/
145/* Derived constants and error checks. */
146/*===========================================================================*/
147
148/*===========================================================================*/
149/* Module data structures and types. */
150/*===========================================================================*/
151
152/**
153 * @brief Type of a system status word.
154 */
155typedef uint8_t syssts_t;
156
157/**
158 * @brief Type of a message.
159 */
160typedef int16_t msg_t;
161
162/**
163 * @brief Type of system time counter.
164 */
165typedef uint32_t systime_t;
166
167/**
168 * @brief Type of realtime counter.
169 */
170typedef uint32_t rtcnt_t;
171
172/**
173 * @brief Type of a thread.
174 * @note The content of this structure is not part of the API and should
175 * not be relied upon. Implementers may define this structure in
176 * an entirely different way.
177 */
178typedef struct {
179 volatile msg_t message;
180} thread_t;
181
182/**
183 * @brief Type of a thread reference.
184 */
185typedef thread_t * thread_reference_t;
186
187/**
188 * @brief Type of an event flags object.
189 * @note The content of this structure is not part of the API and should
190 * not be relied upon. Implementers may define this structure in
191 * an entirely different way.
192 * @note Retrieval and clearing of the flags are not defined in this
193 * API and are implementation-dependent.
194 */
195typedef struct event_source event_source_t;
196
197/**
198 * @brief Type of an event source callback.
199 * @note This type is not part of the OSAL API and is provided
200 * exclusively as an example and for convenience.
201 */
202typedef void (*eventcallback_t)(event_source_t *esp);
203
204/**
205 * @brief Type of an event flags mask.
206 */
207typedef uint8_t eventflags_t;
208
209/**
210 * @brief Events source object.
211 * @note The content of this structure is not part of the API and should
212 * not be relied upon. Implementers may define this structure in
213 * an entirely different way.
214 * @note Retrieval and clearing of the flags are not defined in this
215 * API and are implementation-dependent.
216 */
217struct event_source {
218 volatile eventflags_t flags; /**< @brief Stored event flags. */
219 eventcallback_t cb; /**< @brief Event source callback. */
220 void *param; /**< @brief User defined field. */
221};
222
223/**
224 * @brief Type of a mutex.
225 * @note If the OS does not support mutexes or there is no OS then them
226 * mechanism can be simulated.
227 */
228typedef uint8_t mutex_t;
229
230/**
231 * @brief Type of a thread queue.
232 * @details A thread queue is a queue of sleeping threads, queued threads
233 * can be dequeued one at time or all together.
234 * @note If the OSAL is implemented on a bare metal machine without RTOS
235 * then the queue can be implemented as a single thread reference.
236 */
237typedef struct {
238 thread_reference_t tr;
239} threads_queue_t;
240
241/*===========================================================================*/
242/* Module macros. */
243/*===========================================================================*/
244
245/**
246 * @name Debug related macros
247 * @{
248 */
249/**
250 * @brief Condition assertion.
251 * @details If the condition check fails then the OSAL panics with a
252 * message and halts.
253 * @note The condition is tested only if the @p OSAL_ENABLE_ASSERTIONS
254 * switch is enabled.
255 * @note The remark string is not currently used except for putting a
256 * comment in the code about the assertion.
257 *
258 * @param[in] c the condition to be verified to be true
259 * @param[in] remark a remark string
260 *
261 * @api
262 */
263#define osalDbgAssert(c, remark) do { \
264 /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
265 if (OSAL_DBG_ENABLE_ASSERTS != FALSE) { \
266 if (!(c)) { \
267 /*lint -restore*/ \
268 osalSysHalt(__func__); \
269 } \
270 } \
271} while (false)
272
273/**
274 * @brief Function parameters check.
275 * @details If the condition check fails then the OSAL panics and halts.
276 * @note The condition is tested only if the @p OSAL_ENABLE_CHECKS switch
277 * is enabled.
278 *
279 * @param[in] c the condition to be verified to be true
280 *
281 * @api
282 */
283#define osalDbgCheck(c) do { \
284 /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
285 if (OSAL_DBG_ENABLE_CHECKS != FALSE) { \
286 if (!(c)) { \
287 /*lint -restore*/ \
288 osalSysHalt(__func__); \
289 } \
290 } \
291} while (false)
292
293/**
294 * @brief I-Class state check.
295 * @note Implementation is optional.
296 */
297#define osalDbgCheckClassI()
298
299/**
300 * @brief S-Class state check.
301 * @note Implementation is optional.
302 */
303#define osalDbgCheckClassS()
304/** @} */
305
306/**
307 * @name IRQ service routines wrappers
308 * @{
309 */
310/**
311 * @brief IRQ prologue code.
312 * @details This macro must be inserted at the start of all IRQ handlers.
313 */
314#define OSAL_IRQ_PROLOGUE()
315
316/**
317 * @brief IRQ epilogue code.
318 * @details This macro must be inserted at the end of all IRQ handlers.
319 */
320#define OSAL_IRQ_EPILOGUE()
321
322/**
323 * @brief IRQ handler function declaration.
324 * @details This macro hides the details of an ISR function declaration.
325 *
326 * @param[in] id a vector name as defined in @p vectors.s
327 */
328#define OSAL_IRQ_HANDLER(id) ISR(id)
329/** @} */
330
331/**
332 * @name Time conversion utilities
333 * @{
334 */
335/**
336 * @brief Seconds to system ticks.
337 * @details Converts from seconds to system ticks number.
338 * @note The result is rounded upward to the next tick boundary.
339 *
340 * @param[in] sec number of seconds
341 * @return The number of ticks.
342 *
343 * @api
344 */
345#define OSAL_S2ST(sec) \
346 ((systime_t)((uint32_t)(sec) * (uint32_t)OSAL_ST_FREQUENCY))
347
348/**
349 * @brief Milliseconds to system ticks.
350 * @details Converts from milliseconds to system ticks number.
351 * @note The result is rounded upward to the next tick boundary.
352 *
353 * @param[in] msec number of milliseconds
354 * @return The number of ticks.
355 *
356 * @api
357 */
358#define OSAL_MS2ST(msec) \
359 ((systime_t)((((uint32_t)(msec)) * \
360 ((uint32_t)OSAL_ST_FREQUENCY) + 999UL) / 1000UL))
361
362/**
363 * @brief Microseconds to system ticks.
364 * @details Converts from microseconds to system ticks number.
365 * @note The result is rounded upward to the next tick boundary.
366 *
367 * @param[in] usec number of microseconds
368 * @return The number of ticks.
369 *
370 * @api
371 */
372#define OSAL_US2ST(usec) \
373 ((systime_t)((((uint32_t)(usec)) * \
374 ((uint32_t)OSAL_ST_FREQUENCY) + 999999UL) / 1000000UL))
375/** @} */
376
377/**
378 * @name Time conversion utilities for the realtime counter
379 * @{
380 */
381/**
382 * @brief Seconds to realtime counter.
383 * @details Converts from seconds to realtime counter cycles.
384 * @note The macro assumes that @p freq >= @p 1.
385 *
386 * @param[in] freq clock frequency, in Hz, of the realtime counter
387 * @param[in] sec number of seconds
388 * @return The number of cycles.
389 *
390 * @api
391 */
392#define OSAL_S2RTC(freq, sec) ((freq) * (sec))
393
394/**
395 * @brief Milliseconds to realtime counter.
396 * @details Converts from milliseconds to realtime counter cycles.
397 * @note The result is rounded upward to the next millisecond boundary.
398 * @note The macro assumes that @p freq >= @p 1000.
399 *
400 * @param[in] freq clock frequency, in Hz, of the realtime counter
401 * @param[in] msec number of milliseconds
402 * @return The number of cycles.
403 *
404 * @api
405 */
406#define OSAL_MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec))
407
408/**
409 * @brief Microseconds to realtime counter.
410 * @details Converts from microseconds to realtime counter cycles.
411 * @note The result is rounded upward to the next microsecond boundary.
412 * @note The macro assumes that @p freq >= @p 1000000.
413 *
414 * @param[in] freq clock frequency, in Hz, of the realtime counter
415 * @param[in] usec number of microseconds
416 * @return The number of cycles.
417 *
418 * @api
419 */
420#define OSAL_US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec))
421/** @} */
422
423/**
424 * @name Sleep macros using absolute time
425 * @{
426 */
427/**
428 * @brief Delays the invoking thread for the specified number of seconds.
429 * @note The specified time is rounded up to a value allowed by the real
430 * system tick clock.
431 * @note The maximum specifiable value is implementation dependent.
432 *
433 * @param[in] sec time in seconds, must be different from zero
434 *
435 * @api
436 */
437#define osalThreadSleepSeconds(sec) osalThreadSleep(OSAL_S2ST(sec))
438
439/**
440 * @brief Delays the invoking thread for the specified number of
441 * milliseconds.
442 * @note The specified time is rounded up to a value allowed by the real
443 * system tick clock.
444 * @note The maximum specifiable value is implementation dependent.
445 *
446 * @param[in] msec time in milliseconds, must be different from zero
447 *
448 * @api
449 */
450#define osalThreadSleepMilliseconds(msec) osalThreadSleep(OSAL_MS2ST(msec))
451
452/**
453 * @brief Delays the invoking thread for the specified number of
454 * microseconds.
455 * @note The specified time is rounded up to a value allowed by the real
456 * system tick clock.
457 * @note The maximum specifiable value is implementation dependent.
458 *
459 * @param[in] usec time in microseconds, must be different from zero
460 *
461 * @api
462 */
463#define osalThreadSleepMicroseconds(usec) osalThreadSleep(OSAL_US2ST(usec))
464/** @} */
465
466/*===========================================================================*/
467/* External declarations. */
468/*===========================================================================*/
469
470extern const char *osal_halt_msg;
471
472#ifdef __cplusplus
473extern "C" {
474#endif
475 void osalInit(void);
476 void osalSysHalt(const char *reason);
477 void osalSysPolledDelayX(rtcnt_t cycles);
478 void osalOsTimerHandlerI(void);
479 void osalOsRescheduleS(void);
480 systime_t osalOsGetSystemTimeX(void);
481 void osalThreadSleepS(systime_t time);
482 void osalThreadSleep(systime_t time);
483 msg_t osalThreadSuspendS(thread_reference_t *trp);
484 msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, systime_t timeout);
485 void osalThreadResumeI(thread_reference_t *trp, msg_t msg);
486 void osalThreadResumeS(thread_reference_t *trp, msg_t msg);
487 msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, systime_t timeout);
488 void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg);
489 void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg);
490 void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags);
491 void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags);
492 void osalEventSetCallback(event_source_t *esp,
493 eventcallback_t cb,
494 void *param);
495 void osalMutexLock(mutex_t *mp);
496 void osalMutexUnlock(mutex_t *mp);
497#ifdef __cplusplus
498}
499#endif
500
501/*===========================================================================*/
502/* Module inline functions. */
503/*===========================================================================*/
504
505/**
506 * @brief Disables interrupts globally.
507 *
508 * @special
509 */
510static inline void osalSysDisable(void) {
511
512 asm volatile ("cli" : : : "memory");
513}
514
515/**
516 * @brief Enables interrupts globally.
517 *
518 * @special
519 */
520static inline void osalSysEnable(void) {
521
522 asm volatile ("sei" : : : "memory");
523 asm volatile ("nop");
524}
525
526/**
527 * @brief Enters a critical zone from thread context.
528 * @note This function cannot be used for reentrant critical zones.
529 *
530 * @special
531 */
532static inline void osalSysLock(void) {
533
534 asm volatile ("cli" : : : "memory");
535}
536
537/**
538 * @brief Leaves a critical zone from thread context.
539 * @note This function cannot be used for reentrant critical zones.
540 *
541 * @special
542 */
543static inline void osalSysUnlock(void) {
544
545 asm volatile ("sei" : : : "memory");
546 asm volatile ("nop");
547}
548
549/**
550 * @brief Enters a critical zone from ISR context.
551 * @note This function cannot be used for reentrant critical zones.
552 * @note This function is empty in this port.
553 *
554 * @special
555 */
556static inline void osalSysLockFromISR(void) {
557
558}
559
560/**
561 * @brief Leaves a critical zone from ISR context.
562 * @note This function cannot be used for reentrant critical zones.
563 * @note This function is empty in this port.
564 *
565 * @special
566 */
567static inline void osalSysUnlockFromISR(void) {
568
569}
570
571/**
572 * @brief Returns the execution status and enters a critical zone.
573 * @details This functions enters into a critical zone and can be called
574 * from any context. Because its flexibility it is less efficient
575 * than @p chSysLock() which is preferable when the calling context
576 * is known.
577 * @post The system is in a critical zone.
578 *
579 * @return The previous system status, the encoding of this
580 * status word is architecture-dependent and opaque.
581 *
582 * @xclass
583 */
584static inline syssts_t osalSysGetStatusAndLockX(void) {
585 syssts_t sts;
586
587 sts = SREG;
588 asm volatile ("cli" : : : "memory");
589
590 return sts;
591}
592
593/**
594 * @brief Restores the specified execution status and leaves a critical zone.
595 * @note A call to @p chSchRescheduleS() is automatically performed
596 * if exiting the critical zone and if not in ISR context.
597 *
598 * @param[in] sts the system status to be restored.
599 *
600 * @xclass
601 */
602static inline void osalSysRestoreStatusX(syssts_t sts) {
603
604 if ((sts & 0x80) != 0) {
605 asm volatile ("sei" : : : "memory");
606 asm volatile ("nop");
607 }
608}
609
610/**
611 * @brief Checks if the specified time is within the specified time window.
612 * @note When start==end then the function returns always false because the
613 * time window has zero size.
614 * @note This function can be called from any context.
615 *
616 * @param[in] time the time to be verified
617 * @param[in] start the start of the time window (inclusive)
618 * @param[in] end the end of the time window (non inclusive)
619 * @retval true current time within the specified time window.
620 * @retval false current time not within the specified time window.
621 *
622 * @xclass
623 */
624static inline bool osalOsIsTimeWithinX(systime_t time,
625 systime_t start,
626 systime_t end) {
627
628 return (bool)((time - start) < (end - start));
629}
630
631/**
632 * @brief Initializes a threads queue object.
633 *
634 * @param[out] tqp pointer to the threads queue object
635 *
636 * @init
637 */
638static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) {
639
640 osalDbgCheck(tqp != NULL);
641
642 (void)tqp;
643}
644
645/**
646 * @brief Initializes an event flags object.
647 *
648 * @param[out] esp pointer to the event flags object
649 *
650 * @init
651 */
652static inline void osalEventObjectInit(event_source_t *esp) {
653
654 osalDbgCheck(esp != NULL);
655
656 esp->flags = (eventflags_t)0;
657 esp->cb = NULL;
658 esp->param = NULL;
659}
660
661/**
662 * @brief Initializes s @p mutex_t object.
663 *
664 * @param[out] mp pointer to the @p mutex_t object
665 *
666 * @init
667 */
668static inline void osalMutexObjectInit(mutex_t *mp) {
669
670 osalDbgCheck(mp != NULL);
671
672 *mp = 0;
673}
674
675#endif /* OSAL_H */
676
677/** @} */
diff --git a/lib/chibios/os/hal/osal/os-less/AVR/osal.mk b/lib/chibios/os/hal/osal/os-less/AVR/osal.mk
new file mode 100644
index 000000000..6295bd54a
--- /dev/null
+++ b/lib/chibios/os/hal/osal/os-less/AVR/osal.mk
@@ -0,0 +1,9 @@
1# OSAL files.
2OSALSRC += ${CHIBIOS}/os/hal/osal/os-less/AVR/osal.c
3
4# Required include directories
5OSALINC += ${CHIBIOS}/os/hal/osal/os-less/AVR
6
7# Shared variables
8ALLCSRC += $(OSALSRC)
9ALLINC += $(OSALINC)
diff --git a/lib/chibios/os/hal/osal/rt-nil/osal.c b/lib/chibios/os/hal/osal/rt-nil/osal.c
new file mode 100644
index 000000000..853abe694
--- /dev/null
+++ b/lib/chibios/os/hal/osal/rt-nil/osal.c
@@ -0,0 +1,51 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file osal.c
19 * @brief OSAL module code.
20 *
21 * @addtogroup OSAL
22 * @{
23 */
24
25#include "osal.h"
26
27/*===========================================================================*/
28/* Module local definitions. */
29/*===========================================================================*/
30
31/*===========================================================================*/
32/* Module exported variables. */
33/*===========================================================================*/
34
35/*===========================================================================*/
36/* Module local types. */
37/*===========================================================================*/
38
39/*===========================================================================*/
40/* Module local variables. */
41/*===========================================================================*/
42
43/*===========================================================================*/
44/* Module local functions. */
45/*===========================================================================*/
46
47/*===========================================================================*/
48/* Module exported functions. */
49/*===========================================================================*/
50
51/** @} */
diff --git a/lib/chibios/os/hal/osal/rt-nil/osal.h b/lib/chibios/os/hal/osal/rt-nil/osal.h
new file mode 100644
index 000000000..25ac4de9b
--- /dev/null
+++ b/lib/chibios/os/hal/osal/rt-nil/osal.h
@@ -0,0 +1,1092 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file osal.h
19 * @brief OSAL module header.
20 *
21 * @addtogroup OSAL
22 * @{
23 */
24
25#ifndef OSAL_H
26#define OSAL_H
27
28#include <stddef.h>
29#include <stdint.h>
30#include <stdbool.h>
31
32#include "ch.h"
33
34/*===========================================================================*/
35/* Module constants. */
36/*===========================================================================*/
37
38/**
39 * @name Common constants
40 * @{
41 */
42#if !defined(FALSE) || defined(__DOXYGEN__)
43#define FALSE 0
44#endif
45
46#if !defined(TRUE) || defined(__DOXYGEN__)
47#define TRUE 1
48#endif
49
50#define OSAL_SUCCESS false
51#define OSAL_FAILED true
52/** @} */
53
54#if 0
55/**
56 * @name Messages
57 * @{
58 */
59#define MSG_OK (msg_t)0
60#define MSG_TIMEOUT (msg_t)-1
61#define MSG_RESET (msg_t)-2
62/** @} */
63#endif
64
65#if 0
66/**
67 * @name Special time constants
68 * @{
69 */
70#define TIME_IMMEDIATE ((sysinterval_t)0)
71#define TIME_INFINITE ((sysinterval_t)-1)
72/** @} */
73#endif
74
75/**
76 * @name Systick modes.
77 * @{
78 */
79#define OSAL_ST_MODE_NONE 0
80#define OSAL_ST_MODE_PERIODIC 1
81#define OSAL_ST_MODE_FREERUNNING 2
82/** @} */
83
84/**
85 * @name Systick parameters.
86 * @{
87 */
88/**
89 * @brief Size in bits of the @p systick_t type.
90 */
91#define OSAL_ST_RESOLUTION CH_CFG_ST_RESOLUTION
92
93/**
94 * @brief Required systick frequency or resolution.
95 */
96#define OSAL_ST_FREQUENCY CH_CFG_ST_FREQUENCY
97
98/**
99 * @brief Systick mode required by the underlying OS.
100 */
101#if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
102#define OSAL_ST_MODE OSAL_ST_MODE_PERIODIC
103#else
104#define OSAL_ST_MODE OSAL_ST_MODE_FREERUNNING
105#endif
106/** @} */
107
108/*===========================================================================*/
109/* Module pre-compile time settings. */
110/*===========================================================================*/
111
112/*===========================================================================*/
113/* Derived constants and error checks. */
114/*===========================================================================*/
115
116#if !(OSAL_ST_MODE == OSAL_ST_MODE_NONE) && \
117 !(OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) && \
118 !(OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING)
119#error "invalid OSAL_ST_MODE setting in osal.h"
120#endif
121
122#if (OSAL_ST_RESOLUTION != 16) && (OSAL_ST_RESOLUTION != 32) && \
123 (OSAL_ST_RESOLUTION != 64)
124#error "invalid OSAL_ST_RESOLUTION, must be 16, 32 or 64"
125#endif
126
127/*===========================================================================*/
128/* Module data structures and types. */
129/*===========================================================================*/
130
131#if 0
132/**
133 * @brief Type of a system status word.
134 */
135typedef uint32_t syssts_t;
136#endif
137
138#if 0
139/**
140 * @brief Type of a message.
141 */
142typedef int32_t msg_t;
143#endif
144
145#if 0
146/**
147 * @brief Type of system time counter.
148 */
149typedef uint32_t systime_t;
150#endif
151
152#if 0
153/**
154 * @brief Type of system time interval.
155 */
156typedef uint32_t sysinterval_t;
157#endif
158
159#if 0
160/**
161 * @brief Type of time conversion variable.
162 * @note This type must have double width than other time types, it is
163 * only used internally for conversions.
164 */
165typedef uint64_t time_conv_t;
166#endif
167
168#if 0
169/**
170 * @brief Type of realtime counter.
171 */
172typedef uint32_t rtcnt_t;
173#endif
174
175#if 0
176/**
177 * @brief Type of a thread reference.
178 */
179typedef thread_t * thread_reference_t;
180#endif
181
182#if 0
183/**
184 * @brief Type of an event flags mask.
185 */
186typedef uint32_t eventflags_t;
187#endif
188
189#if (CH_CFG_USE_EVENTS == FALSE) || defined(__DOXYGEN__)
190/**
191 * @brief Type of an event flags object.
192 * @note The content of this structure is not part of the API and should
193 * not be relied upon. Implementers may define this structure in
194 * an entirely different way.
195 * @note Retrieval and clearing of the flags are not defined in this
196 * API and are implementation-dependent.
197 */
198typedef struct event_source event_source_t;
199
200/**
201 * @brief Type of an event source callback.
202 * @note This type is not part of the OSAL API and is provided
203 * exclusively as an example and for convenience.
204 */
205typedef void (*eventcallback_t)(event_source_t *esp);
206
207/**
208 * @brief Events source object.
209 * @note The content of this structure is not part of the API and should
210 * not be relied upon. Implementers may define this structure in
211 * an entirely different way.
212 * @note Retrieval and clearing of the flags are not defined in this
213 * API and are implementation-dependent.
214 */
215struct event_source {
216 volatile eventflags_t flags; /**< @brief Stored event flags. */
217 eventcallback_t cb; /**< @brief Event source callback. */
218 void *param; /**< @brief User defined field. */
219};
220#endif /* CH_CFG_USE_EVENTS == FALSE */
221
222/**
223 * @brief Type of a mutex.
224 * @note If the OS does not support mutexes or there is no OS then the
225 * mechanism can be simulated.
226 */
227#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
228#elif CH_CFG_USE_SEMAPHORES
229typedef semaphore_t mutex_t;
230#else
231typedef uint32_t mutex_t;
232#endif
233
234#if 0
235/**
236 * @brief Type of a thread queue.
237 * @details A thread queue is a queue of sleeping threads, queued threads
238 * can be dequeued one at time or all together.
239 * @note In this implementation it is implemented as a single reference
240 * because there are no real threads.
241 */
242typedef struct {
243 thread_reference_t tr;
244} threads_queue_t;
245#endif
246
247/*===========================================================================*/
248/* Module macros. */
249/*===========================================================================*/
250
251/**
252 * @name Debug related macros
253 * @{
254 */
255/**
256 * @brief Condition assertion.
257 * @details If the condition check fails then the OSAL panics with a
258 * message and halts.
259 * @note The condition is tested only if the @p OSAL_ENABLE_ASSERTIONS
260 * switch is enabled.
261 * @note The remark string is not currently used except for putting a
262 * comment in the code about the assertion.
263 *
264 * @param[in] c the condition to be verified to be true
265 * @param[in] remark a remark string
266 *
267 * @api
268 */
269#define osalDbgAssert(c, remark) chDbgAssert(c, remark)
270
271/**
272 * @brief Function parameters check.
273 * @details If the condition check fails then the OSAL panics and halts.
274 * @note The condition is tested only if the @p OSAL_ENABLE_CHECKS switch
275 * is enabled.
276 *
277 * @param[in] c the condition to be verified to be true
278 *
279 * @api
280 */
281#define osalDbgCheck(c) chDbgCheck(c)
282
283/**
284 * @brief I-Class state check.
285 * @note Not implemented in this simplified OSAL.
286 */
287#define osalDbgCheckClassI() chDbgCheckClassI()
288
289/**
290 * @brief S-Class state check.
291 * @note Not implemented in this simplified OSAL.
292 */
293#define osalDbgCheckClassS() chDbgCheckClassS()
294/** @} */
295
296/**
297 * @name IRQ service routines wrappers
298 * @{
299 */
300/**
301 * @brief Priority level verification macro.
302 */
303#define OSAL_IRQ_IS_VALID_PRIORITY(n) CH_IRQ_IS_VALID_KERNEL_PRIORITY(n)
304
305/**
306 * @brief IRQ prologue code.
307 * @details This macro must be inserted at the start of all IRQ handlers.
308 */
309#define OSAL_IRQ_PROLOGUE() CH_IRQ_PROLOGUE()
310
311/**
312 * @brief IRQ epilogue code.
313 * @details This macro must be inserted at the end of all IRQ handlers.
314 */
315#define OSAL_IRQ_EPILOGUE() CH_IRQ_EPILOGUE()
316
317/**
318 * @brief IRQ handler function declaration.
319 * @details This macro hides the details of an ISR function declaration.
320 *
321 * @param[in] id a vector name as defined in @p vectors.s
322 */
323#define OSAL_IRQ_HANDLER(id) CH_IRQ_HANDLER(id)
324/** @} */
325
326/**
327 * @name Time conversion utilities
328 * @{
329 */
330/**
331 * @brief Seconds to time interval.
332 * @details Converts from seconds to system ticks number.
333 * @note The result is rounded upward to the next tick boundary.
334 * @note Use of this macro for large values is not secure because
335 * integer overflows, make sure your value can be correctly
336 * converted.
337 *
338 * @param[in] secs number of seconds
339 * @return The number of ticks.
340 *
341 * @api
342 */
343#define OSAL_S2I(secs) TIME_S2I(secs)
344
345/**
346 * @brief Milliseconds to time interval.
347 * @details Converts from milliseconds to system ticks number.
348 * @note The result is rounded upward to the next tick boundary.
349 * @note Use of this macro for large values is not secure because
350 * integer overflows, make sure your value can be correctly
351 * converted.
352 *
353 * @param[in] msecs number of milliseconds
354 * @return The number of ticks.
355 *
356 * @api
357 */
358#define OSAL_MS2I(msecs) TIME_MS2I(msecs)
359
360/**
361 * @brief Microseconds to time interval.
362 * @details Converts from microseconds to system ticks number.
363 * @note The result is rounded upward to the next tick boundary.
364 * @note Use of this macro for large values is not secure because
365 * integer overflows, make sure your value can be correctly
366 * converted.
367 *
368 * @param[in] usecs number of microseconds
369 * @return The number of ticks.
370 *
371 * @api
372 */
373#define OSAL_US2I(usecs) TIME_US2I(usecs)
374
375/**
376 * @brief Time interval to seconds.
377 * @details Converts from system ticks number to seconds.
378 * @note The result is rounded up to the next second boundary.
379 * @note Use of this macro for large values is not secure because
380 * integer overflows, make sure your value can be correctly
381 * converted.
382 *
383 * @param[in] interval interval in ticks
384 * @return The number of seconds.
385 *
386 * @api
387 */
388#define OSAL_I2S(interval) TIME_I2S(interval)
389
390/**
391 * @brief Time interval to milliseconds.
392 * @details Converts from system ticks number to milliseconds.
393 * @note The result is rounded up to the next millisecond boundary.
394 * @note Use of this macro for large values is not secure because
395 * integer overflows, make sure your value can be correctly
396 * converted.
397 *
398 * @param[in] interval interval in ticks
399 * @return The number of milliseconds.
400 *
401 * @api
402 */
403#define OSAL_I2MS(interval) TIME_I2MS(interval)
404
405/**
406 * @brief Time interval to microseconds.
407 * @details Converts from system ticks number to microseconds.
408 * @note The result is rounded up to the next microsecond boundary.
409 * @note Use of this macro for large values is not secure because
410 * integer overflows, make sure your value can be correctly
411 * converted.
412 *
413 * @param[in] interval interval in ticks
414 * @return The number of microseconds.
415 *
416 * @api
417 */
418#define OSAL_I2US(interval) TIME_I2US(interval)
419/** @} */
420
421/**
422 * @name Time conversion utilities for the realtime counter
423 * @{
424 */
425/**
426 * @brief Seconds to realtime counter.
427 * @details Converts from seconds to realtime counter cycles.
428 * @note The macro assumes that @p freq >= @p 1.
429 *
430 * @param[in] freq clock frequency, in Hz, of the realtime counter
431 * @param[in] sec number of seconds
432 * @return The number of cycles.
433 *
434 * @api
435 */
436#define OSAL_S2RTC(freq, sec) S2RTC(freq, sec)
437
438/**
439 * @brief Milliseconds to realtime counter.
440 * @details Converts from milliseconds to realtime counter cycles.
441 * @note The result is rounded upward to the next millisecond boundary.
442 * @note The macro assumes that @p freq >= @p 1000.
443 *
444 * @param[in] freq clock frequency, in Hz, of the realtime counter
445 * @param[in] msec number of milliseconds
446 * @return The number of cycles.
447 *
448 * @api
449 */
450#define OSAL_MS2RTC(freq, msec) MS2RTC(freq, msec)
451
452/**
453 * @brief Microseconds to realtime counter.
454 * @details Converts from microseconds to realtime counter cycles.
455 * @note The result is rounded upward to the next microsecond boundary.
456 * @note The macro assumes that @p freq >= @p 1000000.
457 *
458 * @param[in] freq clock frequency, in Hz, of the realtime counter
459 * @param[in] usec number of microseconds
460 * @return The number of cycles.
461 *
462 * @api
463 */
464#define OSAL_US2RTC(freq, usec) US2RTC(freq, usec)
465/** @} */
466
467/**
468 * @name Sleep macros using absolute time
469 * @{
470 */
471/**
472 * @brief Delays the invoking thread for the specified number of seconds.
473 * @note The specified time is rounded up to a value allowed by the real
474 * system tick clock.
475 * @note The maximum specifiable value is implementation dependent.
476 *
477 * @param[in] secs time in seconds, must be different from zero
478 *
479 * @api
480 */
481#define osalThreadSleepSeconds(secs) osalThreadSleep(OSAL_S2I(secs))
482
483/**
484 * @brief Delays the invoking thread for the specified number of
485 * milliseconds.
486 * @note The specified time is rounded up to a value allowed by the real
487 * system tick clock.
488 * @note The maximum specifiable value is implementation dependent.
489 *
490 * @param[in] msecs time in milliseconds, must be different from zero
491 *
492 * @api
493 */
494#define osalThreadSleepMilliseconds(msecs) osalThreadSleep(OSAL_MS2I(msecs))
495
496/**
497 * @brief Delays the invoking thread for the specified number of
498 * microseconds.
499 * @note The specified time is rounded up to a value allowed by the real
500 * system tick clock.
501 * @note The maximum specifiable value is implementation dependent.
502 *
503 * @param[in] usecs time in microseconds, must be different from zero
504 *
505 * @api
506 */
507#define osalThreadSleepMicroseconds(usecs) osalThreadSleep(OSAL_US2I(usecs))
508/** @} */
509
510/*===========================================================================*/
511/* External declarations. */
512/*===========================================================================*/
513
514#ifdef __cplusplus
515extern "C" {
516#endif
517
518#ifdef __cplusplus
519}
520#endif
521
522/*===========================================================================*/
523/* Module inline functions. */
524/*===========================================================================*/
525
526/**
527 * @brief OSAL module initialization.
528 *
529 * @api
530 */
531static inline void osalInit(void) {
532
533}
534
535/**
536 * @brief System halt with error message.
537 *
538 * @param[in] reason the halt message pointer
539 *
540 * @api
541 */
542static inline void osalSysHalt(const char *reason) {
543
544 chSysHalt(reason);
545}
546
547/**
548 * @brief Disables interrupts globally.
549 *
550 * @special
551 */
552static inline void osalSysDisable(void) {
553
554 chSysDisable();
555}
556
557/**
558 * @brief Enables interrupts globally.
559 *
560 * @special
561 */
562static inline void osalSysEnable(void) {
563
564 chSysEnable();
565}
566
567/**
568 * @brief Enters a critical zone from thread context.
569 * @note This function cannot be used for reentrant critical zones.
570 *
571 * @special
572 */
573static inline void osalSysLock(void) {
574
575 chSysLock();
576}
577
578/**
579 * @brief Leaves a critical zone from thread context.
580 * @note This function cannot be used for reentrant critical zones.
581 *
582 * @special
583 */
584static inline void osalSysUnlock(void) {
585
586 chSysUnlock();
587}
588
589/**
590 * @brief Enters a critical zone from ISR context.
591 * @note This function cannot be used for reentrant critical zones.
592 *
593 * @special
594 */
595static inline void osalSysLockFromISR(void) {
596
597 chSysLockFromISR();
598}
599
600/**
601 * @brief Leaves a critical zone from ISR context.
602 * @note This function cannot be used for reentrant critical zones.
603 *
604 * @special
605 */
606static inline void osalSysUnlockFromISR(void) {
607
608 chSysUnlockFromISR();
609}
610
611/**
612 * @brief Returns the execution status and enters a critical zone.
613 * @details This functions enters into a critical zone and can be called
614 * from any context. Because its flexibility it is less efficient
615 * than @p chSysLock() which is preferable when the calling context
616 * is known.
617 * @post The system is in a critical zone.
618 *
619 * @return The previous system status, the encoding of this
620 * status word is architecture-dependent and opaque.
621 *
622 * @xclass
623 */
624static inline syssts_t osalSysGetStatusAndLockX(void) {
625
626 return chSysGetStatusAndLockX();
627}
628
629/**
630 * @brief Restores the specified execution status and leaves a critical zone.
631 * @note A call to @p chSchRescheduleS() is automatically performed
632 * if exiting the critical zone and if not in ISR context.
633 *
634 * @param[in] sts the system status to be restored.
635 *
636 * @xclass
637 */
638static inline void osalSysRestoreStatusX(syssts_t sts) {
639
640 chSysRestoreStatusX(sts);
641}
642
643/**
644 * @brief Polled delay.
645 * @note The real delay is always few cycles in excess of the specified
646 * value.
647 *
648 * @param[in] cycles number of cycles
649 *
650 * @xclass
651 */
652#if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__)
653static inline void osalSysPolledDelayX(rtcnt_t cycles) {
654
655 chSysPolledDelayX(cycles);
656}
657#endif
658
659/**
660 * @brief Systick callback for the underlying OS.
661 * @note This callback is only defined if the OSAL requires such a
662 * service from the HAL.
663 */
664#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
665static inline void osalOsTimerHandlerI(void) {
666
667 chSysTimerHandlerI();
668}
669#endif
670
671/**
672 * @brief Checks if a reschedule is required and performs it.
673 * @note I-Class functions invoked from thread context must not reschedule
674 * by themselves, an explicit reschedule using this function is
675 * required in this scenario.
676 * @note Not implemented in this simplified OSAL.
677 *
678 * @sclass
679 */
680static inline void osalOsRescheduleS(void) {
681
682 chSchRescheduleS();
683}
684
685/**
686 * @brief Current system time.
687 * @details Returns the number of system ticks since the @p osalInit()
688 * invocation.
689 * @note The counter can reach its maximum and then restart from zero.
690 * @note This function can be called from any context but its atomicity
691 * is not guaranteed on architectures whose word size is less than
692 * @p systime_t size.
693 *
694 * @return The system time in ticks.
695 *
696 * @xclass
697 */
698static inline systime_t osalOsGetSystemTimeX(void) {
699
700 return chVTGetSystemTimeX();
701}
702
703/**
704 * @brief Adds an interval to a system time returning a system time.
705 *
706 * @param[in] systime base system time
707 * @param[in] interval interval to be added
708 * @return The new system time.
709 *
710 * @xclass
711 */
712static inline systime_t osalTimeAddX(systime_t systime,
713 sysinterval_t interval) {
714
715 return chTimeAddX(systime, interval);
716}
717
718/**
719 * @brief Subtracts two system times returning an interval.
720 *
721 * @param[in] start first system time
722 * @param[in] end second system time
723 * @return The interval representing the time difference.
724 *
725 * @xclass
726 */
727static inline sysinterval_t osalTimeDiffX(systime_t start, systime_t end) {
728
729 return chTimeDiffX(start, end);
730}
731
732/**
733 * @brief Checks if the specified time is within the specified time window.
734 * @note When start==end then the function returns always true because the
735 * whole time range is specified.
736 * @note This function can be called from any context.
737 *
738 * @param[in] time the time to be verified
739 * @param[in] start the start of the time window (inclusive)
740 * @param[in] end the end of the time window (non inclusive)
741 * @retval true current time within the specified time window.
742 * @retval false current time not within the specified time window.
743 *
744 * @xclass
745 */
746static inline bool osalTimeIsInRangeX(systime_t time,
747 systime_t start,
748 systime_t end) {
749
750 return chTimeIsInRangeX(time, start, end);
751}
752
753/**
754 * @brief Suspends the invoking thread for the specified time.
755 *
756 * @param[in] delay the delay in system ticks, the special values are
757 * handled as follow:
758 * - @a TIME_INFINITE is allowed but interpreted as a
759 * normal time specification.
760 * - @a TIME_IMMEDIATE this value is not allowed.
761 * .
762 *
763 * @sclass
764 */
765static inline void osalThreadSleepS(sysinterval_t delay) {
766
767 chThdSleepS(delay);
768}
769
770/**
771 * @brief Suspends the invoking thread for the specified time.
772 *
773 * @param[in] delay the delay in system ticks, the special values are
774 * handled as follow:
775 * - @a TIME_INFINITE is allowed but interpreted as a
776 * normal time specification.
777 * - @a TIME_IMMEDIATE this value is not allowed.
778 * .
779 *
780 * @api
781 */
782static inline void osalThreadSleep(sysinterval_t delay) {
783
784 chThdSleep(delay);
785}
786
787/**
788 * @brief Sends the current thread sleeping and sets a reference variable.
789 * @note This function must reschedule, it can only be called from thread
790 * context.
791 *
792 * @param[in] trp a pointer to a thread reference object
793 * @return The wake up message.
794 *
795 * @sclass
796 */
797static inline msg_t osalThreadSuspendS(thread_reference_t *trp) {
798
799 return chThdSuspendTimeoutS(trp, TIME_INFINITE);
800}
801
802/**
803 * @brief Sends the current thread sleeping and sets a reference variable.
804 * @note This function must reschedule, it can only be called from thread
805 * context.
806 *
807 * @param[in] trp a pointer to a thread reference object
808 * @param[in] timeout the timeout in system ticks, the special values are
809 * handled as follow:
810 * - @a TIME_INFINITE the thread enters an infinite sleep
811 * state.
812 * - @a TIME_IMMEDIATE the thread is not enqueued and
813 * the function returns @p MSG_TIMEOUT as if a timeout
814 * occurred.
815 * .
816 * @return The wake up message.
817 * @retval MSG_TIMEOUT if the operation timed out.
818 *
819 * @sclass
820 */
821static inline msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp,
822 sysinterval_t timeout) {
823
824 return chThdSuspendTimeoutS(trp, timeout);
825}
826
827/**
828 * @brief Wakes up a thread waiting on a thread reference object.
829 * @note This function must not reschedule because it can be called from
830 * ISR context.
831 *
832 * @param[in] trp a pointer to a thread reference object
833 * @param[in] msg the message code
834 *
835 * @iclass
836 */
837static inline void osalThreadResumeI(thread_reference_t *trp, msg_t msg) {
838
839 chThdResumeI(trp, msg);
840}
841
842/**
843 * @brief Wakes up a thread waiting on a thread reference object.
844 * @note This function must reschedule, it can only be called from thread
845 * context.
846 *
847 * @param[in] trp a pointer to a thread reference object
848 * @param[in] msg the message code
849 *
850 * @iclass
851 */
852static inline void osalThreadResumeS(thread_reference_t *trp, msg_t msg) {
853
854 chThdResumeS(trp, msg);
855}
856
857/**
858 * @brief Initializes a threads queue object.
859 *
860 * @param[out] tqp pointer to the threads queue object
861 *
862 * @init
863 */
864static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) {
865
866 chThdQueueObjectInit(tqp);
867}
868
869/**
870 * @brief Enqueues the caller thread.
871 * @details The caller thread is enqueued and put to sleep until it is
872 * dequeued or the specified timeouts expires.
873 *
874 * @param[in] tqp pointer to the threads queue object
875 * @param[in] timeout the timeout in system ticks, the special values are
876 * handled as follow:
877 * - @a TIME_INFINITE the thread enters an infinite sleep
878 * state.
879 * - @a TIME_IMMEDIATE the thread is not enqueued and
880 * the function returns @p MSG_TIMEOUT as if a timeout
881 * occurred.
882 * .
883 * @return The message from @p osalQueueWakeupOneI() or
884 * @p osalQueueWakeupAllI() functions.
885 * @retval MSG_TIMEOUT if the thread has not been dequeued within the
886 * specified timeout or if the function has been
887 * invoked with @p TIME_IMMEDIATE as timeout
888 * specification.
889 *
890 * @sclass
891 */
892static inline msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp,
893 sysinterval_t timeout) {
894
895 return chThdEnqueueTimeoutS(tqp, timeout);
896}
897
898/**
899 * @brief Dequeues and wakes up one thread from the queue, if any.
900 *
901 * @param[in] tqp pointer to the threads queue object
902 * @param[in] msg the message code
903 *
904 * @iclass
905 */
906static inline void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) {
907
908 chThdDequeueNextI(tqp, msg);
909}
910
911/**
912 * @brief Dequeues and wakes up all threads from the queue.
913 *
914 * @param[in] tqp pointer to the threads queue object
915 * @param[in] msg the message code
916 *
917 * @iclass
918 */
919static inline void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) {
920
921 chThdDequeueAllI(tqp, msg);
922}
923
924#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
925/**
926 * @brief Initializes an event source object.
927 *
928 * @param[out] esp pointer to the event source object
929 *
930 * @init
931 */
932static inline void osalEventObjectInit(event_source_t *esp) {
933
934 chEvtObjectInit(esp);
935}
936#else
937static inline void osalEventObjectInit(event_source_t *esp) {
938
939 osalDbgCheck(esp != NULL);
940
941 esp->flags = (eventflags_t)0;
942 esp->cb = NULL;
943 esp->param = NULL;
944}
945#endif
946
947#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
948/**
949 * @brief Add flags to an event source object.
950 *
951 * @param[in] esp pointer to the event flags object
952 * @param[in] flags flags to be ORed to the flags mask
953 *
954 * @iclass
955 */
956static inline void osalEventBroadcastFlagsI(event_source_t *esp,
957 eventflags_t flags) {
958
959 chEvtBroadcastFlagsI(esp, flags);
960}
961#else
962static inline void osalEventBroadcastFlagsI(event_source_t *esp,
963 eventflags_t flags) {
964
965 osalDbgCheck(esp != NULL);
966
967 esp->flags |= flags;
968 if (esp->cb != NULL) {
969 esp->cb(esp);
970 }
971}
972#endif
973
974#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
975/**
976 * @brief Add flags to an event source object.
977 *
978 * @param[in] esp pointer to the event flags object
979 * @param[in] flags flags to be ORed to the flags mask
980 *
981 * @iclass
982 */
983static inline void osalEventBroadcastFlags(event_source_t *esp,
984 eventflags_t flags) {
985
986 chEvtBroadcastFlags(esp, flags);
987}
988#else
989static inline void osalEventBroadcastFlags(event_source_t *esp,
990 eventflags_t flags) {
991
992 osalDbgCheck(esp != NULL);
993
994 osalSysLock();
995 esp->flags |= flags;
996 if (esp->cb != NULL) {
997 esp->cb(esp);
998 }
999 osalSysUnlock();
1000}
1001#endif
1002
1003#if (CH_CFG_USE_EVENTS == FALSE) || defined(__DOXYGEN__)
1004/**
1005 * @brief Event callback setup.
1006 * @note The callback is invoked from ISR context and can
1007 * only invoke I-Class functions. The callback is meant
1008 * to wakeup the task that will handle the event by
1009 * calling @p osalEventGetAndClearFlagsI().
1010 *
1011 * @param[in] esp pointer to the event flags object
1012 * @param[in] cb pointer to the callback function
1013 * @param[in] param parameter to be passed to the callback function
1014 *
1015 * @api
1016 */
1017static inline void osalEventSetCallback(event_source_t *esp,
1018 eventcallback_t cb,
1019 void *param) {
1020
1021 osalDbgCheck(esp != NULL);
1022
1023 esp->cb = cb;
1024 esp->param = param;
1025}
1026#endif
1027
1028/**
1029 * @brief Initializes s @p mutex_t object.
1030 *
1031 * @param[out] mp pointer to the @p mutex_t object
1032 *
1033 * @init
1034 */
1035static inline void osalMutexObjectInit(mutex_t *mp) {
1036
1037#if CH_CFG_USE_MUTEXES
1038 chMtxObjectInit(mp);
1039#elif CH_CFG_USE_SEMAPHORES
1040 chSemObjectInit((semaphore_t *)mp, 1);
1041#else
1042 *mp = 0;
1043#endif
1044}
1045
1046/**
1047 * @brief Locks the specified mutex.
1048 * @post The mutex is locked and inserted in the per-thread stack of owned
1049 * mutexes.
1050 *
1051 * @param[in,out] mp pointer to the @p mutex_t object
1052 *
1053 * @api
1054 */
1055static inline void osalMutexLock(mutex_t *mp) {
1056
1057#if CH_CFG_USE_MUTEXES
1058 chMtxLock(mp);
1059#elif CH_CFG_USE_SEMAPHORES
1060 chSemWait((semaphore_t *)mp);
1061#else
1062 *mp = 1;
1063#endif
1064}
1065
1066/**
1067 * @brief Unlocks the specified mutex.
1068 * @note The HAL guarantees to release mutex in reverse lock order. The
1069 * mutex being unlocked is guaranteed to be the last locked mutex
1070 * by the invoking thread.
1071 * The implementation can rely on this behavior and eventually
1072 * ignore the @p mp parameter which is supplied in order to support
1073 * those OSes not supporting a stack of the owned mutexes.
1074 *
1075 * @param[in,out] mp pointer to the @p mutex_t object
1076 *
1077 * @api
1078 */
1079static inline void osalMutexUnlock(mutex_t *mp) {
1080
1081#if CH_CFG_USE_MUTEXES
1082 chMtxUnlock(mp);
1083#elif CH_CFG_USE_SEMAPHORES
1084 chSemSignal((semaphore_t *)mp);
1085#else
1086 *mp = 0;
1087#endif
1088}
1089
1090#endif /* OSAL_H */
1091
1092/** @} */
diff --git a/lib/chibios/os/hal/osal/rt-nil/osal.mk b/lib/chibios/os/hal/osal/rt-nil/osal.mk
new file mode 100644
index 000000000..98f162f83
--- /dev/null
+++ b/lib/chibios/os/hal/osal/rt-nil/osal.mk
@@ -0,0 +1,9 @@
1# OSAL files.
2OSALSRC += ${CHIBIOS}/os/hal/osal/rt-nil/osal.c
3
4# Required include directories
5OSALINC += ${CHIBIOS}/os/hal/osal/rt-nil
6
7# Shared variables
8ALLCSRC += $(OSALSRC)
9ALLINC += $(OSALINC)