aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/templates/osal/osal.h
diff options
context:
space:
mode:
Diffstat (limited to 'os/hal/templates/osal/osal.h')
-rw-r--r--os/hal/templates/osal/osal.h528
1 files changed, 423 insertions, 105 deletions
diff --git a/os/hal/templates/osal/osal.h b/os/hal/templates/osal/osal.h
index fdad4dcbb..d1df76826 100644
--- a/os/hal/templates/osal/osal.h
+++ b/os/hal/templates/osal/osal.h
@@ -53,17 +53,47 @@
* @name Messages
* @{
*/
-#define MSG_OK 0
-#define MSG_RESET -1
-#define MSG_TIMEOUT -2
+#define MSG_OK 0
+#define MSG_RESET -1
+#define MSG_TIMEOUT -2
/** @} */
+
/**
* @name Special time constants
* @{
*/
-#define TIME_IMMEDIATE ((systime_t)0)
-#define TIME_INFINITE ((systime_t)-1)
+#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 Required systick frequency or resolution.
+ */
+#define OSAL_ST_FREQUENCY 1000
+
+/**
+ * @brief Systick mode required by the underlying OS.
+ */
+#define OSAL_ST_MODE OSAL_ST_MODE_PERIODIC
/** @} */
/*===========================================================================*/
@@ -79,9 +109,9 @@
/*===========================================================================*/
/**
- * @brief Type of a machine status register.
+ * @brief Type of a system status word.
*/
-typedef uint32_t osal_sts_t;
+typedef uint32_t syssts_t;
/**
* @brief Type of a message.
@@ -94,27 +124,50 @@ typedef int32_t msg_t;
typedef uint32_t systime_t;
/**
+ * @brief Type of realtime counter.
+ */
+typedef uint32_t rtcnt_t;
+
+/**
* @brief Type of a thread reference.
*/
typedef void * 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 *);
+
+/**
* @brief Type of an event flags mask.
*/
typedef uint32_t eventflags_t;
/**
- * @brief Type of an event flags object.
+ * @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.
*/
-typedef struct {
- volatile eventflags_t flags; /**< @brief Flags stored into the
- object. */
-} event_source_t;
+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.
@@ -127,8 +180,8 @@ 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 In this implementation it is implemented as a single reference
- * because there are no real threads.
+ * @note If the OSAL is implemented on a bare metal machine withou RTOS
+ * then the queue can be implemented as a single thread reference.
*/
typedef struct {
thread_reference_t tr;
@@ -139,23 +192,24 @@ typedef struct {
/*===========================================================================*/
/**
+ * @name Debug related macros
+ * @{
+ */
+/**
* @brief Condition assertion.
- * @details If the condition check fails then the OSAL panics with the
- * specified message and halts.
+ * @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 convention for the message is the following:<br>
- * @<function_name@>(), #@<assert_number@>
* @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] msg the text message
* @param[in] remark a remark string
*
* @api
*/
-#define osalDbgAssert(c, msg, remark)
+#define osalDbgAssert(c, remark)
/**
* @brief Function parameters check.
@@ -171,17 +225,22 @@ typedef struct {
/**
* @brief I-Class state check.
- * @note Not implemented in this simplified OSAL.
+ * @note Implementation is optional.
*/
#define osalDbgCheckClassI()
/**
* @brief S-Class state check.
- * @note Not implemented in this simplified OSAL.
+ * @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.
*/
@@ -200,6 +259,96 @@ typedef struct {
* @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] sec number of seconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define OSAL_S2ST(sec) \
+ ((systime_t)((sec) * 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) - 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] usec number of microseconds
+ * @return The number of ticks.
+ *
+ * @api
+ */
+#define OSAL_US2ST(usec) \
+ ((systime_t)(((((uint32_t)(usec)) * ((uint32_t)OSAL_ST_FREQUENCY) - 1UL) /\
+ 1000000UL) + 1UL))
+/** @} */
+
+/**
+ * @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. */
@@ -210,7 +359,8 @@ extern "C" {
#endif
void osalInit(void);
void osalSysHalt(const char *reason);
- msg_t osalQueueGoSleepTimeoutS(threads_queue_t *tqp, systime_t time);
+ void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg);
+ void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg);
#ifdef __cplusplus
}
#endif
@@ -220,6 +370,33 @@ extern "C" {
/*===========================================================================*/
/**
+ * @brief Globally enables interrupts.
+ *
+ * @special
+ */
+static inline void osalSysEnable(void) {
+
+}
+
+/**
+ * @brief Globally disables interrupts.
+ *
+ * @special
+ */
+static inline void osalSysDisable(void) {
+
+}
+
+/**
+ * @brief Waits for an interrupt to occur.
+ *
+ * @special
+ */
+static inline void osalSysWait(void) {
+
+}
+
+/**
* @brief Enters a critical zone from thread context.
* @note This function cannot be used for reentrant critical zones.
*
@@ -260,32 +437,63 @@ static inline void osalSysUnlockFromISR(void) {
}
/**
- * @brief Enters a critical zone returning the previous machine status.
+ * @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 status.
+ * @return The previous system status, the encoding of this
+ * status word is architecture-dependent and opaque.
*
- * @special
+ * @xclass
*/
-static inline osal_sts_t osalSysGetStatusAndLock(void) {
+static inline syssts_t osalSysGetStatusAndLockX(void) {
return 0;
}
/**
- * @brief Restores a machine status.
+ * @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 previous status. This value must be something
- * returned by the function @p osalSysGetStatusAndLock().
- * Arbitrary values are not allowed.
+ * @param[in] sts the system status to be restored.
*
- * @special
+ * @xclass
*/
-static inline void osalSysSetStatus(osal_sts_t sts) {
+static inline void osalSysRestoreStatusX(syssts_t sts) {
(void)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
+ */
+static inline void osalSysPolledDelayX(rtcnt_t cycles) {
+
+ (void)cycles;
+}
+
+/**
+ * @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) {
+
+}
+#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
@@ -299,6 +507,45 @@ static inline 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
+ * @systime_t size.
+ *
+ * @return The system time in ticks.
+ *
+ * @xclass
+ */
+static inline systime_t osalOsGetSystemTimeX(void) {
+
+ return 0;
+}
+
+/**
+ * @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 osalOsIsTimeWithinX(systime_t time,
+ systime_t start,
+ systime_t end) {
+
+ return (bool)(time - start < end - start);
+}
+
+/**
* @brief Suspends the invoking thread for the specified time.
*
* @param[in] time the delay in system ticks, the special values are
@@ -310,7 +557,7 @@ static inline void osalOsRescheduleS(void) {
*
* @sclass
*/
-inline void osalThreadSleepS(systime_t time) {
+static inline void osalThreadSleepS(systime_t time) {
(void)time;
}
@@ -327,23 +574,146 @@ inline void osalThreadSleepS(systime_t time) {
*
* @api
*/
-void osalThreadSleep(systime_t time) {
+static inline void osalThreadSleep(systime_t time) {
(void)time;
}
/**
+ * @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) {
+
+ (void)trp;
+
+ return MSG_OK;
+}
+
+/**
+ * @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,
+ systime_t timeout) {
+
+ (void)trp;
+ (void)timeout;
+
+ return MSG_OK;
+}
+
+/**
+ * @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) {
+
+ (void)trp;
+ (void)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) {
+
+ (void)trp;
+ (void)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) {
+
+ (void)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] time 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 RDY_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,
+ systime_t time) {
+
+ (void)tqp;
+ (void)time;
+
+ return MSG_OK;
+}
+
+/**
* @brief Initializes an event flags object.
*
* @param[out] esp pointer to the event flags object
*
* @init
*/
-static inline void osalEventInit(event_source_t *esp) {
+static inline void osalEventObjectInit(event_source_t *esp) {
osalDbgCheck(esp != NULL);
esp->flags = 0;
+ esp->cb = NULL;
+ esp->param = NULL;
}
/**
@@ -360,6 +730,8 @@ static inline void osalEventBroadcastFlagsI(event_source_t *esp,
osalDbgCheck(esp != NULL);
esp->flags |= flags;
+ if (esp->cb != NULL)
+ esp->cb(esp);
}
/**
@@ -376,47 +748,33 @@ static inline void osalEventBroadcastFlags(event_source_t *esp,
osalDbgCheck(esp != NULL);
osalSysLock();
- esp->flags |= flags;
+ osalEventBroadcastFlagsI(esp, flags);
osalSysUnlock();
}
/**
- * @brief Returns the flags associated to the event object then clears them.
+ * @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
- * @return The flags.
+ * @param[in] cb pointer to the callback function
+ * @param[in] param parameter to be passed to the callback function
*
- * @iclass
+ * @api
*/
-static inline eventflags_t osalEventGetAndClearFlagsI(event_source_t *esp) {
- eventflags_t flags;
+static inline void osalEventSetCallback(event_source_t *esp,
+ eventcallback_t cb,
+ void *param) {
osalDbgCheck(esp != NULL);
- flags = esp->flags;
- esp->flags = 0;
- return flags;
-}
-
-/**
- * @brief Returns the flags associated to the event object and clears them.
- * @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
- * @return The flags.
- *
- * @api
- */
-static inline eventflags_t osalEventGetAndClearFlags(event_source_t *esp) {
- eventflags_t flags;
-
- osalSysLock();
- flags = osalEventGetAndClearFlagsI(esp);
- osalSysUnlock();
- return flags;
+ esp->cb = cb;
+ esp->param = param;
}
/**
@@ -426,7 +784,7 @@ static inline eventflags_t osalEventGetAndClearFlags(event_source_t *esp) {
*
* @init
*/
-static inline void osalMutexInit(mutex_t *mp) {
+static inline void osalMutexObjectInit(mutex_t *mp) {
*mp = 0;
}
@@ -463,46 +821,6 @@ static inline void osalMutexUnlock(mutex_t *mp) {
*mp = 0;
}
-/**
- * @brief Initializes a threads queue object.
- *
- * @param[out] tqp pointer to the threads queue object
- *
- * @init
- */
-static inline void osalQueueInit(threads_queue_t *tqp) {
-
- (void)tqp;
-}
-
-/**
- * @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 osalQueueWakeupOneI(threads_queue_t *tqp, msg_t msg) {
-
- (void)tqp;
- (void)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 osalQueueWakeupAllI(threads_queue_t *tqp, msg_t msg) {
-
- (void)tqp;
- (void)msg;
-}
-
#endif /* _OSAL_H_ */
/** @} */