aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/osal/lib/osal_vt.c
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2016-12-22 10:36:32 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2016-12-22 10:36:32 +0000
commit70aee6011b8f5fc985140464623019f6d57af540 (patch)
tree120a5bece9718f7d559dd282a59ccf6b1029f3e4 /os/hal/osal/lib/osal_vt.c
parentded823da225a0214cf028cdb79ecfb1cba0df9cd (diff)
downloadChibiOS-70aee6011b8f5fc985140464623019f6d57af540.tar.gz
ChibiOS-70aee6011b8f5fc985140464623019f6d57af540.tar.bz2
ChibiOS-70aee6011b8f5fc985140464623019f6d57af540.zip
Added standalone virtual timers module.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9985 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/osal/lib/osal_vt.c')
-rw-r--r--os/hal/osal/lib/osal_vt.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/os/hal/osal/lib/osal_vt.c b/os/hal/osal/lib/osal_vt.c
new file mode 100644
index 000000000..8954b5c8f
--- /dev/null
+++ b/os/hal/osal/lib/osal_vt.c
@@ -0,0 +1,168 @@
+/*
+ ChibiOS - Copyright (C) 2006..2016 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_time = (systime_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_time;
+ while (!(vtp = vtlist.vt_next)->vt_time) {
+ 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] time 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, systime_t time,
+ vtfunc_t vtfunc, void *par) {
+ virtual_timer_t *p;
+
+ vtp->vt_par = par;
+ vtp->vt_func = vtfunc;
+ p = vtlist.vt_next;
+ while (p->vt_time < time) {
+ time -= p->vt_time;
+ p = p->vt_next;
+ }
+
+ vtp->vt_prev = (vtp->vt_next = p)->vt_prev;
+ vtp->vt_prev->vt_next = p->vt_prev = vtp;
+ vtp->vt_time = time;
+ if (p != (void *)&vtlist)
+ p->vt_time -= time;
+}
+
+/**
+ * @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_time += vtp->vt_time;
+ vtp->vt_prev->vt_next = vtp->vt_next;
+ vtp->vt_next->vt_prev = vtp->vt_prev;
+ vtp->vt_func = (vtfunc_t)NULL;
+}
+
+/** @} */