diff options
author | Clyne Sullivan <clyne@bitgloo.com> | 2021-01-22 21:43:36 -0500 |
---|---|---|
committer | Clyne Sullivan <clyne@bitgloo.com> | 2021-01-22 21:43:36 -0500 |
commit | 48026bb824fd2d9cfb00ecd040db6ef3a416bae9 (patch) | |
tree | c14713aedfe78ee8b34f2e1252408782e2e2ff5d /ChibiOS_20.3.2/os/hal/osal | |
parent | e080a26651f90c88176140d63a74c93c2f4041a2 (diff) |
upload initial port
Diffstat (limited to 'ChibiOS_20.3.2/os/hal/osal')
-rw-r--r-- | ChibiOS_20.3.2/os/hal/osal/lib/osal_vt.c | 168 | ||||
-rw-r--r-- | ChibiOS_20.3.2/os/hal/osal/lib/osal_vt.h | 123 | ||||
-rw-r--r-- | ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.c | 467 | ||||
-rw-r--r-- | ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.h | 754 | ||||
-rw-r--r-- | ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.mk | 11 | ||||
-rw-r--r-- | ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.c | 467 | ||||
-rw-r--r-- | ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.h | 677 | ||||
-rw-r--r-- | ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.mk | 9 | ||||
-rw-r--r-- | ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.c | 51 | ||||
-rw-r--r-- | ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.h | 1028 | ||||
-rw-r--r-- | ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.mk | 9 |
11 files changed, 3764 insertions, 0 deletions
diff --git a/ChibiOS_20.3.2/os/hal/osal/lib/osal_vt.c b/ChibiOS_20.3.2/os/hal/osal/lib/osal_vt.c new file mode 100644 index 0000000..7d92d13 --- /dev/null +++ b/ChibiOS_20.3.2/os/hal/osal/lib/osal_vt.c @@ -0,0 +1,168 @@ +/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file osal_vt.c
+ * @brief OSAL Virtual Timers module code.
+ * @details This module can be used in an OSAL implementation whenever an
+ * underlying RTOS is unable to provide timeout services or there
+ * is no underlying RTOS.
+ *
+ * @addtogroup OSAL_VT
+ * @{
+ */
+
+#include "osal.h"
+#include "osal_vt.h"
+
+/*===========================================================================*/
+/* Module local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief Virtual timers delta list header.
+ */
+virtual_timers_list_t vtlist;
+
+/*===========================================================================*/
+/* Module local types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Timers initialization.
+ *
+ * @init
+ */
+void vtInit(void) {
+
+ /* Virtual Timers initialization.*/
+ vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist;
+ vtlist.vt_delta = (sysinterval_t)-1;
+ vtlist.vt_systime = 0;
+}
+
+/**
+ * @brief Returns @p TRUE if the specified timer is armed.
+ *
+ * @param[out] vtp the @p virtual_timer_t structure pointer
+ *
+ * @iclass
+ */
+bool vtIsArmedI(virtual_timer_t *vtp) {
+
+ return vtp->vt_func != NULL;
+}
+
+/**
+ * @brief Virtual timers ticker.
+ * @note The system lock is released before entering the callback and
+ * re-acquired immediately after. It is callback's responsibility
+ * to acquire the lock if needed. This is done in order to reduce
+ * interrupts jitter when many timers are in use.
+ *
+ * @iclass
+ */
+void vtDoTickI(void) {
+
+ vtlist.vt_systime++;
+ if (&vtlist != (virtual_timers_list_t *)vtlist.vt_next) {
+ virtual_timer_t *vtp;
+
+ --vtlist.vt_next->vt_delta;
+ while (!(vtp = vtlist.vt_next)->vt_delta) {
+ vtfunc_t fn = vtp->vt_func;
+ vtp->vt_func = (vtfunc_t)NULL;
+ vtp->vt_next->vt_prev = (void *)&vtlist;
+ (&vtlist)->vt_next = vtp->vt_next;
+ osalSysUnlockFromISR();
+ fn(vtp->vt_par);
+ osalSysLockFromISR();
+ }
+ }
+}
+
+/**
+ * @brief Enables a virtual timer.
+ * @note The associated function is invoked from interrupt context.
+ *
+ * @param[out] vtp the @p virtual_timer_t structure pointer
+ * @param[in] timeout the number of ticks before the operation timeouts, the
+ * special values are handled as follow:
+ * - @a TIME_INFINITE is allowed but interpreted as a
+ * normal time specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
+ * @param[in] vtfunc the timer callback function. After invoking the
+ * callback the timer is disabled and the structure can
+ * be disposed or reused.
+ * @param[in] par a parameter that will be passed to the callback
+ * function
+ *
+ * @iclass
+ */
+void vtSetI(virtual_timer_t *vtp, sysinterval_t timeout,
+ vtfunc_t vtfunc, void *par) {
+ virtual_timer_t *p;
+
+ vtp->vt_par = par;
+ vtp->vt_func = vtfunc;
+ p = vtlist.vt_next;
+ while (p->vt_delta < timeout) {
+ timeout -= p->vt_delta;
+ p = p->vt_next;
+ }
+
+ vtp->vt_prev = (vtp->vt_next = p)->vt_prev;
+ vtp->vt_prev->vt_next = p->vt_prev = vtp;
+ vtp->vt_delta = timeout;
+ if (p != (void *)&vtlist)
+ p->vt_delta -= timeout;
+}
+
+/**
+ * @brief Disables a Virtual Timer.
+ * @note The timer MUST be active when this function is invoked.
+ *
+ * @param[in] vtp the @p virtual_timer_t structure pointer
+ *
+ * @iclass
+ */
+void vtResetI(virtual_timer_t *vtp) {
+
+ if (vtp->vt_next != (void *)&vtlist)
+ vtp->vt_next->vt_delta += vtp->vt_delta;
+ vtp->vt_prev->vt_next = vtp->vt_next;
+ vtp->vt_next->vt_prev = vtp->vt_prev;
+ vtp->vt_func = (vtfunc_t)NULL;
+}
+
+/** @} */
diff --git a/ChibiOS_20.3.2/os/hal/osal/lib/osal_vt.h b/ChibiOS_20.3.2/os/hal/osal/lib/osal_vt.h new file mode 100644 index 0000000..4926bc5 --- /dev/null +++ b/ChibiOS_20.3.2/os/hal/osal/lib/osal_vt.h @@ -0,0 +1,123 @@ +/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file osal_vt.h
+ * @brief OSAL Virtual Timers module header.
+ *
+ * @addtogroup OSAL_VT
+ * @{
+ */
+
+#ifndef _OSAL_VT_H_
+#define _OSAL_VT_H_
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a Virtual Timer callback function.
+ */
+typedef void (*vtfunc_t)(void *);
+
+/**
+ * @brief Type of a Virtual Timer structure.
+ */
+typedef struct virtual_timer virtual_timer_t;
+
+/**
+ * @brief Virtual timers list header.
+ * @note The content of this structure is not part of the API and should
+ * not be relied upon. Implementers may define this structure in
+ * an entirely different way.
+ * @note The delta list is implemented as a double link bidirectional list
+ * in order to make the unlink time constant, the reset of a virtual
+ * timer is often used in the code.
+ */
+typedef struct {
+ virtual_timer_t *vt_next; /**< @brief Next timer in the timers
+ list. */
+ virtual_timer_t *vt_prev; /**< @brief Last timer in the timers
+ list. */
+ sysinterval_t vt_delta; /**< @brief Must be initialized to -1. */
+ volatile systime_t vt_systime; /**< @brief System Time counter. */
+} virtual_timers_list_t;
+
+/**
+ * @extends virtual_timers_list_t
+ *
+ * @brief Virtual Timer descriptor structure.
+ * @note The content of this structure is not part of the API and should
+ * not be relied upon. Implementers may define this structure in
+ * an entirely different way.
+ */
+struct virtual_timer {
+ virtual_timer_t *vt_next; /**< @brief Next timer in the timers
+ list. */
+ virtual_timer_t *vt_prev; /**< @brief Previous timer in the timers
+ list. */
+ sysinterval_t vt_delta; /**< @brief Time delta before timeout. */
+ vtfunc_t vt_func; /**< @brief Timer callback function
+ pointer. */
+ void *vt_par; /**< @brief Timer callback function
+ parameter. */
+};
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#if !defined(__DOXYGEN__)
+extern virtual_timers_list_t vtlist;
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void vtInit(void);
+ bool vtIsArmedI(virtual_timer_t *vtp);
+ void vtDoTickI(void);
+ void vtSetI(virtual_timer_t *vtp, sysinterval_t timeout,
+ vtfunc_t vtfunc, void *par);
+ void vtResetI(virtual_timer_t *vtp);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+#endif /* _OSAL_VT_H_ */
+
+/** @} */
diff --git a/ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.c b/ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.c new file mode 100644 index 0000000..5c62069 --- /dev/null +++ b/ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.c @@ -0,0 +1,467 @@ +/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file osal.c
+ * @brief OSAL module code.
+ *
+ * @addtogroup OSAL
+ * @{
+ */
+
+#include "osal.h"
+#include "osal_vt.h"
+
+/*===========================================================================*/
+/* Module local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief Pointer to a halt error message.
+ * @note The message is meant to be retrieved by the debugger after the
+ * system halt caused by an unexpected error.
+ */
+const char *osal_halt_msg;
+
+/*===========================================================================*/
+/* Module local types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local functions. */
+/*===========================================================================*/
+
+static void callback_timeout(void *p) {
+ osalSysLockFromISR();
+ osalThreadResumeI((thread_reference_t *)p, MSG_TIMEOUT);
+ osalSysUnlockFromISR();
+}
+
+/*===========================================================================*/
+/* Module exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief OSAL module initialization.
+ *
+ * @api
+ */
+void osalInit(void) {
+
+ vtInit();
+
+ OSAL_INIT_HOOK();
+}
+
+/**
+ * @brief System halt with error message.
+ *
+ * @param[in] reason the halt message pointer
+ *
+ * @api
+ */
+#if !defined(__DOXYGEN__)
+__attribute__((weak, noreturn))
+#endif
+void osalSysHalt(const char *reason) {
+
+ osalSysDisable();
+ osal_halt_msg = reason;
+ while (true) {
+ }
+}
+
+/**
+ * @brief Polled delay.
+ * @note The real delay is always few cycles in excess of the specified
+ * value.
+ *
+ * @param[in] cycles number of cycles
+ *
+ * @xclass
+ */
+void osalSysPolledDelayX(rtcnt_t cycles) {
+
+ (void)cycles;
+}
+
+/**
+ * @brief System timer handler.
+ * @details The handler is used for scheduling and Virtual Timers management.
+ *
+ * @iclass
+ */
+void osalOsTimerHandlerI(void) {
+
+ osalDbgCheckClassI();
+
+ vtDoTickI();
+}
+
+/**
+ * @brief Checks if a reschedule is required and performs it.
+ * @note I-Class functions invoked from thread context must not reschedule
+ * by themselves, an explicit reschedule using this function is
+ * required in this scenario.
+ * @note Not implemented in this simplified OSAL.
+ *
+ * @sclass
+ */
+void osalOsRescheduleS(void) {
+
+}
+
+/**
+ * @brief Current system time.
+ * @details Returns the number of system ticks since the @p osalInit()
+ * invocation.
+ * @note The counter can reach its maximum and then restart from zero.
+ * @note This function can be called from any context but its atomicity
+ * is not guaranteed on architectures whose word size is less than
+ * @p systime_t size.
+ *
+ * @return The system time in ticks.
+ *
+ * @xclass
+ */
+systime_t osalOsGetSystemTimeX(void) {
+
+ return vtlist.vt_systime;
+}
+
+/**
+ * @brief Suspends the invoking thread for the specified time.
+ *
+ * @param[in] time the delay in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE is allowed but interpreted as a
+ * normal time specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
+ *
+ * @sclass
+ */
+void osalThreadSleepS(sysinterval_t time) {
+ virtual_timer_t vt;
+ thread_reference_t tr;
+
+ tr = NULL;
+ vtSetI(&vt, time, callback_timeout, (void *)&tr);
+ osalThreadSuspendS(&tr);
+}
+
+/**
+ * @brief Suspends the invoking thread for the specified time.
+ *
+ * @param[in] time the delay in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE is allowed but interpreted as a
+ * normal time specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
+ *
+ * @api
+ */
+void osalThreadSleep(sysinterval_t time) {
+
+ osalSysLock();
+ osalThreadSleepS(time);
+ osalSysUnlock();
+}
+
+/**
+ * @brief Sends the current thread sleeping and sets a reference variable.
+ * @note This function must reschedule, it can only be called from thread
+ * context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @return The wake up message.
+ *
+ * @sclass
+ */
+msg_t osalThreadSuspendS(thread_reference_t *trp) {
+ thread_t self = {MSG_WAIT};
+
+ osalDbgCheck(trp != NULL);
+
+ *trp = &self;
+ while (self.message == MSG_WAIT) {
+ osalSysUnlock();
+ /* A state-changing interrupt could occur here and cause the loop to
+ terminate, an hook macro is executed while waiting.*/
+ OSAL_IDLE_HOOK();
+ osalSysLock();
+ }
+
+ return self.message;
+}
+
+/**
+ * @brief Sends the current thread sleeping and sets a reference variable.
+ * @note This function must reschedule, it can only be called from thread
+ * context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @param[in] timeout the timeout in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE the thread enters an infinite sleep
+ * state.
+ * - @a TIME_IMMEDIATE the thread is not enqueued and
+ * the function returns @p MSG_TIMEOUT as if a timeout
+ * occurred.
+ * .
+ * @return The wake up message.
+ * @retval MSG_TIMEOUT if the operation timed out.
+ *
+ * @sclass
+ */
+msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout) {
+ msg_t msg;
+ virtual_timer_t vt;
+
+ osalDbgCheck(trp != NULL);
+
+ if (TIME_INFINITE == timeout)
+ return osalThreadSuspendS(trp);
+
+ vtSetI(&vt, timeout, callback_timeout, (void *)trp);
+ msg = osalThreadSuspendS(trp);
+ if (vtIsArmedI(&vt))
+ vtResetI(&vt);
+
+ return msg;
+}
+
+/**
+ * @brief Wakes up a thread waiting on a thread reference object.
+ * @note This function must not reschedule because it can be called from
+ * ISR context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+void osalThreadResumeI(thread_reference_t *trp, msg_t msg) {
+
+ osalDbgCheck(trp != NULL);
+
+ if (*trp != NULL) {
+ (*trp)->message = msg;
+ *trp = NULL;
+ }
+}
+
+/**
+ * @brief Wakes up a thread waiting on a thread reference object.
+ * @note This function must reschedule, it can only be called from thread
+ * context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+void osalThreadResumeS(thread_reference_t *trp, msg_t msg) {
+
+ osalDbgCheck(trp != NULL);
+
+ if (*trp != NULL) {
+ (*trp)->message = msg;
+ *trp = NULL;
+ }
+}
+
+/**
+ * @brief Enqueues the caller thread.
+ * @details The caller thread is enqueued and put to sleep until it is
+ * dequeued or the specified timeouts expires.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] timeout the timeout in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE the thread enters an infinite sleep
+ * state.
+ * - @a TIME_IMMEDIATE the thread is not enqueued and
+ * the function returns @p MSG_TIMEOUT as if a timeout
+ * occurred.
+ * .
+ * @return The message from @p osalQueueWakeupOneI() or
+ * @p osalQueueWakeupAllI() functions.
+ * @retval MSG_TIMEOUT if the thread has not been dequeued within the
+ * specified timeout or if the function has been
+ * invoked with @p TIME_IMMEDIATE as timeout
+ * specification.
+ *
+ * @sclass
+ */
+msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) {
+ msg_t msg;
+ virtual_timer_t vt;
+
+ osalDbgCheck(tqp != NULL);
+
+ if (TIME_IMMEDIATE == timeout)
+ return MSG_TIMEOUT;
+
+ tqp->tr = NULL;
+
+ if (TIME_INFINITE == timeout)
+ return osalThreadSuspendS(&tqp->tr);
+
+ vtSetI(&vt, timeout, callback_timeout, (void *)&tqp->tr);
+ msg = osalThreadSuspendS(&tqp->tr);
+ if (vtIsArmedI(&vt))
+ vtResetI(&vt);
+
+ return msg;
+}
+
+/**
+ * @brief Dequeues and wakes up one thread from the queue, if any.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) {
+
+ osalDbgCheck(tqp != NULL);
+
+ osalThreadResumeI(&tqp->tr, msg);
+}
+
+/**
+ * @brief Dequeues and wakes up all threads from the queue.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) {
+
+ osalDbgCheck(tqp != NULL);
+
+ osalThreadResumeI(&tqp->tr, msg);
+}
+
+/**
+ * @brief Add flags to an event source object.
+ *
+ * @param[in] esp pointer to the event flags object
+ * @param[in] flags flags to be ORed to the flags mask
+ *
+ * @iclass
+ */
+void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags) {
+
+ osalDbgCheck(esp != NULL);
+
+ esp->flags |= flags;
+ if (esp->cb != NULL) {
+ esp->cb(esp);
+ }
+}
+
+/**
+ * @brief Add flags to an event source object.
+ *
+ * @param[in] esp pointer to the event flags object
+ * @param[in] flags flags to be ORed to the flags mask
+ *
+ * @iclass
+ */
+void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags) {
+
+ osalDbgCheck(esp != NULL);
+
+ osalSysLock();
+ osalEventBroadcastFlagsI(esp, flags);
+ osalSysUnlock();
+}
+
+/**
+ * @brief Event callback setup.
+ * @note The callback is invoked from ISR context and can
+ * only invoke I-Class functions. The callback is meant
+ * to wakeup the task that will handle the event by
+ * calling @p osalEventGetAndClearFlagsI().
+ * @note This function is not part of the OSAL API and is provided
+ * exclusively as an example and for convenience.
+ *
+ * @param[in] esp pointer to the event flags object
+ * @param[in] cb pointer to the callback function
+ * @param[in] param parameter to be passed to the callback function
+ *
+ * @api
+ */
+void osalEventSetCallback(event_source_t *esp,
+ eventcallback_t cb,
+ void *param) {
+
+ osalDbgCheck(esp != NULL);
+
+ esp->cb = cb;
+ esp->param = param;
+}
+
+/**
+ * @brief Locks the specified mutex.
+ * @post The mutex is locked and inserted in the per-thread stack of owned
+ * mutexes.
+ *
+ * @param[in,out] mp pointer to the @p mutex_t object
+ *
+ * @api
+ */
+void osalMutexLock(mutex_t *mp) {
+
+ osalDbgCheck(mp != NULL);
+
+ *mp = 1;
+}
+
+/**
+ * @brief Unlocks the specified mutex.
+ * @note The HAL guarantees to release mutex in reverse lock order. The
+ * mutex being unlocked is guaranteed to be the last locked mutex
+ * by the invoking thread.
+ * The implementation can rely on this behavior and eventually
+ * ignore the @p mp parameter which is supplied in order to support
+ * those OSes not supporting a stack of the owned mutexes.
+ *
+ * @param[in,out] mp pointer to the @p mutex_t object
+ *
+ * @api
+ */
+void osalMutexUnlock(mutex_t *mp) {
+
+ osalDbgCheck(mp != NULL);
+
+ *mp = 0;
+}
+
+/** @} */
diff --git a/ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.h b/ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.h new file mode 100644 index 0000000..362a30c --- /dev/null +++ b/ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.h @@ -0,0 +1,754 @@ +/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file osal.h
+ * @brief OSAL module header.
+ *
+ * @addtogroup OSAL
+ * @{
+ */
+
+#ifndef OSAL_H
+#define OSAL_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "cmparams.h"
+
+#include "osalconf.h"
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/**
+ * @name Common constants
+ * @{
+ */
+#if !defined(FALSE) || defined(__DOXYGEN__)
+#define FALSE 0
+#endif
+
+#if !defined(TRUE) || defined(__DOXYGEN__)
+#define TRUE 1
+#endif
+
+#define OSAL_SUCCESS false
+#define OSAL_FAILED true
+/** @} */
+
+/**
+ * @name Messages
+ * @{
+ */
+#define MSG_OK (msg_t)0
+#define MSG_RESET (msg_t)-1
+#define MSG_TIMEOUT (msg_t)-2
+#define MSG_WAIT (msg_t)-10
+/** @} */
+
+/**
+ * @name Special time constants
+ * @{
+ */
+#define TIME_IMMEDIATE ((sysinterval_t)0)
+#define TIME_INFINITE ((sysinterval_t)-1)
+/** @} */
+
+/**
+ * @name Systick modes.
+ * @{
+ */
+#define OSAL_ST_MODE_NONE 0
+#define OSAL_ST_MODE_PERIODIC 1
+#define OSAL_ST_MODE_FREERUNNING 2
+/** @} */
+
+/**
+ * @name Systick parameters.
+ * @{
+ */
+/**
+ * @brief Size in bits of the @p systick_t type.
+ */
+#define OSAL_ST_RESOLUTION 32
+
+/**
+ * @brief Systick mode required by the underlying OS.
+ */
+#define OSAL_ST_MODE OSAL_ST_MODE_PERIODIC
+/** @} */
+
+/**
+ * @name IRQ-related constants
+ * @{
+ */
+/**
+ * @brief Total priority levels.
+ */
+#define OSAL_IRQ_PRIORITY_LEVELS (1U << CORTEX_PRIORITY_BITS)
+
+/**
+ * @brief Highest IRQ priority for HAL drivers.
+ */
+#if (CORTEX_MODEL == 0) || defined(__DOXYGEN__)
+#define OSAL_IRQ_MAXIMUM_PRIORITY 0
+#else
+#define OSAL_IRQ_MAXIMUM_PRIORITY 1
+#endif
+
+/**
+ * @brief Converts from numeric priority to BASEPRI register value.
+ */
+#define OSAL_BASEPRI(priority) ((priority) << (8U - CORTEX_PRIORITY_BITS))
+/** @} */
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Frequency in Hertz of the system tick.
+ */
+#if !defined(OSAL_ST_FREQUENCY) || defined(__DOXYGEN__)
+#define OSAL_ST_FREQUENCY 1000
+#endif
+
+/**
+ * @brief Enables OSAL assertions.
+ */
+#if !defined(OSAL_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
+#define OSAL_DBG_ENABLE_ASSERTS FALSE
+#endif
+
+/**
+ * @brief Enables OSAL functions parameters checks.
+ */
+#if !defined(OSAL_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
+#define OSAL_DBG_ENABLE_CHECKS FALSE
+#endif
+
+/**
+ * @brief OSAL initialization hook.
+ */
+#if !defined(OSAL_INIT_HOOK) || defined(__DOXYGEN__)
+#define OSAL_INIT_HOOK()
+#endif
+
+/**
+ * @brief Idle loop hook macro.
+ */
+#if !defined(OSAL_IDLE_HOOK) || defined(__DOXYGEN__)
+#define OSAL_IDLE_HOOK()
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a system status word.
+ */
+typedef uint32_t syssts_t;
+
+/**
+ * @brief Type of a message.
+ */
+typedef int32_t msg_t;
+
+/**
+ * @brief Type of system time counter.
+ */
+typedef uint32_t systime_t;
+
+/**
+ * @brief Type of system time interval.
+ */
+typedef uint32_t sysinterval_t;
+
+/**
+ * @brief Type of realtime counter.
+ */
+typedef uint32_t rtcnt_t;
+
+/**
+ * @brief Type of a thread.
+ * @note The content of this structure is not part of the API and should
+ * not be relied upon. Implementers may define this structure in
+ * an entirely different way.
+ */
+typedef struct {
+ volatile msg_t message;
+} thread_t;
+
+/**
+ * @brief Type of a thread reference.
+ */
+typedef thread_t * thread_reference_t;
+
+/**
+ * @brief Type of an event flags mask.
+ */
+typedef uint32_t eventflags_t;
+
+/**
+ * @brief Type of an event flags object.
+ * @note The content of this structure is not part of the API and should
+ * not be relied upon. Implementers may define this structure in
+ * an entirely different way.
+ * @note Retrieval and clearing of the flags are not defined in this
+ * API and are implementation-dependent.
+ */
+typedef struct event_source event_source_t;
+
+/**
+ * @brief Type of an event source callback.
+ * @note This type is not part of the OSAL API and is provided
+ * exclusively as an example and for convenience.
+ */
+typedef void (*eventcallback_t)(event_source_t *esp);
+
+/**
+ * @brief Events source object.
+ * @note The content of this structure is not part of the API and should
+ * not be relied upon. Implementers may define this structure in
+ * an entirely different way.
+ * @note Retrieval and clearing of the flags are not defined in this
+ * API and are implementation-dependent.
+ */
+struct event_source {
+ volatile eventflags_t flags; /**< @brief Stored event flags. */
+ eventcallback_t cb; /**< @brief Event source callback. */
+ void *param; /**< @brief User defined field. */
+};
+
+/**
+ * @brief Type of a mutex.
+ * @note If the OS does not support mutexes or there is no OS then them
+ * mechanism can be simulated.
+ */
+typedef uint32_t mutex_t;
+
+/**
+ * @brief Type of a thread queue.
+ * @details A thread queue is a queue of sleeping threads, queued threads
+ * can be dequeued one at time or all together.
+ * @note If the OSAL is implemented on a bare metal machine without RTOS
+ * then the queue can be implemented as a single thread reference.
+ */
+typedef struct {
+ thread_reference_t tr;
+} threads_queue_t;
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @name Debug related macros
+ * @{
+ */
+/**
+ * @brief Condition assertion.
+ * @details If the condition check fails then the OSAL panics with a
+ * message and halts.
+ * @note The condition is tested only if the @p OSAL_ENABLE_ASSERTIONS
+ * switch is enabled.
+ * @note The remark string is not currently used except for putting a
+ * comment in the code about the assertion.
+ *
+ * @param[in] c the condition to be verified to be true
+ * @param[in] remark a remark string
+ *
+ * @api
+ */
+#define osalDbgAssert(c, remark) do { \
+ /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
+ if (OSAL_DBG_ENABLE_ASSERTS != FALSE) { \
+ if (!(c)) { \
+ /*lint -restore*/ \
+ osalSysHalt(__func__); \
+ } \
+ } \
+} while (false)
+
+/**
+ * @brief Function parameters check.
+ * @details If the condition check fails then the OSAL panics and halts.
+ * @note The condition is tested only if the @p OSAL_ENABLE_CHECKS switch
+ * is enabled.
+ *
+ * @param[in] c the condition to be verified to be true
+ *
+ * @api
+ */
+#define osalDbgCheck(c) do { \
+ /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
+ if (OSAL_DBG_ENABLE_CHECKS != FALSE) { \
+ if (!(c)) { \
+ /*lint -restore*/ \
+ osalSysHalt(__func__); \
+ } \
+ } \
+} while (false)
+
+/**
+ * @brief I-Class state check.
+ * @note Implementation is optional.
+ */
+#define osalDbgCheckClassI()
+
+/**
+ * @brief S-Class state check.
+ * @note Implementation is optional.
+ */
+#define osalDbgCheckClassS()
+/** @} */
+
+/**
+ * @name IRQ service routines wrappers
+ * @{
+ */
+/**
+ * @brief Priority level verification macro.
+ */
+#define OSAL_IRQ_IS_VALID_PRIORITY(n) \
+ (((n) >= OSAL_IRQ_MAXIMUM_PRIORITY) && ((n) < OSAL_IRQ_PRIORITY_LEVELS))
+
+/**
+ * @brief IRQ prologue code.
+ * @details This macro must be inserted at the start of all IRQ handlers.
+ */
+#define OSAL_IRQ_PROLOGUE()
+
+/**
+ * @brief IRQ epilogue code.
+ * @details This macro must be inserted at the end of all IRQ handlers.
+ */
+#define OSAL_IRQ_EPILOGUE()
+
+/**
+ * @brief IRQ handler function declaration.
+ * @details This macro hides the details of an ISR function declaration.
+ *
+ * @param[in] id a vector name as defined in @p vectors.s
+ */
+#define OSAL_IRQ_HANDLER(id) void id(void)
+/** @} */
+
+/**
+ * @name Time conversion utilities
+ * @{
+ */
+/**
+ * @brief Seconds to system ticks.
+ * @details Converts from seconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] secs number of seconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define OSAL_S2I(secs) \
+ ((sysinterval_t)((uint32_t)(secs) * (uint32_t)OSAL_ST_FREQUENCY))
+
+/**
+ * @brief Milliseconds to system ticks.
+ * @details Converts from milliseconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] msecs number of milliseconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define OSAL_MS2I(msecs) \
+ ((sysinterval_t)((((((uint32_t)(msecs)) * \
+ ((uint32_t)OSAL_ST_FREQUENCY)) - 1UL) / 1000UL) + 1UL))
+
+/**
+ * @brief Microseconds to system ticks.
+ * @details Converts from microseconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] usecs number of microseconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define OSAL_US2I(usecs) \
+ ((sysinterval_t)((((((uint32_t)(usecs)) * \
+ ((uint32_t)OSAL_ST_FREQUENCY)) - 1UL) / 1000000UL) + 1UL))
+/** @} */
+
+/**
+ * @name Time conversion utilities for the realtime counter
+ * @{
+ */
+/**
+ * @brief Seconds to realtime counter.
+ * @details Converts from seconds to realtime counter cycles.
+ * @note The macro assumes that @p freq >= @p 1.
+ *
+ * @param[in] freq clock frequency, in Hz, of the realtime counter
+ * @param[in] sec number of seconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define OSAL_S2RTC(freq, sec) ((freq) * (sec))
+
+/**
+ * @brief Milliseconds to realtime counter.
+ * @details Converts from milliseconds to realtime counter cycles.
+ * @note The result is rounded upward to the next millisecond boundary.
+ * @note The macro assumes that @p freq >= @p 1000.
+ *
+ * @param[in] freq clock frequency, in Hz, of the realtime counter
+ * @param[in] msec number of milliseconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define OSAL_MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec))
+
+/**
+ * @brief Microseconds to realtime counter.
+ * @details Converts from microseconds to realtime counter cycles.
+ * @note The result is rounded upward to the next microsecond boundary.
+ * @note The macro assumes that @p freq >= @p 1000000.
+ *
+ * @param[in] freq clock frequency, in Hz, of the realtime counter
+ * @param[in] usec number of microseconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define OSAL_US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec))
+/** @} */
+
+/**
+ * @name Sleep macros using absolute time
+ * @{
+ */
+/**
+ * @brief Delays the invoking thread for the specified number of seconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] secs time in seconds, must be different from zero
+ *
+ * @api
+ */
+#define osalThreadSleepSeconds(secs) osalThreadSleep(OSAL_S2I(secs))
+
+/**
+ * @brief Delays the invoking thread for the specified number of
+ * milliseconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] msecs time in milliseconds, must be different from zero
+ *
+ * @api
+ */
+#define osalThreadSleepMilliseconds(msecs) osalThreadSleep(OSAL_MS2I(msecs))
+
+/**
+ * @brief Delays the invoking thread for the specified number of
+ * microseconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] usecs time in microseconds, must be different from zero
+ *
+ * @api
+ */
+#define osalThreadSleepMicroseconds(usecs) osalThreadSleep(OSAL_US2I(usecs))
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+extern const char *osal_halt_msg;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void osalInit(void);
+ void osalSysHalt(const char *reason);
+ void osalSysPolledDelayX(rtcnt_t cycles);
+ void osalOsTimerHandlerI(void);
+ void osalOsRescheduleS(void);
+ systime_t osalOsGetSystemTimeX(void);
+ void osalThreadSleepS(sysinterval_t time);
+ void osalThreadSleep(sysinterval_t time);
+ msg_t osalThreadSuspendS(thread_reference_t *trp);
+ msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout);
+ void osalThreadResumeI(thread_reference_t *trp, msg_t msg);
+ void osalThreadResumeS(thread_reference_t *trp, msg_t msg);
+ msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout);
+ void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg);
+ void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg);
+ void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags);
+ void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags);
+ void osalEventSetCallback(event_source_t *esp,
+ eventcallback_t cb,
+ void *param);
+ void osalMutexLock(mutex_t *mp);
+ void osalMutexUnlock(mutex_t *mp);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Disables interrupts globally.
+ *
+ * @special
+ */
+static inline void osalSysDisable(void) {
+
+ __disable_irq();
+}
+
+/**
+ * @brief Enables interrupts globally.
+ *
+ * @special
+ */
+static inline void osalSysEnable(void) {
+
+ __enable_irq();
+}
+
+/**
+ * @brief Enters a critical zone from thread context.
+ * @note This function cannot be used for reentrant critical zones.
+ *
+ * @special
+ */
+static inline void osalSysLock(void) {
+
+#if CORTEX_MODEL == 0
+ __disable_irq();
+#else
+ __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY));
+#endif
+}
+
+/**
+ * @brief Leaves a critical zone from thread context.
+ * @note This function cannot be used for reentrant critical zones.
+ *
+ * @special
+ */
+static inline void osalSysUnlock(void) {
+
+#if CORTEX_MODEL == 0
+ __enable_irq();
+#else
+ __set_BASEPRI(0);
+#endif
+}
+
+/**
+ * @brief Enters a critical zone from ISR context.
+ * @note This function cannot be used for reentrant critical zones.
+ *
+ * @special
+ */
+static inline void osalSysLockFromISR(void) {
+
+#if CORTEX_MODEL == 0
+ __disable_irq();
+#else
+ __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY));
+#endif
+}
+
+/**
+ * @brief Leaves a critical zone from ISR context.
+ * @note This function cannot be used for reentrant critical zones.
+ *
+ * @special
+ */
+static inline void osalSysUnlockFromISR(void) {
+
+#if CORTEX_MODEL == 0
+ __enable_irq();
+#else
+ __set_BASEPRI(0);
+#endif
+}
+
+/**
+ * @brief Returns the execution status and enters a critical zone.
+ * @details This functions enters into a critical zone and can be called
+ * from any context. Because its flexibility it is less efficient
+ * than @p chSysLock() which is preferable when the calling context
+ * is known.
+ * @post The system is in a critical zone.
+ *
+ * @return The previous system status, the encoding of this
+ * status word is architecture-dependent and opaque.
+ *
+ * @xclass
+ */
+static inline syssts_t osalSysGetStatusAndLockX(void) {
+ syssts_t sts;
+
+#if CORTEX_MODEL == 0
+ sts = (syssts_t)__get_PRIMASK();
+ __disable_irq();
+#else
+ sts = (syssts_t)__get_BASEPRI();
+ __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY));
+#endif
+ return sts;
+}
+
+/**
+ * @brief Restores the specified execution status and leaves a critical zone.
+ * @note A call to @p chSchRescheduleS() is automatically performed
+ * if exiting the critical zone and if not in ISR context.
+ *
+ * @param[in] sts the system status to be restored.
+ *
+ * @xclass
+ */
+static inline void osalSysRestoreStatusX(syssts_t sts) {
+
+#if CORTEX_MODEL == 0
+ if ((sts & (syssts_t)1) == (syssts_t)0) {
+ __enable_irq();
+ }
+#else
+ __set_BASEPRI(sts);
+#endif
+}
+
+/**
+ * @brief Adds an interval to a system time returning a system time.
+ *
+ * @param[in] systime base system time
+ * @param[in] interval interval to be added
+ * @return The new system time.
+ *
+ * @xclass
+ */
+static inline systime_t osalTimeAddX(systime_t systime,
+ sysinterval_t interval) {
+
+ return systime + (systime_t)interval;
+}
+
+/**
+ * @brief Subtracts two system times returning an interval.
+ *
+ * @param[in] start first system time
+ * @param[in] end second system time
+ * @return The interval representing the time difference.
+ *
+ * @xclass
+ */
+static inline sysinterval_t osalTimeDiffX(systime_t start, systime_t end) {
+
+ return (sysinterval_t)((systime_t)(end - start));
+}
+
+/**
+ * @brief Checks if the specified time is within the specified time window.
+ * @note When start==end then the function returns always false because the
+ * time window has zero size.
+ * @note This function can be called from any context.
+ *
+ * @param[in] time the time to be verified
+ * @param[in] start the start of the time window (inclusive)
+ * @param[in] end the end of the time window (non inclusive)
+ * @retval true current time within the specified time window.
+ * @retval false current time not within the specified time window.
+ *
+ * @xclass
+ */
+static inline bool osalTimeIsInRangeX(systime_t time,
+ systime_t start,
+ systime_t end) {
+
+ return (bool)((systime_t)((systime_t)time - (systime_t)start) <
+ (systime_t)((systime_t)end - (systime_t)start));
+}
+
+/**
+ * @brief Initializes a threads queue object.
+ *
+ * @param[out] tqp pointer to the threads queue object
+ *
+ * @init
+ */
+static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) {
+
+ osalDbgCheck(tqp != NULL);
+}
+
+/**
+ * @brief Initializes an event source object.
+ *
+ * @param[out] esp pointer to the event source object
+ *
+ * @init
+ */
+static inline void osalEventObjectInit(event_source_t *esp) {
+
+ osalDbgCheck(esp != NULL);
+
+ esp->flags = (eventflags_t)0;
+ esp->cb = NULL;
+ esp->param = NULL;
+}
+
+/**
+ * @brief Initializes s @p mutex_t object.
+ *
+ * @param[out] mp pointer to the @p mutex_t object
+ *
+ * @init
+ */
+static inline void osalMutexObjectInit(mutex_t *mp) {
+
+ osalDbgCheck(mp != NULL);
+
+ *mp = 0;
+}
+
+#endif /* OSAL_H */
+
+/** @} */
diff --git a/ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.mk b/ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.mk new file mode 100644 index 0000000..e2cd7ad --- /dev/null +++ b/ChibiOS_20.3.2/os/hal/osal/os-less/ARMCMx/osal.mk @@ -0,0 +1,11 @@ +# OSAL files.
+OSALSRC += ${CHIBIOS}/os/hal/osal/os-less/ARMCMx/osal.c \
+ ${CHIBIOS}/os/hal/osal/lib/osal_vt.c
+
+# Required include directories
+OSALINC += ${CHIBIOS}/os/hal/osal/os-less/ARMCMx \
+ ${CHIBIOS}/os/hal/osal/lib
+
+# Shared variables
+ALLCSRC += $(OSALSRC)
+ALLINC += $(OSALINC)
diff --git a/ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.c b/ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.c new file mode 100644 index 0000000..616beaf --- /dev/null +++ b/ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.c @@ -0,0 +1,467 @@ +/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file osal.c
+ * @brief OSAL module code.
+ *
+ * @addtogroup OSAL
+ * @{
+ */
+
+#include "osal.h"
+#include "osal_vt.h"
+
+/*===========================================================================*/
+/* Module local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module exported variables. */
+/*===========================================================================*/
+
+/**
+ * @brief Pointer to a halt error message.
+ * @note The message is meant to be retrieved by the debugger after the
+ * system halt caused by an unexpected error.
+ */
+const char *osal_halt_msg;
+
+/*===========================================================================*/
+/* Module local types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local functions. */
+/*===========================================================================*/
+
+static void callback_timeout(void *p) {
+ osalSysLockFromISR();
+ osalThreadResumeI((thread_reference_t *)p, MSG_TIMEOUT);
+ osalSysUnlockFromISR();
+}
+
+/*===========================================================================*/
+/* Module exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief OSAL module initialization.
+ *
+ * @api
+ */
+void osalInit(void) {
+
+ vtInit();
+
+ OSAL_INIT_HOOK();
+}
+
+/**
+ * @brief System halt with error message.
+ *
+ * @param[in] reason the halt message pointer
+ *
+ * @api
+ */
+#if !defined(__DOXYGEN__)
+__attribute__((weak, noreturn))
+#endif
+void osalSysHalt(const char *reason) {
+
+ osalSysDisable();
+ osal_halt_msg = reason;
+ while (true) {
+ }
+}
+
+/**
+ * @brief Polled delay.
+ * @note The real delay is always few cycles in excess of the specified
+ * value.
+ *
+ * @param[in] cycles number of cycles
+ *
+ * @xclass
+ */
+void osalSysPolledDelayX(rtcnt_t cycles) {
+
+ (void)cycles;
+}
+
+/**
+ * @brief System timer handler.
+ * @details The handler is used for scheduling and Virtual Timers management.
+ *
+ * @iclass
+ */
+void osalOsTimerHandlerI(void) {
+
+ osalDbgCheckClassI();
+
+ vtDoTickI();
+}
+
+/**
+ * @brief Checks if a reschedule is required and performs it.
+ * @note I-Class functions invoked from thread context must not reschedule
+ * by themselves, an explicit reschedule using this function is
+ * required in this scenario.
+ * @note Not implemented in this simplified OSAL.
+ *
+ * @sclass
+ */
+void osalOsRescheduleS(void) {
+
+}
+
+/**
+ * @brief Current system time.
+ * @details Returns the number of system ticks since the @p osalInit()
+ * invocation.
+ * @note The counter can reach its maximum and then restart from zero.
+ * @note This function can be called from any context but its atomicity
+ * is not guaranteed on architectures whose word size is less than
+ * @p systime_t size.
+ *
+ * @return The system time in ticks.
+ *
+ * @xclass
+ */
+systime_t osalOsGetSystemTimeX(void) {
+
+ return vtlist.vt_systime;
+}
+
+/**
+ * @brief Suspends the invoking thread for the specified time.
+ *
+ * @param[in] time the delay in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE is allowed but interpreted as a
+ * normal time specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
+ *
+ * @sclass
+ */
+void osalThreadSleepS(systime_t time) {
+ virtual_timer_t vt;
+ thread_reference_t tr;
+
+ tr = NULL;
+ vtSetI(&vt, time, callback_timeout, (void *)&tr);
+ osalThreadSuspendS(&tr);
+}
+
+/**
+ * @brief Suspends the invoking thread for the specified time.
+ *
+ * @param[in] time the delay in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE is allowed but interpreted as a
+ * normal time specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
+ *
+ * @api
+ */
+void osalThreadSleep(systime_t time) {
+
+ osalSysLock();
+ osalThreadSleepS(time);
+ osalSysUnlock();
+}
+
+/**
+ * @brief Sends the current thread sleeping and sets a reference variable.
+ * @note This function must reschedule, it can only be called from thread
+ * context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @return The wake up message.
+ *
+ * @sclass
+ */
+msg_t osalThreadSuspendS(thread_reference_t *trp) {
+ thread_t self = {MSG_WAIT};
+
+ osalDbgCheck(trp != NULL);
+
+ *trp = &self;
+ while (self.message == MSG_WAIT) {
+ osalSysUnlock();
+ /* A state-changing interrupt could occur here and cause the loop to
+ terminate, an hook macro is executed while waiting.*/
+ OSAL_IDLE_HOOK();
+ osalSysLock();
+ }
+
+ return self.message;
+}
+
+/**
+ * @brief Sends the current thread sleeping and sets a reference variable.
+ * @note This function must reschedule, it can only be called from thread
+ * context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @param[in] timeout the timeout in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE the thread enters an infinite sleep
+ * state.
+ * - @a TIME_IMMEDIATE the thread is not enqueued and
+ * the function returns @p MSG_TIMEOUT as if a timeout
+ * occurred.
+ * .
+ * @return The wake up message.
+ * @retval MSG_TIMEOUT if the operation timed out.
+ *
+ * @sclass
+ */
+msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, systime_t timeout) {
+ msg_t msg;
+ virtual_timer_t vt;
+
+ osalDbgCheck(trp != NULL);
+
+ if (TIME_INFINITE == timeout)
+ return osalThreadSuspendS(trp);
+
+ vtSetI(&vt, timeout, callback_timeout, (void *)trp);
+ msg = osalThreadSuspendS(trp);
+ if (vtIsArmedI(&vt))
+ vtResetI(&vt);
+
+ return msg;
+}
+
+/**
+ * @brief Wakes up a thread waiting on a thread reference object.
+ * @note This function must not reschedule because it can be called from
+ * ISR context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+void osalThreadResumeI(thread_reference_t *trp, msg_t msg) {
+
+ osalDbgCheck(trp != NULL);
+
+ if (*trp != NULL) {
+ (*trp)->message = msg;
+ *trp = NULL;
+ }
+}
+
+/**
+ * @brief Wakes up a thread waiting on a thread reference object.
+ * @note This function must reschedule, it can only be called from thread
+ * context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+void osalThreadResumeS(thread_reference_t *trp, msg_t msg) {
+
+ osalDbgCheck(trp != NULL);
+
+ if (*trp != NULL) {
+ (*trp)->message = msg;
+ *trp = NULL;
+ }
+}
+
+/**
+ * @brief Enqueues the caller thread.
+ * @details The caller thread is enqueued and put to sleep until it is
+ * dequeued or the specified timeouts expires.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] timeout the timeout in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE the thread enters an infinite sleep
+ * state.
+ * - @a TIME_IMMEDIATE the thread is not enqueued and
+ * the function returns @p MSG_TIMEOUT as if a timeout
+ * occurred.
+ * .
+ * @return The message from @p osalQueueWakeupOneI() or
+ * @p osalQueueWakeupAllI() functions.
+ * @retval MSG_TIMEOUT if the thread has not been dequeued within the
+ * specified timeout or if the function has been
+ * invoked with @p TIME_IMMEDIATE as timeout
+ * specification.
+ *
+ * @sclass
+ */
+msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, systime_t timeout) {
+ msg_t msg;
+ virtual_timer_t vt;
+
+ osalDbgCheck(tqp != NULL);
+
+ if (TIME_IMMEDIATE == timeout)
+ return MSG_TIMEOUT;
+
+ tqp->tr = NULL;
+
+ if (TIME_INFINITE == timeout)
+ return osalThreadSuspendS(&tqp->tr);
+
+ vtSetI(&vt, timeout, callback_timeout, (void *)&tqp->tr);
+ msg = osalThreadSuspendS(&tqp->tr);
+ if (vtIsArmedI(&vt))
+ vtResetI(&vt);
+
+ return msg;
+}
+
+/**
+ * @brief Dequeues and wakes up one thread from the queue, if any.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) {
+
+ osalDbgCheck(tqp != NULL);
+
+ osalThreadResumeI(&tqp->tr, msg);
+}
+
+/**
+ * @brief Dequeues and wakes up all threads from the queue.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) {
+
+ osalDbgCheck(tqp != NULL);
+
+ osalThreadResumeI(&tqp->tr, msg);
+}
+
+/**
+ * @brief Add flags to an event source object.
+ *
+ * @param[in] esp pointer to the event flags object
+ * @param[in] flags flags to be ORed to the flags mask
+ *
+ * @iclass
+ */
+void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags) {
+
+ osalDbgCheck(esp != NULL);
+
+ esp->flags |= flags;
+ if (esp->cb != NULL) {
+ esp->cb(esp);
+ }
+}
+
+/**
+ * @brief Add flags to an event source object.
+ *
+ * @param[in] esp pointer to the event flags object
+ * @param[in] flags flags to be ORed to the flags mask
+ *
+ * @iclass
+ */
+void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags) {
+
+ osalDbgCheck(esp != NULL);
+
+ osalSysLock();
+ osalEventBroadcastFlagsI(esp, flags);
+ osalSysUnlock();
+}
+
+/**
+ * @brief Event callback setup.
+ * @note The callback is invoked from ISR context and can
+ * only invoke I-Class functions. The callback is meant
+ * to wakeup the task that will handle the event by
+ * calling @p osalEventGetAndClearFlagsI().
+ * @note This function is not part of the OSAL API and is provided
+ * exclusively as an example and for convenience.
+ *
+ * @param[in] esp pointer to the event flags object
+ * @param[in] cb pointer to the callback function
+ * @param[in] param parameter to be passed to the callback function
+ *
+ * @api
+ */
+void osalEventSetCallback(event_source_t *esp,
+ eventcallback_t cb,
+ void *param) {
+
+ osalDbgCheck(esp != NULL);
+
+ esp->cb = cb;
+ esp->param = param;
+}
+
+/**
+ * @brief Locks the specified mutex.
+ * @post The mutex is locked and inserted in the per-thread stack of owned
+ * mutexes.
+ *
+ * @param[in,out] mp pointer to the @p mutex_t object
+ *
+ * @api
+ */
+void osalMutexLock(mutex_t *mp) {
+
+ osalDbgCheck(mp != NULL);
+
+ *mp = 1;
+}
+
+/**
+ * @brief Unlocks the specified mutex.
+ * @note The HAL guarantees to release mutex in reverse lock order. The
+ * mutex being unlocked is guaranteed to be the last locked mutex
+ * by the invoking thread.
+ * The implementation can rely on this behavior and eventually
+ * ignore the @p mp parameter which is supplied in order to support
+ * those OSes not supporting a stack of the owned mutexes.
+ *
+ * @param[in,out] mp pointer to the @p mutex_t object
+ *
+ * @api
+ */
+void osalMutexUnlock(mutex_t *mp) {
+
+ osalDbgCheck(mp != NULL);
+
+ *mp = 0;
+}
+
+/** @} */
diff --git a/ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.h b/ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.h new file mode 100644 index 0000000..79b4046 --- /dev/null +++ b/ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.h @@ -0,0 +1,677 @@ +/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file osal.h
+ * @brief OSAL module header.
+ *
+ * @addtogroup OSAL
+ * @{
+ */
+
+#ifndef OSAL_H
+#define OSAL_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+#include "osalconf.h"
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/**
+ * @name Common constants
+ * @{
+ */
+#if !defined(FALSE) || defined(__DOXYGEN__)
+#define FALSE 0
+#endif
+
+#if !defined(TRUE) || defined(__DOXYGEN__)
+#define TRUE 1
+#endif
+
+#define OSAL_SUCCESS false
+#define OSAL_FAILED true
+/** @} */
+
+/**
+ * @name Messages
+ * @{
+ */
+#define MSG_OK (msg_t)0
+#define MSG_RESET (msg_t)-1
+#define MSG_TIMEOUT (msg_t)-2
+#define MSG_WAIT (msg_t)-10
+/** @} */
+
+/**
+ * @name Special time constants
+ * @{
+ */
+#define TIME_IMMEDIATE ((systime_t)0)
+#define TIME_INFINITE ((systime_t)-1)
+/** @} */
+
+/**
+ * @name Systick modes.
+ * @{
+ */
+#define OSAL_ST_MODE_NONE 0
+#define OSAL_ST_MODE_PERIODIC 1
+#define OSAL_ST_MODE_FREERUNNING 2
+/** @} */
+
+/**
+ * @name Systick parameters.
+ * @{
+ */
+/**
+ * @brief Size in bits of the @p systick_t type.
+ */
+#define OSAL_ST_RESOLUTION 32
+
+/**
+ * @brief Systick mode required by the underlying OS.
+ */
+#define OSAL_ST_MODE OSAL_ST_MODE_PERIODIC
+/** @} */
+
+/**
+ * @brief ROM constant modifier.
+ * @note It is set to use the "const" keyword in this port.
+ */
+#define ROMCONST const
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Frequency in Hertz of the system tick.
+ */
+#if !defined(OSAL_ST_FREQUENCY) || defined(__DOXYGEN__)
+#define OSAL_ST_FREQUENCY 1000
+#endif
+
+/**
+ * @brief Enables OSAL assertions.
+ */
+#if !defined(OSAL_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)
+#define OSAL_DBG_ENABLE_ASSERTS FALSE
+#endif
+
+/**
+ * @brief Enables OSAL functions parameters checks.
+ */
+#if !defined(OSAL_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)
+#define OSAL_DBG_ENABLE_CHECKS FALSE
+#endif
+
+/**
+ * @brief OSAL initialization hook.
+ */
+#if !defined(OSAL_INIT_HOOK) || defined(__DOXYGEN__)
+#define OSAL_INIT_HOOK()
+#endif
+
+/**
+ * @brief Idle loop hook macro.
+ */
+#if !defined(OSAL_IDLE_HOOK) || defined(__DOXYGEN__)
+#define OSAL_IDLE_HOOK()
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of a system status word.
+ */
+typedef uint8_t syssts_t;
+
+/**
+ * @brief Type of a message.
+ */
+typedef int16_t msg_t;
+
+/**
+ * @brief Type of system time counter.
+ */
+typedef uint32_t systime_t;
+
+/**
+ * @brief Type of realtime counter.
+ */
+typedef uint32_t rtcnt_t;
+
+/**
+ * @brief Type of a thread.
+ * @note The content of this structure is not part of the API and should
+ * not be relied upon. Implementers may define this structure in
+ * an entirely different way.
+ */
+typedef struct {
+ volatile msg_t message;
+} thread_t;
+
+/**
+ * @brief Type of a thread reference.
+ */
+typedef thread_t * thread_reference_t;
+
+/**
+ * @brief Type of an event flags object.
+ * @note The content of this structure is not part of the API and should
+ * not be relied upon. Implementers may define this structure in
+ * an entirely different way.
+ * @note Retrieval and clearing of the flags are not defined in this
+ * API and are implementation-dependent.
+ */
+typedef struct event_source event_source_t;
+
+/**
+ * @brief Type of an event source callback.
+ * @note This type is not part of the OSAL API and is provided
+ * exclusively as an example and for convenience.
+ */
+typedef void (*eventcallback_t)(event_source_t *esp);
+
+/**
+ * @brief Type of an event flags mask.
+ */
+typedef uint8_t eventflags_t;
+
+/**
+ * @brief Events source object.
+ * @note The content of this structure is not part of the API and should
+ * not be relied upon. Implementers may define this structure in
+ * an entirely different way.
+ * @note Retrieval and clearing of the flags are not defined in this
+ * API and are implementation-dependent.
+ */
+struct event_source {
+ volatile eventflags_t flags; /**< @brief Stored event flags. */
+ eventcallback_t cb; /**< @brief Event source callback. */
+ void *param; /**< @brief User defined field. */
+};
+
+/**
+ * @brief Type of a mutex.
+ * @note If the OS does not support mutexes or there is no OS then them
+ * mechanism can be simulated.
+ */
+typedef uint8_t mutex_t;
+
+/**
+ * @brief Type of a thread queue.
+ * @details A thread queue is a queue of sleeping threads, queued threads
+ * can be dequeued one at time or all together.
+ * @note If the OSAL is implemented on a bare metal machine without RTOS
+ * then the queue can be implemented as a single thread reference.
+ */
+typedef struct {
+ thread_reference_t tr;
+} threads_queue_t;
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @name Debug related macros
+ * @{
+ */
+/**
+ * @brief Condition assertion.
+ * @details If the condition check fails then the OSAL panics with a
+ * message and halts.
+ * @note The condition is tested only if the @p OSAL_ENABLE_ASSERTIONS
+ * switch is enabled.
+ * @note The remark string is not currently used except for putting a
+ * comment in the code about the assertion.
+ *
+ * @param[in] c the condition to be verified to be true
+ * @param[in] remark a remark string
+ *
+ * @api
+ */
+#define osalDbgAssert(c, remark) do { \
+ /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
+ if (OSAL_DBG_ENABLE_ASSERTS != FALSE) { \
+ if (!(c)) { \
+ /*lint -restore*/ \
+ osalSysHalt(__func__); \
+ } \
+ } \
+} while (false)
+
+/**
+ * @brief Function parameters check.
+ * @details If the condition check fails then the OSAL panics and halts.
+ * @note The condition is tested only if the @p OSAL_ENABLE_CHECKS switch
+ * is enabled.
+ *
+ * @param[in] c the condition to be verified to be true
+ *
+ * @api
+ */
+#define osalDbgCheck(c) do { \
+ /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/ \
+ if (OSAL_DBG_ENABLE_CHECKS != FALSE) { \
+ if (!(c)) { \
+ /*lint -restore*/ \
+ osalSysHalt(__func__); \
+ } \
+ } \
+} while (false)
+
+/**
+ * @brief I-Class state check.
+ * @note Implementation is optional.
+ */
+#define osalDbgCheckClassI()
+
+/**
+ * @brief S-Class state check.
+ * @note Implementation is optional.
+ */
+#define osalDbgCheckClassS()
+/** @} */
+
+/**
+ * @name IRQ service routines wrappers
+ * @{
+ */
+/**
+ * @brief IRQ prologue code.
+ * @details This macro must be inserted at the start of all IRQ handlers.
+ */
+#define OSAL_IRQ_PROLOGUE()
+
+/**
+ * @brief IRQ epilogue code.
+ * @details This macro must be inserted at the end of all IRQ handlers.
+ */
+#define OSAL_IRQ_EPILOGUE()
+
+/**
+ * @brief IRQ handler function declaration.
+ * @details This macro hides the details of an ISR function declaration.
+ *
+ * @param[in] id a vector name as defined in @p vectors.s
+ */
+#define OSAL_IRQ_HANDLER(id) ISR(id)
+/** @} */
+
+/**
+ * @name Time conversion utilities
+ * @{
+ */
+/**
+ * @brief Seconds to system ticks.
+ * @details Converts from seconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] sec number of seconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define OSAL_S2ST(sec) \
+ ((systime_t)((uint32_t)(sec) * (uint32_t)OSAL_ST_FREQUENCY))
+
+/**
+ * @brief Milliseconds to system ticks.
+ * @details Converts from milliseconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] msec number of milliseconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define OSAL_MS2ST(msec) \
+ ((systime_t)((((uint32_t)(msec)) * \
+ ((uint32_t)OSAL_ST_FREQUENCY) + 999UL) / 1000UL))
+
+/**
+ * @brief Microseconds to system ticks.
+ * @details Converts from microseconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] usec number of microseconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define OSAL_US2ST(usec) \
+ ((systime_t)((((uint32_t)(usec)) * \
+ ((uint32_t)OSAL_ST_FREQUENCY) + 999999UL) / 1000000UL))
+/** @} */
+
+/**
+ * @name Time conversion utilities for the realtime counter
+ * @{
+ */
+/**
+ * @brief Seconds to realtime counter.
+ * @details Converts from seconds to realtime counter cycles.
+ * @note The macro assumes that @p freq >= @p 1.
+ *
+ * @param[in] freq clock frequency, in Hz, of the realtime counter
+ * @param[in] sec number of seconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define OSAL_S2RTC(freq, sec) ((freq) * (sec))
+
+/**
+ * @brief Milliseconds to realtime counter.
+ * @details Converts from milliseconds to realtime counter cycles.
+ * @note The result is rounded upward to the next millisecond boundary.
+ * @note The macro assumes that @p freq >= @p 1000.
+ *
+ * @param[in] freq clock frequency, in Hz, of the realtime counter
+ * @param[in] msec number of milliseconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define OSAL_MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec))
+
+/**
+ * @brief Microseconds to realtime counter.
+ * @details Converts from microseconds to realtime counter cycles.
+ * @note The result is rounded upward to the next microsecond boundary.
+ * @note The macro assumes that @p freq >= @p 1000000.
+ *
+ * @param[in] freq clock frequency, in Hz, of the realtime counter
+ * @param[in] usec number of microseconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define OSAL_US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec))
+/** @} */
+
+/**
+ * @name Sleep macros using absolute time
+ * @{
+ */
+/**
+ * @brief Delays the invoking thread for the specified number of seconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] sec time in seconds, must be different from zero
+ *
+ * @api
+ */
+#define osalThreadSleepSeconds(sec) osalThreadSleep(OSAL_S2ST(sec))
+
+/**
+ * @brief Delays the invoking thread for the specified number of
+ * milliseconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] msec time in milliseconds, must be different from zero
+ *
+ * @api
+ */
+#define osalThreadSleepMilliseconds(msec) osalThreadSleep(OSAL_MS2ST(msec))
+
+/**
+ * @brief Delays the invoking thread for the specified number of
+ * microseconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] usec time in microseconds, must be different from zero
+ *
+ * @api
+ */
+#define osalThreadSleepMicroseconds(usec) osalThreadSleep(OSAL_US2ST(usec))
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+extern const char *osal_halt_msg;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void osalInit(void);
+ void osalSysHalt(const char *reason);
+ void osalSysPolledDelayX(rtcnt_t cycles);
+ void osalOsTimerHandlerI(void);
+ void osalOsRescheduleS(void);
+ systime_t osalOsGetSystemTimeX(void);
+ void osalThreadSleepS(systime_t time);
+ void osalThreadSleep(systime_t time);
+ msg_t osalThreadSuspendS(thread_reference_t *trp);
+ msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, systime_t timeout);
+ void osalThreadResumeI(thread_reference_t *trp, msg_t msg);
+ void osalThreadResumeS(thread_reference_t *trp, msg_t msg);
+ msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, systime_t timeout);
+ void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg);
+ void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg);
+ void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags);
+ void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags);
+ void osalEventSetCallback(event_source_t *esp,
+ eventcallback_t cb,
+ void *param);
+ void osalMutexLock(mutex_t *mp);
+ void osalMutexUnlock(mutex_t *mp);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Disables interrupts globally.
+ *
+ * @special
+ */
+static inline void osalSysDisable(void) {
+
+ asm volatile ("cli" : : : "memory");
+}
+
+/**
+ * @brief Enables interrupts globally.
+ *
+ * @special
+ */
+static inline void osalSysEnable(void) {
+
+ asm volatile ("sei" : : : "memory");
+ asm volatile ("nop");
+}
+
+/**
+ * @brief Enters a critical zone from thread context.
+ * @note This function cannot be used for reentrant critical zones.
+ *
+ * @special
+ */
+static inline void osalSysLock(void) {
+
+ asm volatile ("cli" : : : "memory");
+}
+
+/**
+ * @brief Leaves a critical zone from thread context.
+ * @note This function cannot be used for reentrant critical zones.
+ *
+ * @special
+ */
+static inline void osalSysUnlock(void) {
+
+ asm volatile ("sei" : : : "memory");
+ asm volatile ("nop");
+}
+
+/**
+ * @brief Enters a critical zone from ISR context.
+ * @note This function cannot be used for reentrant critical zones.
+ * @note This function is empty in this port.
+ *
+ * @special
+ */
+static inline void osalSysLockFromISR(void) {
+
+}
+
+/**
+ * @brief Leaves a critical zone from ISR context.
+ * @note This function cannot be used for reentrant critical zones.
+ * @note This function is empty in this port.
+ *
+ * @special
+ */
+static inline void osalSysUnlockFromISR(void) {
+
+}
+
+/**
+ * @brief Returns the execution status and enters a critical zone.
+ * @details This functions enters into a critical zone and can be called
+ * from any context. Because its flexibility it is less efficient
+ * than @p chSysLock() which is preferable when the calling context
+ * is known.
+ * @post The system is in a critical zone.
+ *
+ * @return The previous system status, the encoding of this
+ * status word is architecture-dependent and opaque.
+ *
+ * @xclass
+ */
+static inline syssts_t osalSysGetStatusAndLockX(void) {
+ syssts_t sts;
+
+ sts = SREG;
+ asm volatile ("cli" : : : "memory");
+
+ return sts;
+}
+
+/**
+ * @brief Restores the specified execution status and leaves a critical zone.
+ * @note A call to @p chSchRescheduleS() is automatically performed
+ * if exiting the critical zone and if not in ISR context.
+ *
+ * @param[in] sts the system status to be restored.
+ *
+ * @xclass
+ */
+static inline void osalSysRestoreStatusX(syssts_t sts) {
+
+ if ((sts & 0x80) != 0) {
+ asm volatile ("sei" : : : "memory");
+ asm volatile ("nop");
+ }
+}
+
+/**
+ * @brief Checks if the specified time is within the specified time window.
+ * @note When start==end then the function returns always false because the
+ * time window has zero size.
+ * @note This function can be called from any context.
+ *
+ * @param[in] time the time to be verified
+ * @param[in] start the start of the time window (inclusive)
+ * @param[in] end the end of the time window (non inclusive)
+ * @retval true current time within the specified time window.
+ * @retval false current time not within the specified time window.
+ *
+ * @xclass
+ */
+static inline bool osalOsIsTimeWithinX(systime_t time,
+ systime_t start,
+ systime_t end) {
+
+ return (bool)((time - start) < (end - start));
+}
+
+/**
+ * @brief Initializes a threads queue object.
+ *
+ * @param[out] tqp pointer to the threads queue object
+ *
+ * @init
+ */
+static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) {
+
+ osalDbgCheck(tqp != NULL);
+
+ (void)tqp;
+}
+
+/**
+ * @brief Initializes an event flags object.
+ *
+ * @param[out] esp pointer to the event flags object
+ *
+ * @init
+ */
+static inline void osalEventObjectInit(event_source_t *esp) {
+
+ osalDbgCheck(esp != NULL);
+
+ esp->flags = (eventflags_t)0;
+ esp->cb = NULL;
+ esp->param = NULL;
+}
+
+/**
+ * @brief Initializes s @p mutex_t object.
+ *
+ * @param[out] mp pointer to the @p mutex_t object
+ *
+ * @init
+ */
+static inline void osalMutexObjectInit(mutex_t *mp) {
+
+ osalDbgCheck(mp != NULL);
+
+ *mp = 0;
+}
+
+#endif /* OSAL_H */
+
+/** @} */
diff --git a/ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.mk b/ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.mk new file mode 100644 index 0000000..4f929d7 --- /dev/null +++ b/ChibiOS_20.3.2/os/hal/osal/os-less/AVR/osal.mk @@ -0,0 +1,9 @@ +# OSAL files.
+OSALSRC += ${CHIBIOS}/os/hal/osal/os-less/AVR/osal.c
+
+# Required include directories
+OSALINC += ${CHIBIOS}/os/hal/osal/os-less/AVR
+
+# Shared variables
+ALLCSRC += $(OSALSRC)
+ALLINC += $(OSALINC)
diff --git a/ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.c b/ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.c new file mode 100644 index 0000000..7f4103b --- /dev/null +++ b/ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.c @@ -0,0 +1,51 @@ +/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file osal.c
+ * @brief OSAL module code.
+ *
+ * @addtogroup OSAL
+ * @{
+ */
+
+#include "osal.h"
+
+/*===========================================================================*/
+/* Module local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module exported functions. */
+/*===========================================================================*/
+
+/** @} */
diff --git a/ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.h b/ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.h new file mode 100644 index 0000000..73e8e3f --- /dev/null +++ b/ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.h @@ -0,0 +1,1028 @@ +/*
+ ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file osal.h
+ * @brief OSAL module header.
+ *
+ * @addtogroup OSAL
+ * @{
+ */
+
+#ifndef OSAL_H
+#define OSAL_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "ch.h"
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/**
+ * @name Common constants
+ * @{
+ */
+#if !defined(FALSE) || defined(__DOXYGEN__)
+#define FALSE 0
+#endif
+
+#if !defined(TRUE) || defined(__DOXYGEN__)
+#define TRUE 1
+#endif
+
+#define OSAL_SUCCESS false
+#define OSAL_FAILED true
+/** @} */
+
+#if 0
+/**
+ * @name Messages
+ * @{
+ */
+#define MSG_OK (msg_t)0
+#define MSG_TIMEOUT (msg_t)-1
+#define MSG_RESET (msg_t)-2
+/** @} */
+#endif
+
+#if 0
+/**
+ * @name Special time constants
+ * @{
+ */
+#define TIME_IMMEDIATE ((sysinterval_t)0)
+#define TIME_INFINITE ((sysinterval_t)-1)
+/** @} */
+#endif
+
+/**
+ * @name Systick modes.
+ * @{
+ */
+#define OSAL_ST_MODE_NONE 0
+#define OSAL_ST_MODE_PERIODIC 1
+#define OSAL_ST_MODE_FREERUNNING 2
+/** @} */
+
+/**
+ * @name Systick parameters.
+ * @{
+ */
+/**
+ * @brief Size in bits of the @p systick_t type.
+ */
+#define OSAL_ST_RESOLUTION CH_CFG_ST_RESOLUTION
+
+/**
+ * @brief Required systick frequency or resolution.
+ */
+#define OSAL_ST_FREQUENCY CH_CFG_ST_FREQUENCY
+
+/**
+ * @brief Systick mode required by the underlying OS.
+ */
+#if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
+#define OSAL_ST_MODE OSAL_ST_MODE_PERIODIC
+#else
+#define OSAL_ST_MODE OSAL_ST_MODE_FREERUNNING
+#endif
+/** @} */
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !(OSAL_ST_MODE == OSAL_ST_MODE_NONE) && \
+ !(OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) && \
+ !(OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING)
+#error "invalid OSAL_ST_MODE setting in osal.h"
+#endif
+
+#if (OSAL_ST_RESOLUTION != 16) && (OSAL_ST_RESOLUTION != 32)
+#error "invalid OSAL_ST_RESOLUTION, must be 16 or 32"
+#endif
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+#if 0
+/**
+ * @brief Type of a system status word.
+ */
+typedef uint32_t syssts_t;
+#endif
+
+#if 0
+/**
+ * @brief Type of a message.
+ */
+typedef int32_t msg_t;
+#endif
+
+#if 0
+/**
+ * @brief Type of system time counter.
+ */
+typedef uint32_t systime_t;
+#endif
+
+#if 0
+/**
+ * @brief Type of system time interval.
+ */
+typedef uint32_t sysinterval_t;
+#endif
+
+#if 0
+/**
+ * @brief Type of realtime counter.
+ */
+typedef uint32_t rtcnt_t;
+#endif
+
+#if 0
+/**
+ * @brief Type of a thread reference.
+ */
+typedef thread_t * thread_reference_t;
+#endif
+
+#if 0
+/**
+ * @brief Type of an event flags mask.
+ */
+typedef uint32_t eventflags_t;
+#endif
+
+#if (CH_CFG_USE_EVENTS == FALSE) || defined(__DOXYGEN__)
+/**
+ * @brief Type of an event flags object.
+ * @note The content of this structure is not part of the API and should
+ * not be relied upon. Implementers may define this structure in
+ * an entirely different way.
+ * @note Retrieval and clearing of the flags are not defined in this
+ * API and are implementation-dependent.
+ */
+typedef struct event_source event_source_t;
+
+/**
+ * @brief Type of an event source callback.
+ * @note This type is not part of the OSAL API and is provided
+ * exclusively as an example and for convenience.
+ */
+typedef void (*eventcallback_t)(event_source_t *esp);
+
+/**
+ * @brief Events source object.
+ * @note The content of this structure is not part of the API and should
+ * not be relied upon. Implementers may define this structure in
+ * an entirely different way.
+ * @note Retrieval and clearing of the flags are not defined in this
+ * API and are implementation-dependent.
+ */
+struct event_source {
+ volatile eventflags_t flags; /**< @brief Stored event flags. */
+ eventcallback_t cb; /**< @brief Event source callback. */
+ void *param; /**< @brief User defined field. */
+};
+#endif /* CH_CFG_USE_EVENTS == FALSE */
+
+/**
+ * @brief Type of a mutex.
+ * @note If the OS does not support mutexes or there is no OS then the
+ * mechanism can be simulated.
+ */
+#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
+#elif CH_CFG_USE_SEMAPHORES
+typedef semaphore_t mutex_t;
+#else
+typedef uint32_t mutex_t;
+#endif
+
+#if 0
+/**
+ * @brief Type of a thread queue.
+ * @details A thread queue is a queue of sleeping threads, queued threads
+ * can be dequeued one at time or all together.
+ * @note In this implementation it is implemented as a single reference
+ * because there are no real threads.
+ */
+typedef struct {
+ thread_reference_t tr;
+} threads_queue_t;
+#endif
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @name Debug related macros
+ * @{
+ */
+/**
+ * @brief Condition assertion.
+ * @details If the condition check fails then the OSAL panics with a
+ * message and halts.
+ * @note The condition is tested only if the @p OSAL_ENABLE_ASSERTIONS
+ * switch is enabled.
+ * @note The remark string is not currently used except for putting a
+ * comment in the code about the assertion.
+ *
+ * @param[in] c the condition to be verified to be true
+ * @param[in] remark a remark string
+ *
+ * @api
+ */
+#define osalDbgAssert(c, remark) chDbgAssert(c, remark)
+
+/**
+ * @brief Function parameters check.
+ * @details If the condition check fails then the OSAL panics and halts.
+ * @note The condition is tested only if the @p OSAL_ENABLE_CHECKS switch
+ * is enabled.
+ *
+ * @param[in] c the condition to be verified to be true
+ *
+ * @api
+ */
+#define osalDbgCheck(c) chDbgCheck(c)
+
+/**
+ * @brief I-Class state check.
+ * @note Not implemented in this simplified OSAL.
+ */
+#define osalDbgCheckClassI() chDbgCheckClassI()
+
+/**
+ * @brief S-Class state check.
+ * @note Not implemented in this simplified OSAL.
+ */
+#define osalDbgCheckClassS() chDbgCheckClassS()
+/** @} */
+
+/**
+ * @name IRQ service routines wrappers
+ * @{
+ */
+/**
+ * @brief Priority level verification macro.
+ */
+#define OSAL_IRQ_IS_VALID_PRIORITY(n) CH_IRQ_IS_VALID_KERNEL_PRIORITY(n)
+
+/**
+ * @brief IRQ prologue code.
+ * @details This macro must be inserted at the start of all IRQ handlers.
+ */
+#define OSAL_IRQ_PROLOGUE() CH_IRQ_PROLOGUE()
+
+/**
+ * @brief IRQ epilogue code.
+ * @details This macro must be inserted at the end of all IRQ handlers.
+ */
+#define OSAL_IRQ_EPILOGUE() CH_IRQ_EPILOGUE()
+
+/**
+ * @brief IRQ handler function declaration.
+ * @details This macro hides the details of an ISR function declaration.
+ *
+ * @param[in] id a vector name as defined in @p vectors.s
+ */
+#define OSAL_IRQ_HANDLER(id) CH_IRQ_HANDLER(id)
+/** @} */
+
+/**
+ * @name Time conversion utilities
+ * @{
+ */
+/**
+ * @brief Seconds to system ticks.
+ * @details Converts from seconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] secs number of seconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define OSAL_S2I(secs) TIME_S2I(secs)
+
+/**
+ * @brief Milliseconds to system ticks.
+ * @details Converts from milliseconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] msecs number of milliseconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define OSAL_MS2I(msecs) TIME_MS2I(msecs)
+
+/**
+ * @brief Microseconds to system ticks.
+ * @details Converts from microseconds to system ticks number.
+ * @note The result is rounded upward to the next tick boundary.
+ *
+ * @param[in] usecs number of microseconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define OSAL_US2I(usecs) TIME_US2I(usecs)
+/** @} */
+
+/**
+ * @name Time conversion utilities for the realtime counter
+ * @{
+ */
+/**
+ * @brief Seconds to realtime counter.
+ * @details Converts from seconds to realtime counter cycles.
+ * @note The macro assumes that @p freq >= @p 1.
+ *
+ * @param[in] freq clock frequency, in Hz, of the realtime counter
+ * @param[in] sec number of seconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define OSAL_S2RTC(freq, sec) S2RTC(freq, sec)
+
+/**
+ * @brief Milliseconds to realtime counter.
+ * @details Converts from milliseconds to realtime counter cycles.
+ * @note The result is rounded upward to the next millisecond boundary.
+ * @note The macro assumes that @p freq >= @p 1000.
+ *
+ * @param[in] freq clock frequency, in Hz, of the realtime counter
+ * @param[in] msec number of milliseconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define OSAL_MS2RTC(freq, msec) MS2RTC(freq, msec)
+
+/**
+ * @brief Microseconds to realtime counter.
+ * @details Converts from microseconds to realtime counter cycles.
+ * @note The result is rounded upward to the next microsecond boundary.
+ * @note The macro assumes that @p freq >= @p 1000000.
+ *
+ * @param[in] freq clock frequency, in Hz, of the realtime counter
+ * @param[in] usec number of microseconds
+ * @return The number of cycles.
+ *
+ * @api
+ */
+#define OSAL_US2RTC(freq, usec) US2RTC(freq, usec)
+/** @} */
+
+/**
+ * @name Sleep macros using absolute time
+ * @{
+ */
+/**
+ * @brief Delays the invoking thread for the specified number of seconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] secs time in seconds, must be different from zero
+ *
+ * @api
+ */
+#define osalThreadSleepSeconds(secs) osalThreadSleep(OSAL_S2I(secs))
+
+/**
+ * @brief Delays the invoking thread for the specified number of
+ * milliseconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] msecs time in milliseconds, must be different from zero
+ *
+ * @api
+ */
+#define osalThreadSleepMilliseconds(msecs) osalThreadSleep(OSAL_MS2I(msecs))
+
+/**
+ * @brief Delays the invoking thread for the specified number of
+ * microseconds.
+ * @note The specified time is rounded up to a value allowed by the real
+ * system tick clock.
+ * @note The maximum specifiable value is implementation dependent.
+ *
+ * @param[in] usecs time in microseconds, must be different from zero
+ *
+ * @api
+ */
+#define osalThreadSleepMicroseconds(usecs) osalThreadSleep(OSAL_US2I(usecs))
+/** @} */
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief OSAL module initialization.
+ *
+ * @api
+ */
+static inline void osalInit(void) {
+
+}
+
+/**
+ * @brief System halt with error message.
+ *
+ * @param[in] reason the halt message pointer
+ *
+ * @api
+ */
+static inline void osalSysHalt(const char *reason) {
+
+ chSysHalt(reason);
+}
+
+/**
+ * @brief Disables interrupts globally.
+ *
+ * @special
+ */
+static inline void osalSysDisable(void) {
+
+ chSysDisable();
+}
+
+/**
+ * @brief Enables interrupts globally.
+ *
+ * @special
+ */
+static inline void osalSysEnable(void) {
+
+ chSysEnable();
+}
+
+/**
+ * @brief Enters a critical zone from thread context.
+ * @note This function cannot be used for reentrant critical zones.
+ *
+ * @special
+ */
+static inline void osalSysLock(void) {
+
+ chSysLock();
+}
+
+/**
+ * @brief Leaves a critical zone from thread context.
+ * @note This function cannot be used for reentrant critical zones.
+ *
+ * @special
+ */
+static inline void osalSysUnlock(void) {
+
+ chSysUnlock();
+}
+
+/**
+ * @brief Enters a critical zone from ISR context.
+ * @note This function cannot be used for reentrant critical zones.
+ *
+ * @special
+ */
+static inline void osalSysLockFromISR(void) {
+
+ chSysLockFromISR();
+}
+
+/**
+ * @brief Leaves a critical zone from ISR context.
+ * @note This function cannot be used for reentrant critical zones.
+ *
+ * @special
+ */
+static inline void osalSysUnlockFromISR(void) {
+
+ chSysUnlockFromISR();
+}
+
+/**
+ * @brief Returns the execution status and enters a critical zone.
+ * @details This functions enters into a critical zone and can be called
+ * from any context. Because its flexibility it is less efficient
+ * than @p chSysLock() which is preferable when the calling context
+ * is known.
+ * @post The system is in a critical zone.
+ *
+ * @return The previous system status, the encoding of this
+ * status word is architecture-dependent and opaque.
+ *
+ * @xclass
+ */
+static inline syssts_t osalSysGetStatusAndLockX(void) {
+
+ return chSysGetStatusAndLockX();
+}
+
+/**
+ * @brief Restores the specified execution status and leaves a critical zone.
+ * @note A call to @p chSchRescheduleS() is automatically performed
+ * if exiting the critical zone and if not in ISR context.
+ *
+ * @param[in] sts the system status to be restored.
+ *
+ * @xclass
+ */
+static inline void osalSysRestoreStatusX(syssts_t sts) {
+
+ chSysRestoreStatusX(sts);
+}
+
+/**
+ * @brief Polled delay.
+ * @note The real delay is always few cycles in excess of the specified
+ * value.
+ *
+ * @param[in] cycles number of cycles
+ *
+ * @xclass
+ */
+#if (PORT_SUPPORTS_RT == TRUE) || defined(__DOXYGEN__)
+static inline void osalSysPolledDelayX(rtcnt_t cycles) {
+
+ chSysPolledDelayX(cycles);
+}
+#endif
+
+/**
+ * @brief Systick callback for the underlying OS.
+ * @note This callback is only defined if the OSAL requires such a
+ * service from the HAL.
+ */
+#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
+static inline void osalOsTimerHandlerI(void) {
+
+ chSysTimerHandlerI();
+}
+#endif
+
+/**
+ * @brief Checks if a reschedule is required and performs it.
+ * @note I-Class functions invoked from thread context must not reschedule
+ * by themselves, an explicit reschedule using this function is
+ * required in this scenario.
+ * @note Not implemented in this simplified OSAL.
+ *
+ * @sclass
+ */
+static inline void osalOsRescheduleS(void) {
+
+ chSchRescheduleS();
+}
+
+/**
+ * @brief Current system time.
+ * @details Returns the number of system ticks since the @p osalInit()
+ * invocation.
+ * @note The counter can reach its maximum and then restart from zero.
+ * @note This function can be called from any context but its atomicity
+ * is not guaranteed on architectures whose word size is less than
+ * @p systime_t size.
+ *
+ * @return The system time in ticks.
+ *
+ * @xclass
+ */
+static inline systime_t osalOsGetSystemTimeX(void) {
+
+ return chVTGetSystemTimeX();
+}
+
+/**
+ * @brief Adds an interval to a system time returning a system time.
+ *
+ * @param[in] systime base system time
+ * @param[in] interval interval to be added
+ * @return The new system time.
+ *
+ * @xclass
+ */
+static inline systime_t osalTimeAddX(systime_t systime,
+ sysinterval_t interval) {
+
+ return chTimeAddX(systime, interval);
+}
+
+/**
+ * @brief Subtracts two system times returning an interval.
+ *
+ * @param[in] start first system time
+ * @param[in] end second system time
+ * @return The interval representing the time difference.
+ *
+ * @xclass
+ */
+static inline sysinterval_t osalTimeDiffX(systime_t start, systime_t end) {
+
+ return chTimeDiffX(start, end);
+}
+
+/**
+ * @brief Checks if the specified time is within the specified time window.
+ * @note When start==end then the function returns always true because the
+ * whole time range is specified.
+ * @note This function can be called from any context.
+ *
+ * @param[in] time the time to be verified
+ * @param[in] start the start of the time window (inclusive)
+ * @param[in] end the end of the time window (non inclusive)
+ * @retval true current time within the specified time window.
+ * @retval false current time not within the specified time window.
+ *
+ * @xclass
+ */
+static inline bool osalTimeIsInRangeX(systime_t time,
+ systime_t start,
+ systime_t end) {
+
+ return chTimeIsInRangeX(time, start, end);
+}
+
+/**
+ * @brief Suspends the invoking thread for the specified time.
+ *
+ * @param[in] delay the delay in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE is allowed but interpreted as a
+ * normal time specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
+ *
+ * @sclass
+ */
+static inline void osalThreadSleepS(sysinterval_t delay) {
+
+ chThdSleepS(delay);
+}
+
+/**
+ * @brief Suspends the invoking thread for the specified time.
+ *
+ * @param[in] delay the delay in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE is allowed but interpreted as a
+ * normal time specification.
+ * - @a TIME_IMMEDIATE this value is not allowed.
+ * .
+ *
+ * @api
+ */
+static inline void osalThreadSleep(sysinterval_t delay) {
+
+ chThdSleep(delay);
+}
+
+/**
+ * @brief Sends the current thread sleeping and sets a reference variable.
+ * @note This function must reschedule, it can only be called from thread
+ * context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @return The wake up message.
+ *
+ * @sclass
+ */
+static inline msg_t osalThreadSuspendS(thread_reference_t *trp) {
+
+ return chThdSuspendTimeoutS(trp, TIME_INFINITE);
+}
+
+/**
+ * @brief Sends the current thread sleeping and sets a reference variable.
+ * @note This function must reschedule, it can only be called from thread
+ * context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @param[in] timeout the timeout in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE the thread enters an infinite sleep
+ * state.
+ * - @a TIME_IMMEDIATE the thread is not enqueued and
+ * the function returns @p MSG_TIMEOUT as if a timeout
+ * occurred.
+ * .
+ * @return The wake up message.
+ * @retval MSG_TIMEOUT if the operation timed out.
+ *
+ * @sclass
+ */
+static inline msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp,
+ sysinterval_t timeout) {
+
+ return chThdSuspendTimeoutS(trp, timeout);
+}
+
+/**
+ * @brief Wakes up a thread waiting on a thread reference object.
+ * @note This function must not reschedule because it can be called from
+ * ISR context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+static inline void osalThreadResumeI(thread_reference_t *trp, msg_t msg) {
+
+ chThdResumeI(trp, msg);
+}
+
+/**
+ * @brief Wakes up a thread waiting on a thread reference object.
+ * @note This function must reschedule, it can only be called from thread
+ * context.
+ *
+ * @param[in] trp a pointer to a thread reference object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+static inline void osalThreadResumeS(thread_reference_t *trp, msg_t msg) {
+
+ chThdResumeS(trp, msg);
+}
+
+/**
+ * @brief Initializes a threads queue object.
+ *
+ * @param[out] tqp pointer to the threads queue object
+ *
+ * @init
+ */
+static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) {
+
+ chThdQueueObjectInit(tqp);
+}
+
+/**
+ * @brief Enqueues the caller thread.
+ * @details The caller thread is enqueued and put to sleep until it is
+ * dequeued or the specified timeouts expires.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] timeout the timeout in system ticks, the special values are
+ * handled as follow:
+ * - @a TIME_INFINITE the thread enters an infinite sleep
+ * state.
+ * - @a TIME_IMMEDIATE the thread is not enqueued and
+ * the function returns @p MSG_TIMEOUT as if a timeout
+ * occurred.
+ * .
+ * @return The message from @p osalQueueWakeupOneI() or
+ * @p osalQueueWakeupAllI() functions.
+ * @retval MSG_TIMEOUT if the thread has not been dequeued within the
+ * specified timeout or if the function has been
+ * invoked with @p TIME_IMMEDIATE as timeout
+ * specification.
+ *
+ * @sclass
+ */
+static inline msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp,
+ sysinterval_t timeout) {
+
+ return chThdEnqueueTimeoutS(tqp, timeout);
+}
+
+/**
+ * @brief Dequeues and wakes up one thread from the queue, if any.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+static inline void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) {
+
+ chThdDequeueNextI(tqp, msg);
+}
+
+/**
+ * @brief Dequeues and wakes up all threads from the queue.
+ *
+ * @param[in] tqp pointer to the threads queue object
+ * @param[in] msg the message code
+ *
+ * @iclass
+ */
+static inline void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) {
+
+ chThdDequeueAllI(tqp, msg);
+}
+
+#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Initializes an event source object.
+ *
+ * @param[out] esp pointer to the event source object
+ *
+ * @init
+ */
+static inline void osalEventObjectInit(event_source_t *esp) {
+
+ chEvtObjectInit(esp);
+}
+#else
+static inline void osalEventObjectInit(event_source_t *esp) {
+
+ osalDbgCheck(esp != NULL);
+
+ esp->flags = (eventflags_t)0;
+ esp->cb = NULL;
+ esp->param = NULL;
+}
+#endif
+
+#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Add flags to an event source object.
+ *
+ * @param[in] esp pointer to the event flags object
+ * @param[in] flags flags to be ORed to the flags mask
+ *
+ * @iclass
+ */
+static inline void osalEventBroadcastFlagsI(event_source_t *esp,
+ eventflags_t flags) {
+
+ chEvtBroadcastFlagsI(esp, flags);
+}
+#else
+static inline void osalEventBroadcastFlagsI(event_source_t *esp,
+ eventflags_t flags) {
+
+ osalDbgCheck(esp != NULL);
+
+ esp->flags |= flags;
+ if (esp->cb != NULL) {
+ esp->cb(esp);
+ }
+}
+#endif
+
+#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
+/**
+ * @brief Add flags to an event source object.
+ *
+ * @param[in] esp pointer to the event flags object
+ * @param[in] flags flags to be ORed to the flags mask
+ *
+ * @iclass
+ */
+static inline void osalEventBroadcastFlags(event_source_t *esp,
+ eventflags_t flags) {
+
+ chEvtBroadcastFlags(esp, flags);
+}
+#else
+static inline void osalEventBroadcastFlags(event_source_t *esp,
+ eventflags_t flags) {
+
+ osalDbgCheck(esp != NULL);
+
+ osalSysLock();
+ esp->flags |= flags;
+ if (esp->cb != NULL) {
+ esp->cb(esp);
+ }
+ osalSysUnlock();
+}
+#endif
+
+#if (CH_CFG_USE_EVENTS == FALSE) || defined(__DOXYGEN__)
+/**
+ * @brief Event callback setup.
+ * @note The callback is invoked from ISR context and can
+ * only invoke I-Class functions. The callback is meant
+ * to wakeup the task that will handle the event by
+ * calling @p osalEventGetAndClearFlagsI().
+ *
+ * @param[in] esp pointer to the event flags object
+ * @param[in] cb pointer to the callback function
+ * @param[in] param parameter to be passed to the callback function
+ *
+ * @api
+ */
+static inline void osalEventSetCallback(event_source_t *esp,
+ eventcallback_t cb,
+ void *param) {
+
+ osalDbgCheck(esp != NULL);
+
+ esp->cb = cb;
+ esp->param = param;
+}
+#endif
+
+/**
+ * @brief Initializes s @p mutex_t object.
+ *
+ * @param[out] mp pointer to the @p mutex_t object
+ *
+ * @init
+ */
+static inline void osalMutexObjectInit(mutex_t *mp) {
+
+#if CH_CFG_USE_MUTEXES
+ chMtxObjectInit(mp);
+#elif CH_CFG_USE_SEMAPHORES
+ chSemObjectInit((semaphore_t *)mp, 1);
+#else
+ *mp = 0;
+#endif
+}
+
+/**
+ * @brief Locks the specified mutex.
+ * @post The mutex is locked and inserted in the per-thread stack of owned
+ * mutexes.
+ *
+ * @param[in,out] mp pointer to the @p mutex_t object
+ *
+ * @api
+ */
+static inline void osalMutexLock(mutex_t *mp) {
+
+#if CH_CFG_USE_MUTEXES
+ chMtxLock(mp);
+#elif CH_CFG_USE_SEMAPHORES
+ chSemWait((semaphore_t *)mp);
+#else
+ *mp = 1;
+#endif
+}
+
+/**
+ * @brief Unlocks the specified mutex.
+ * @note The HAL guarantees to release mutex in reverse lock order. The
+ * mutex being unlocked is guaranteed to be the last locked mutex
+ * by the invoking thread.
+ * The implementation can rely on this behavior and eventually
+ * ignore the @p mp parameter which is supplied in order to support
+ * those OSes not supporting a stack of the owned mutexes.
+ *
+ * @param[in,out] mp pointer to the @p mutex_t object
+ *
+ * @api
+ */
+static inline void osalMutexUnlock(mutex_t *mp) {
+
+#if CH_CFG_USE_MUTEXES
+ chMtxUnlock(mp);
+#elif CH_CFG_USE_SEMAPHORES
+ chSemSignal((semaphore_t *)mp);
+#else
+ *mp = 0;
+#endif
+}
+
+#endif /* OSAL_H */
+
+/** @} */
diff --git a/ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.mk b/ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.mk new file mode 100644 index 0000000..f408d12 --- /dev/null +++ b/ChibiOS_20.3.2/os/hal/osal/rt-nil/osal.mk @@ -0,0 +1,9 @@ +# OSAL files.
+OSALSRC += ${CHIBIOS}/os/hal/osal/rt-nil/osal.c
+
+# Required include directories
+OSALINC += ${CHIBIOS}/os/hal/osal/rt-nil
+
+# Shared variables
+ALLCSRC += $(OSALSRC)
+ALLINC += $(OSALINC)
|