]> code.bitgloo.com Git - clyne/stm-game.git/commitdiff
remove rtos; disable systick
authorClyne Sullivan <clyne@bitgloo.com>
Sat, 18 Sep 2021 19:06:11 +0000 (15:06 -0400)
committerClyne Sullivan <clyne@bitgloo.com>
Sat, 18 Sep 2021 19:06:11 +0000 (15:06 -0400)
Makefile
buttons.c
cfg/chconf.h
cfg/halconf.h
cfg/osalconf.h [new file with mode: 0644]
dogs.c
main.c
osal.c [new file with mode: 0644]
osal.h [new file with mode: 0644]

index cf0172d5c4129a20041641e7745e987a645ecf98..050356ddd991d580d5e322d063d5bca86d94da19 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -55,13 +55,13 @@ endif
 # Stack size to be allocated to the Cortex-M process stack. This stack is\r
 # the stack used by the main() thread.\r
 ifeq ($(USE_PROCESS_STACKSIZE),)\r
-  USE_PROCESS_STACKSIZE = 0x80\r
+  USE_PROCESS_STACKSIZE = 0\r
 endif\r
 \r
 # Stack size to the allocated to the Cortex-M main/exceptions stack. This\r
 # stack is used for processing interrupts and exceptions.\r
 ifeq ($(USE_EXCEPTIONS_STACKSIZE),)\r
-  USE_EXCEPTIONS_STACKSIZE = 0x100\r
+  USE_EXCEPTIONS_STACKSIZE = 0x180\r
 endif\r
 \r
 # Enables the use of FPU (no, softfp, hard).\r
@@ -102,12 +102,13 @@ include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32l0xx.m
 include $(CHIBIOS)/os/hal/hal.mk\r
 include $(CHIBIOS)/os/hal/ports/STM32/STM32L0xx/platform.mk\r
 include $(CHIBIOS)/os/hal/boards/ST_NUCLEO32_L011K4/board.mk\r
-include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk\r
+#include $(CHIBIOS)/os/hal/osal/os-less/ARMCMx/osal.mk\r
+#include $(CHIBIOS)/os/hal/osal/rt-nil/osal.mk\r
 # RTOS files (optional).\r
-include $(CHIBIOS)/os/nil/nil.mk\r
-include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk\r
+#include $(CHIBIOS)/os/nil/nil.mk\r
+#include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v6m.mk\r
 # Auto-build files in ./source recursively.\r
-include $(CHIBIOS)/tools/mk/autobuild.mk\r
+#include $(CHIBIOS)/tools/mk/autobuild.mk\r
 # Other files (optional).\r
 #include $(CHIBIOS)/test/lib/test.mk\r
 #include $(CHIBIOS)/test/nil/nil_test.mk\r
@@ -121,11 +122,13 @@ LDSCRIPT= ./STM32L011x4.ld
 # setting.\r
 CSRC = $(ALLCSRC) \\r
        $(TESTSRC) \\r
-          dogs.c \\r
+          $(CHIBIOS)/os/hal/osal/lib/osal_vt.c \\r
+          2048.c \\r
           buttons.c \\r
+          dogs.c \\r
           flapbird.c \\r
-          2048.c \\r
-       main.c\r
+       main.c \\r
+          osal.c\r
 \r
 # C++ sources that can be compiled in ARM or THUMB mode depending on the global\r
 # setting.\r
@@ -155,13 +158,13 @@ CPPWARN = -Wall -Wextra -Wundef
 #\r
 \r
 # List all user C define here, like -D_DEBUG=1\r
-UDEFS =\r
+UDEFS = -DNOINLINE="" -DchDbgCheck=osalDbgCheck\r
 \r
 # Define ASM defines here\r
-UADEFS =\r
+UADEFS = -DCRT0_CONTROL_INIT=0\r
 \r
 # List all user directories here\r
-UINCDIR =\r
+UINCDIR = $(CHIBIOS)/os/hal/osal/lib\r
 \r
 # List the user directory to look for the libraries here\r
 ULIBDIR =\r
index 5605e69a8423227a0818239795b0509b5b0edc5e..45ea7bd527d7ece3ab8b0eb1e4d339427fda1fec 100644 (file)
--- a/buttons.c
+++ b/buttons.c
@@ -10,7 +10,6 @@
  */
 
 #include "buttons.h"
-#include "ch.h"
 #include "hal.h"
 
 unsigned char button_state = 0;
index 25d444a4417d88ea46cbfd5110f19cde340798f4..f935558ddee4be79e3ec994a7c694e96ebab6a65 100644 (file)
@@ -55,7 +55,7 @@
  * @brief   Auto starts threads when @p chSysInit() is invoked.\r
  */\r
 #if !defined(CH_CFG_AUTOSTART_THREADS)\r
-#define CH_CFG_AUTOSTART_THREADS            TRUE\r
+#define CH_CFG_AUTOSTART_THREADS            FALSE\r
 #endif\r
 \r
 /** @} */\r
index 6688b95793eac20e4b39745f52fe6a1d8ec332ff..e3a57ae8798c0446562c85f64749a80e706c7832 100644 (file)
  * @note    Disabling this option saves both code and data space.\r
  */\r
 #if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)\r
-#define SPI_USE_WAIT                        FALSE\r
+#define SPI_USE_WAIT                        TRUE\r
 #endif\r
 \r
 /**\r
diff --git a/cfg/osalconf.h b/cfg/osalconf.h
new file mode 100644 (file)
index 0000000..0d772ed
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+        http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+*/\r
+\r
+/**\r
+ * @file    templates/halconf.h\r
+ * @brief   Bare-metal OSAL configuration header.\r
+ *\r
+ * @addtogroup OSAL_CONF\r
+ * @{\r
+ */\r
+\r
+#ifndef OSALCONF_H\r
+#define OSALCONF_H\r
+\r
+/**\r
+ * @brief   Frequency in Hertz of the system tick.\r
+ */\r
+#if !defined(OSAL_ST_FREQUENCY) || defined(__DOXYGEN__)\r
+#define OSAL_ST_FREQUENCY                   0\r
+#endif\r
+\r
+#define OSAL_ST_MODE                                           OSAL_ST_MODE_NONE\r
+\r
+/**\r
+ * @brief   Enables OSAL assertions.\r
+ */\r
+#if !defined(OSAL_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)\r
+#define OSAL_DBG_ENABLE_ASSERTS             TRUE\r
+#endif\r
+\r
+/**\r
+ * @brief   Enables OSAL functions parameters checks.\r
+ */\r
+#if !defined(OSAL_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)\r
+#define OSAL_DBG_ENABLE_CHECKS              TRUE\r
+#endif\r
+\r
+/**\r
+ * @brief   OSAL initialization hook.\r
+ */\r
+#if !defined(OSAL_INIT_HOOK) || defined(__DOXYGEN__)\r
+#define OSAL_INIT_HOOK() {                                                  \\r
+}\r
+#endif\r
+\r
+/**\r
+ * @brief   Idle loop hook macro.\r
+ */\r
+#if !defined(OSAL_IDLE_HOOK) || defined(__DOXYGEN__)\r
+#define OSAL_IDLE_HOOK() {                                                  \\r
+}\r
+#endif\r
+\r
+#endif /* OSALCONF_H */\r
+\r
+/** @} */\r
diff --git a/dogs.c b/dogs.c
index 7d3269842db12816695fa3b24afa3a2f87a96660..101339f39ddadb5cb47bb3f698fda0049d8ad54b 100644 (file)
--- a/dogs.c
+++ b/dogs.c
@@ -9,7 +9,7 @@
  * See the GNU General Public License for more details.
  */
 
-#include "ch.h"
+//#include "ch.h"
 #include "dogs.h"
 #include "hal.h"
 
 #define CS_LOW   palClearPad(GPIOA, 4)
 unsigned char dogs_buffer[DISP_WIDTH * DISP_HEIGHT / 8];
 
-static volatile bool dogs_spi_done = false;
+//static volatile bool dogs_spi_done = false;
 
-static void spi_send(unsigned char *data, unsigned int len)
-{
-    dogs_spi_done = false;
-    spiStartSend(&SPID1, len, data);
-    while (!dogs_spi_done)
-        asm("wfi");
+#define spi_send(data, len) spiSend(&SPID1, len, data)
+//static void spi_send(unsigned char *data, unsigned int len)
+//{
+    //dogs_spi_done = false;
+    //spiStartSend(&SPID1, len, data);
+    //while (!dogs_spi_done)
+    //    asm("wfi");
 
     //for (; len > 0; --len)
     //    spiPolledExchange(&SPID1, *data++);
-}
+//}
 
 static void dogs_init_display();
-static void dogs_spi_callback(SPIDriver *spid)
-{
-    if (spiIsBufferComplete(spid))
-        dogs_spi_done = true;
-}
+//static void dogs_spi_callback(SPIDriver *spid)
+//{
+//    if (spiIsBufferComplete(spid))
+//        dogs_spi_done = true;
+//}
 
 void dogs_init()
 {
@@ -54,7 +55,7 @@ void dogs_init()
 
     static const SPIConfig spicfg = {
         false,
-        dogs_spi_callback,
+        NULL /*dogs_spi_callback*/,
         0, // cr1
         0
     };
@@ -136,7 +137,13 @@ void dogs_init_display()
     CS_LOW;
     dogs_reset();
     CS_HIGH;
-    chThdSleepS(TIME_MS2I(100) / 64);
+
+       unsigned long int reset_sleep = (STM32_SYSCLK / 1000) * 100;
+       while (reset_sleep != 0) {
+               asm("nop; nop; nop; nop; nop");
+               reset_sleep -= 8;
+       }
+
     CS_LOW;
     dogs_set_scroll_line(0);
     dogs_set_segdir(true);
diff --git a/main.c b/main.c
index 37c1471760e59b577bb87f717065bafe674a5af1..1ef13bf05bd1a1a72613191fe87212cb3788dadd 100644 (file)
--- a/main.c
+++ b/main.c
  */
 
 #include "buttons.h"
-#include "ch.h"
 #include "dogs.h"
 #include "hal.h"
 
-#include "2048.h"
+//#include "2048.h"
 #include "flapbird.h"
 
 /*
 
 static int readVddmv();
 
-THD_WORKING_AREA(waThread2, 128);
-THD_FUNCTION(Thread2, arg)
-{
-    (void)arg;
-
-    dogs_init();
-    flapbird_init();
-}
-THD_TABLE_BEGIN
-    THD_TABLE_THREAD(0, "game", waThread2, Thread2, NULL)
-THD_TABLE_END
-
 static void alarm_callback(RTCDriver *rtcp, rtcevent_t event)
 {
     (void)rtcp;
@@ -80,12 +67,15 @@ static void alarm_callback(RTCDriver *rtcp, rtcevent_t event)
 int main(void)
 {
     halInit();
-    chSysInit();
+    //chSysInit();
     buttons_init();
 
+    dogs_init();
+    flapbird_init();
+
     static const RTCWakeup wakeupcfg = {
         (0 << 16) | // wucksel (37k /16 = ~2k)
-        240         // wut (hope for 10Hz)
+        200         // wut (hope for 10Hz)
     };
     rtcSTM32SetPeriodicWakeup(&RTCD1, &wakeupcfg);
     rtcSetCallback(&RTCD1, alarm_callback);
@@ -94,7 +84,7 @@ int main(void)
     PWR->CR |= PWR_CR_LPSDSR | PWR_CR_ULP;
     PWR->CR |= PWR_CR_LPRUN;
     SCB->SCR = 6;
-    FLASH->ACR |= FLASH_ACR_SLEEP_PD;
+    //FLASH->ACR |= FLASH_ACR_SLEEP_PD;
 
     // Below code for serial -- note that it cuts off debugging, and MUST be used in a thread
     //chThdSleepMilliseconds(2000);
diff --git a/osal.c b/osal.c
new file mode 100644 (file)
index 0000000..5c62069
--- /dev/null
+++ b/osal.c
@@ -0,0 +1,467 @@
+/*\r
+    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+        http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+*/\r
+\r
+/**\r
+ * @file    osal.c\r
+ * @brief   OSAL module code.\r
+ *\r
+ * @addtogroup OSAL\r
+ * @{\r
+ */\r
+\r
+#include "osal.h"\r
+#include "osal_vt.h"\r
+\r
+/*===========================================================================*/\r
+/* Module local definitions.                                                 */\r
+/*===========================================================================*/\r
+\r
+/*===========================================================================*/\r
+/* Module exported variables.                                                */\r
+/*===========================================================================*/\r
+\r
+/**\r
+ * @brief   Pointer to a halt error message.\r
+ * @note    The message is meant to be retrieved by the debugger after the\r
+ *          system halt caused by an unexpected error.\r
+ */\r
+const char *osal_halt_msg;\r
+\r
+/*===========================================================================*/\r
+/* Module local types.                                                       */\r
+/*===========================================================================*/\r
+\r
+/*===========================================================================*/\r
+/* Module local variables.                                                   */\r
+/*===========================================================================*/\r
+\r
+/*===========================================================================*/\r
+/* Module local functions.                                                   */\r
+/*===========================================================================*/\r
+\r
+static void callback_timeout(void *p) {\r
+  osalSysLockFromISR();\r
+  osalThreadResumeI((thread_reference_t *)p, MSG_TIMEOUT);\r
+  osalSysUnlockFromISR();\r
+}\r
+\r
+/*===========================================================================*/\r
+/* Module exported functions.                                                */\r
+/*===========================================================================*/\r
+\r
+/**\r
+ * @brief   OSAL module initialization.\r
+ *\r
+ * @api\r
+ */\r
+void osalInit(void) {\r
+\r
+  vtInit();\r
+\r
+  OSAL_INIT_HOOK();\r
+}\r
+\r
+/**\r
+ * @brief   System halt with error message.\r
+ *\r
+ * @param[in] reason    the halt message pointer\r
+ *\r
+ * @api\r
+ */\r
+#if !defined(__DOXYGEN__)\r
+__attribute__((weak, noreturn))\r
+#endif\r
+void osalSysHalt(const char *reason) {\r
+\r
+  osalSysDisable();\r
+  osal_halt_msg = reason;\r
+  while (true) {\r
+  }\r
+}\r
+\r
+/**\r
+ * @brief   Polled delay.\r
+ * @note    The real delay is always few cycles in excess of the specified\r
+ *          value.\r
+ *\r
+ * @param[in] cycles    number of cycles\r
+ *\r
+ * @xclass\r
+ */\r
+void osalSysPolledDelayX(rtcnt_t cycles) {\r
+\r
+  (void)cycles;\r
+}\r
+\r
+/**\r
+ * @brief   System timer handler.\r
+ * @details The handler is used for scheduling and Virtual Timers management.\r
+ *\r
+ * @iclass\r
+ */\r
+void osalOsTimerHandlerI(void) {\r
+\r
+  osalDbgCheckClassI();\r
+\r
+  vtDoTickI();\r
+}\r
+\r
+/**\r
+ * @brief   Checks if a reschedule is required and performs it.\r
+ * @note    I-Class functions invoked from thread context must not reschedule\r
+ *          by themselves, an explicit reschedule using this function is\r
+ *          required in this scenario.\r
+ * @note    Not implemented in this simplified OSAL.\r
+ *\r
+ * @sclass\r
+ */\r
+void osalOsRescheduleS(void) {\r
+\r
+}\r
+\r
+/**\r
+ * @brief   Current system time.\r
+ * @details Returns the number of system ticks since the @p osalInit()\r
+ *          invocation.\r
+ * @note    The counter can reach its maximum and then restart from zero.\r
+ * @note    This function can be called from any context but its atomicity\r
+ *          is not guaranteed on architectures whose word size is less than\r
+ *          @p systime_t size.\r
+ *\r
+ * @return              The system time in ticks.\r
+ *\r
+ * @xclass\r
+ */\r
+systime_t osalOsGetSystemTimeX(void) {\r
+\r
+  return vtlist.vt_systime;\r
+}\r
+\r
+/**\r
+ * @brief   Suspends the invoking thread for the specified time.\r
+ *\r
+ * @param[in] time      the delay in system ticks, the special values are\r
+ *                      handled as follow:\r
+ *                      - @a TIME_INFINITE is allowed but interpreted as a\r
+ *                        normal time specification.\r
+ *                      - @a TIME_IMMEDIATE this value is not allowed.\r
+ *                      .\r
+ *\r
+ * @sclass\r
+ */\r
+void osalThreadSleepS(sysinterval_t time) {\r
+  virtual_timer_t vt;\r
+  thread_reference_t tr;\r
+\r
+  tr = NULL;\r
+  vtSetI(&vt, time, callback_timeout, (void *)&tr);\r
+  osalThreadSuspendS(&tr);\r
+}\r
+\r
+/**\r
+ * @brief   Suspends the invoking thread for the specified time.\r
+ *\r
+ * @param[in] time      the delay in system ticks, the special values are\r
+ *                      handled as follow:\r
+ *                      - @a TIME_INFINITE is allowed but interpreted as a\r
+ *                        normal time specification.\r
+ *                      - @a TIME_IMMEDIATE this value is not allowed.\r
+ *                      .\r
+ *\r
+ * @api\r
+ */\r
+void osalThreadSleep(sysinterval_t time) {\r
+\r
+  osalSysLock();\r
+  osalThreadSleepS(time);\r
+  osalSysUnlock();\r
+}\r
+\r
+/**\r
+ * @brief   Sends the current thread sleeping and sets a reference variable.\r
+ * @note    This function must reschedule, it can only be called from thread\r
+ *          context.\r
+ *\r
+ * @param[in] trp       a pointer to a thread reference object\r
+ * @return              The wake up message.\r
+ *\r
+ * @sclass\r
+ */\r
+msg_t osalThreadSuspendS(thread_reference_t *trp) {\r
+  thread_t self = {MSG_WAIT};\r
+\r
+  osalDbgCheck(trp != NULL);\r
+\r
+  *trp = &self;\r
+  while (self.message == MSG_WAIT) {\r
+    osalSysUnlock();\r
+    /* A state-changing interrupt could occur here and cause the loop to\r
+       terminate, an hook macro is executed while waiting.*/\r
+    OSAL_IDLE_HOOK();\r
+    osalSysLock();\r
+  }\r
+\r
+  return self.message;\r
+}\r
+\r
+/**\r
+ * @brief   Sends the current thread sleeping and sets a reference variable.\r
+ * @note    This function must reschedule, it can only be called from thread\r
+ *          context.\r
+ *\r
+ * @param[in] trp       a pointer to a thread reference object\r
+ * @param[in] timeout   the timeout in system ticks, the special values are\r
+ *                      handled as follow:\r
+ *                      - @a TIME_INFINITE the thread enters an infinite sleep\r
+ *                        state.\r
+ *                      - @a TIME_IMMEDIATE the thread is not enqueued and\r
+ *                        the function returns @p MSG_TIMEOUT as if a timeout\r
+ *                        occurred.\r
+ *                      .\r
+ * @return              The wake up message.\r
+ * @retval MSG_TIMEOUT  if the operation timed out.\r
+ *\r
+ * @sclass\r
+ */\r
+msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout) {\r
+  msg_t msg;\r
+  virtual_timer_t vt;\r
+\r
+  osalDbgCheck(trp != NULL);\r
+\r
+  if (TIME_INFINITE == timeout)\r
+   return osalThreadSuspendS(trp);\r
+\r
+  vtSetI(&vt, timeout, callback_timeout, (void *)trp);\r
+  msg = osalThreadSuspendS(trp);\r
+  if (vtIsArmedI(&vt))\r
+    vtResetI(&vt);\r
+\r
+  return msg;\r
+}\r
+\r
+/**\r
+ * @brief   Wakes up a thread waiting on a thread reference object.\r
+ * @note    This function must not reschedule because it can be called from\r
+ *          ISR context.\r
+ *\r
+ * @param[in] trp       a pointer to a thread reference object\r
+ * @param[in] msg       the message code\r
+ *\r
+ * @iclass\r
+ */\r
+void osalThreadResumeI(thread_reference_t *trp, msg_t msg) {\r
+\r
+  osalDbgCheck(trp != NULL);\r
+\r
+  if (*trp != NULL) {\r
+    (*trp)->message = msg;\r
+    *trp = NULL;\r
+  }\r
+}\r
+\r
+/**\r
+ * @brief   Wakes up a thread waiting on a thread reference object.\r
+ * @note    This function must reschedule, it can only be called from thread\r
+ *          context.\r
+ *\r
+ * @param[in] trp       a pointer to a thread reference object\r
+ * @param[in] msg       the message code\r
+ *\r
+ * @iclass\r
+ */\r
+void osalThreadResumeS(thread_reference_t *trp, msg_t msg) {\r
+\r
+  osalDbgCheck(trp != NULL);\r
+\r
+  if (*trp != NULL) {\r
+    (*trp)->message = msg;\r
+    *trp = NULL;\r
+  }\r
+}\r
+\r
+/**\r
+ * @brief   Enqueues the caller thread.\r
+ * @details The caller thread is enqueued and put to sleep until it is\r
+ *          dequeued or the specified timeouts expires.\r
+ *\r
+ * @param[in] tqp       pointer to the threads queue object\r
+ * @param[in] timeout   the timeout in system ticks, the special values are\r
+ *                      handled as follow:\r
+ *                      - @a TIME_INFINITE the thread enters an infinite sleep\r
+ *                        state.\r
+ *                      - @a TIME_IMMEDIATE the thread is not enqueued and\r
+ *                        the function returns @p MSG_TIMEOUT as if a timeout\r
+ *                        occurred.\r
+ *                      .\r
+ * @return              The message from @p osalQueueWakeupOneI() or\r
+ *                      @p osalQueueWakeupAllI() functions.\r
+ * @retval MSG_TIMEOUT  if the thread has not been dequeued within the\r
+ *                      specified timeout or if the function has been\r
+ *                      invoked with @p TIME_IMMEDIATE as timeout\r
+ *                      specification.\r
+ *\r
+ * @sclass\r
+ */\r
+msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout) {\r
+  msg_t msg;\r
+  virtual_timer_t vt;\r
+\r
+  osalDbgCheck(tqp != NULL);\r
+\r
+  if (TIME_IMMEDIATE == timeout)\r
+    return MSG_TIMEOUT;\r
+\r
+  tqp->tr = NULL;\r
+\r
+  if (TIME_INFINITE == timeout)\r
+   return osalThreadSuspendS(&tqp->tr);\r
+\r
+  vtSetI(&vt, timeout, callback_timeout, (void *)&tqp->tr);\r
+  msg = osalThreadSuspendS(&tqp->tr);\r
+  if (vtIsArmedI(&vt))\r
+    vtResetI(&vt);\r
+\r
+  return msg;\r
+}\r
+\r
+/**\r
+ * @brief   Dequeues and wakes up one thread from the queue, if any.\r
+ *\r
+ * @param[in] tqp       pointer to the threads queue object\r
+ * @param[in] msg       the message code\r
+ *\r
+ * @iclass\r
+ */\r
+void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg) {\r
+\r
+  osalDbgCheck(tqp != NULL);\r
+\r
+  osalThreadResumeI(&tqp->tr, msg);\r
+}\r
+\r
+/**\r
+ * @brief   Dequeues and wakes up all threads from the queue.\r
+ *\r
+ * @param[in] tqp       pointer to the threads queue object\r
+ * @param[in] msg       the message code\r
+ *\r
+ * @iclass\r
+ */\r
+void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg) {\r
+\r
+  osalDbgCheck(tqp != NULL);\r
+\r
+  osalThreadResumeI(&tqp->tr, msg);\r
+}\r
+\r
+/**\r
+ * @brief   Add flags to an event source object.\r
+ *\r
+ * @param[in] esp       pointer to the event flags object\r
+ * @param[in] flags     flags to be ORed to the flags mask\r
+ *\r
+ * @iclass\r
+ */\r
+void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags) {\r
+\r
+  osalDbgCheck(esp != NULL);\r
+\r
+  esp->flags |= flags;\r
+  if (esp->cb != NULL) {\r
+    esp->cb(esp);\r
+  }\r
+}\r
+\r
+/**\r
+ * @brief   Add flags to an event source object.\r
+ *\r
+ * @param[in] esp       pointer to the event flags object\r
+ * @param[in] flags     flags to be ORed to the flags mask\r
+ *\r
+ * @iclass\r
+ */\r
+void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags) {\r
+\r
+  osalDbgCheck(esp != NULL);\r
+\r
+  osalSysLock();\r
+  osalEventBroadcastFlagsI(esp, flags);\r
+  osalSysUnlock();\r
+}\r
+\r
+/**\r
+ * @brief   Event callback setup.\r
+ * @note    The callback is invoked from ISR context and can\r
+ *          only invoke I-Class functions. The callback is meant\r
+ *          to wakeup the task that will handle the event by\r
+ *          calling @p osalEventGetAndClearFlagsI().\r
+ * @note    This function is not part of the OSAL API and is provided\r
+ *          exclusively as an example and for convenience.\r
+ *\r
+ * @param[in] esp       pointer to the event flags object\r
+ * @param[in] cb        pointer to the callback function\r
+ * @param[in] param     parameter to be passed to the callback function\r
+ *\r
+ * @api\r
+ */\r
+void osalEventSetCallback(event_source_t *esp,\r
+                          eventcallback_t cb,\r
+                          void *param) {\r
+\r
+  osalDbgCheck(esp != NULL);\r
+\r
+  esp->cb    = cb;\r
+  esp->param = param;\r
+}\r
+\r
+/**\r
+ * @brief   Locks the specified mutex.\r
+ * @post    The mutex is locked and inserted in the per-thread stack of owned\r
+ *          mutexes.\r
+ *\r
+ * @param[in,out] mp    pointer to the @p mutex_t object\r
+ *\r
+ * @api\r
+ */\r
+void osalMutexLock(mutex_t *mp) {\r
+\r
+  osalDbgCheck(mp != NULL);\r
+\r
+  *mp = 1;\r
+}\r
+\r
+/**\r
+ * @brief   Unlocks the specified mutex.\r
+ * @note    The HAL guarantees to release mutex in reverse lock order. The\r
+ *          mutex being unlocked is guaranteed to be the last locked mutex\r
+ *          by the invoking thread.\r
+ *          The implementation can rely on this behavior and eventually\r
+ *          ignore the @p mp parameter which is supplied in order to support\r
+ *          those OSes not supporting a stack of the owned mutexes.\r
+ *\r
+ * @param[in,out] mp    pointer to the @p mutex_t object\r
+ *\r
+ * @api\r
+ */\r
+void osalMutexUnlock(mutex_t *mp) {\r
+\r
+  osalDbgCheck(mp != NULL);\r
+\r
+  *mp = 0;\r
+}\r
+\r
+/** @} */\r
diff --git a/osal.h b/osal.h
new file mode 100644 (file)
index 0000000..30e1592
--- /dev/null
+++ b/osal.h
@@ -0,0 +1,754 @@
+/*\r
+    ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio\r
+\r
+    Licensed under the Apache License, Version 2.0 (the "License");\r
+    you may not use this file except in compliance with the License.\r
+    You may obtain a copy of the License at\r
+\r
+        http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+    Unless required by applicable law or agreed to in writing, software\r
+    distributed under the License is distributed on an "AS IS" BASIS,\r
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+    See the License for the specific language governing permissions and\r
+    limitations under the License.\r
+*/\r
+\r
+/**\r
+ * @file    osal.h\r
+ * @brief   OSAL module header.\r
+ *\r
+ * @addtogroup OSAL\r
+ * @{\r
+ */\r
+\r
+#ifndef OSAL_H\r
+#define OSAL_H\r
+\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+\r
+#include "cmparams.h"\r
+\r
+#include "osalconf.h"\r
+\r
+/*===========================================================================*/\r
+/* Module constants.                                                         */\r
+/*===========================================================================*/\r
+\r
+/**\r
+ * @name    Common constants\r
+ * @{\r
+ */\r
+#if !defined(FALSE) || defined(__DOXYGEN__)\r
+#define FALSE                               0\r
+#endif\r
+\r
+#if !defined(TRUE) || defined(__DOXYGEN__)\r
+#define TRUE                                1\r
+#endif\r
+\r
+#define OSAL_SUCCESS                        false\r
+#define OSAL_FAILED                         true\r
+/** @} */\r
+\r
+/**\r
+ * @name    Messages\r
+ * @{\r
+ */\r
+#define MSG_OK                              (msg_t)0\r
+#define MSG_RESET                           (msg_t)-1\r
+#define MSG_TIMEOUT                         (msg_t)-2\r
+#define MSG_WAIT                            (msg_t)-10\r
+/** @} */\r
+\r
+/**\r
+ * @name    Special time constants\r
+ * @{\r
+ */\r
+#define TIME_IMMEDIATE                      ((sysinterval_t)0)\r
+#define TIME_INFINITE                       ((sysinterval_t)-1)\r
+/** @} */\r
+\r
+/**\r
+ * @name    Systick modes.\r
+ * @{\r
+ */\r
+#define OSAL_ST_MODE_NONE                   0\r
+#define OSAL_ST_MODE_PERIODIC               1\r
+#define OSAL_ST_MODE_FREERUNNING            2\r
+/** @} */\r
+\r
+/**\r
+ * @name    Systick parameters.\r
+ * @{\r
+ */\r
+/**\r
+ * @brief   Size in bits of the @p systick_t type.\r
+ */\r
+#define OSAL_ST_RESOLUTION                  32\r
+\r
+/**\r
+ * @brief   Systick mode required by the underlying OS.\r
+ */\r
+#define OSAL_ST_MODE                        OSAL_ST_MODE_NONE\r
+/** @} */\r
+\r
+/**\r
+ * @name    IRQ-related constants\r
+ * @{\r
+ */\r
+/**\r
+ * @brief   Total priority levels.\r
+ */\r
+#define OSAL_IRQ_PRIORITY_LEVELS            (1U << CORTEX_PRIORITY_BITS)\r
+\r
+/**\r
+ * @brief   Highest IRQ priority for HAL drivers.\r
+ */\r
+#if (CORTEX_MODEL == 0) || defined(__DOXYGEN__)\r
+#define OSAL_IRQ_MAXIMUM_PRIORITY           0\r
+#else\r
+#define OSAL_IRQ_MAXIMUM_PRIORITY           1\r
+#endif\r
+\r
+/**\r
+ * @brief   Converts from numeric priority to BASEPRI register value.\r
+ */\r
+#define OSAL_BASEPRI(priority)              ((priority) << (8U - CORTEX_PRIORITY_BITS))\r
+/** @} */\r
+\r
+/*===========================================================================*/\r
+/* Module pre-compile time settings.                                         */\r
+/*===========================================================================*/\r
+\r
+/**\r
+ * @brief   Frequency in Hertz of the system tick.\r
+ */\r
+#if !defined(OSAL_ST_FREQUENCY) || defined(__DOXYGEN__)\r
+#define OSAL_ST_FREQUENCY                   1000\r
+#endif\r
+\r
+/**\r
+ * @brief   Enables OSAL assertions.\r
+ */\r
+#if !defined(OSAL_DBG_ENABLE_ASSERTS) || defined(__DOXYGEN__)\r
+#define OSAL_DBG_ENABLE_ASSERTS             FALSE\r
+#endif\r
+\r
+/**\r
+ * @brief   Enables OSAL functions parameters checks.\r
+ */\r
+#if !defined(OSAL_DBG_ENABLE_CHECKS) || defined(__DOXYGEN__)\r
+#define OSAL_DBG_ENABLE_CHECKS              FALSE\r
+#endif\r
+\r
+/**\r
+ * @brief   OSAL initialization hook.\r
+ */\r
+#if !defined(OSAL_INIT_HOOK) || defined(__DOXYGEN__)\r
+#define OSAL_INIT_HOOK()\r
+#endif\r
+\r
+/**\r
+ * @brief   Idle loop hook macro.\r
+ */\r
+#if !defined(OSAL_IDLE_HOOK) || defined(__DOXYGEN__)\r
+#define OSAL_IDLE_HOOK()\r
+#endif\r
+\r
+/*===========================================================================*/\r
+/* Derived constants and error checks.                                       */\r
+/*===========================================================================*/\r
+\r
+/*===========================================================================*/\r
+/* Module data structures and types.                                         */\r
+/*===========================================================================*/\r
+\r
+/**\r
+ * @brief   Type of a system status word.\r
+ */\r
+typedef uint32_t syssts_t;\r
+\r
+/**\r
+ * @brief   Type of a message.\r
+ */\r
+typedef int32_t msg_t;\r
+\r
+/**\r
+ * @brief   Type of system time counter.\r
+ */\r
+typedef uint32_t systime_t;\r
+\r
+/**\r
+ * @brief   Type of system time interval.\r
+ */\r
+typedef uint32_t sysinterval_t;\r
+\r
+/**\r
+ * @brief   Type of realtime counter.\r
+ */\r
+typedef uint32_t rtcnt_t;\r
+\r
+/**\r
+ * @brief   Type of a thread.\r
+ * @note    The content of this structure is not part of the API and should\r
+ *          not be relied upon. Implementers may define this structure in\r
+ *          an entirely different way.\r
+ */\r
+typedef struct {\r
+  volatile msg_t        message;\r
+} thread_t;\r
+\r
+/**\r
+ * @brief   Type of a thread reference.\r
+ */\r
+typedef thread_t * thread_reference_t;\r
+\r
+/**\r
+ * @brief   Type of an event flags mask.\r
+ */\r
+typedef uint32_t eventflags_t;\r
+\r
+/**\r
+ * @brief   Type of an event flags object.\r
+ * @note    The content of this structure is not part of the API and should\r
+ *          not be relied upon. Implementers may define this structure in\r
+ *          an entirely different way.\r
+ * @note    Retrieval and clearing of the flags are not defined in this\r
+ *          API and are implementation-dependent.\r
+ */\r
+typedef struct event_source event_source_t;\r
+\r
+/**\r
+ * @brief   Type of an event source callback.\r
+ * @note    This type is not part of the OSAL API and is provided\r
+ *          exclusively as an example and for convenience.\r
+ */\r
+typedef void (*eventcallback_t)(event_source_t *esp);\r
+\r
+/**\r
+ * @brief   Events source object.\r
+ * @note    The content of this structure is not part of the API and should\r
+ *          not be relied upon. Implementers may define this structure in\r
+ *          an entirely different way.\r
+ * @note    Retrieval and clearing of the flags are not defined in this\r
+ *          API and are implementation-dependent.\r
+ */\r
+struct event_source {\r
+  volatile eventflags_t flags;      /**< @brief Stored event flags.         */\r
+  eventcallback_t       cb;         /**< @brief Event source callback.      */\r
+  void                  *param;     /**< @brief User defined field.         */\r
+};\r
+\r
+/**\r
+ * @brief   Type of a mutex.\r
+ * @note    If the OS does not support mutexes or there is no OS then them\r
+ *          mechanism can be simulated.\r
+ */\r
+typedef uint32_t mutex_t;\r
+\r
+/**\r
+ * @brief   Type of a thread queue.\r
+ * @details A thread queue is a queue of sleeping threads, queued threads\r
+ *          can be dequeued one at time or all together.\r
+ * @note    If the OSAL is implemented on a bare metal machine without RTOS\r
+ *          then the queue can be implemented as a single thread reference.\r
+ */\r
+typedef struct {\r
+  thread_reference_t    tr;\r
+} threads_queue_t;\r
+\r
+/*===========================================================================*/\r
+/* Module macros.                                                            */\r
+/*===========================================================================*/\r
+\r
+/**\r
+ * @name    Debug related macros\r
+ * @{\r
+ */\r
+/**\r
+ * @brief   Condition assertion.\r
+ * @details If the condition check fails then the OSAL panics with a\r
+ *          message and halts.\r
+ * @note    The condition is tested only if the @p OSAL_ENABLE_ASSERTIONS\r
+ *          switch is enabled.\r
+ * @note    The remark string is not currently used except for putting a\r
+ *          comment in the code about the assertion.\r
+ *\r
+ * @param[in] c         the condition to be verified to be true\r
+ * @param[in] remark    a remark string\r
+ *\r
+ * @api\r
+ */\r
+#define osalDbgAssert(c, remark) do {                                       \\r
+  /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/       \\r
+  if (OSAL_DBG_ENABLE_ASSERTS != FALSE) {                                   \\r
+    if (!(c)) {                                                             \\r
+  /*lint -restore*/                                                         \\r
+      osalSysHalt(__func__);                                                \\r
+    }                                                                       \\r
+  }                                                                         \\r
+} while (false)\r
+\r
+/**\r
+ * @brief   Function parameters check.\r
+ * @details If the condition check fails then the OSAL panics and halts.\r
+ * @note    The condition is tested only if the @p OSAL_ENABLE_CHECKS switch\r
+ *          is enabled.\r
+ *\r
+ * @param[in] c         the condition to be verified to be true\r
+ *\r
+ * @api\r
+ */\r
+#define osalDbgCheck(c) do {                                                \\r
+  /*lint -save -e506 -e774 [2.1, 14.3] Can be a constant by design.*/       \\r
+  if (OSAL_DBG_ENABLE_CHECKS != FALSE) {                                    \\r
+    if (!(c)) {                                                             \\r
+  /*lint -restore*/                                                         \\r
+      osalSysHalt(__func__);                                                \\r
+    }                                                                       \\r
+  }                                                                         \\r
+} while (false)\r
+\r
+/**\r
+ * @brief   I-Class state check.\r
+ * @note    Implementation is optional.\r
+ */\r
+#define osalDbgCheckClassI()\r
+\r
+/**\r
+ * @brief   S-Class state check.\r
+ * @note    Implementation is optional.\r
+ */\r
+#define osalDbgCheckClassS()\r
+/** @} */\r
+\r
+/**\r
+ * @name    IRQ service routines wrappers\r
+ * @{\r
+ */\r
+/**\r
+ * @brief   Priority level verification macro.\r
+ */\r
+#define OSAL_IRQ_IS_VALID_PRIORITY(n)                                       \\r
+  (((n) >= OSAL_IRQ_MAXIMUM_PRIORITY) && ((n) < OSAL_IRQ_PRIORITY_LEVELS))\r
+\r
+/**\r
+ * @brief   IRQ prologue code.\r
+ * @details This macro must be inserted at the start of all IRQ handlers.\r
+ */\r
+#define OSAL_IRQ_PROLOGUE()\r
+\r
+/**\r
+ * @brief   IRQ epilogue code.\r
+ * @details This macro must be inserted at the end of all IRQ handlers.\r
+ */\r
+#define OSAL_IRQ_EPILOGUE()\r
+\r
+/**\r
+ * @brief   IRQ handler function declaration.\r
+ * @details This macro hides the details of an ISR function declaration.\r
+ *\r
+ * @param[in] id        a vector name as defined in @p vectors.s\r
+ */\r
+#define OSAL_IRQ_HANDLER(id) void id(void)\r
+/** @} */\r
+\r
+/**\r
+ * @name    Time conversion utilities\r
+ * @{\r
+ */\r
+/**\r
+ * @brief   Seconds to system ticks.\r
+ * @details Converts from seconds to system ticks number.\r
+ * @note    The result is rounded upward to the next tick boundary.\r
+ *\r
+ * @param[in] secs      number of seconds\r
+ * @return              The number of ticks.\r
+ *\r
+ * @api\r
+ */\r
+#define OSAL_S2I(secs)                                                      \\r
+  ((sysinterval_t)((uint32_t)(secs) * (uint32_t)OSAL_ST_FREQUENCY))\r
+\r
+/**\r
+ * @brief   Milliseconds to system ticks.\r
+ * @details Converts from milliseconds to system ticks number.\r
+ * @note    The result is rounded upward to the next tick boundary.\r
+ *\r
+ * @param[in] msecs     number of milliseconds\r
+ * @return              The number of ticks.\r
+ *\r
+ * @api\r
+ */\r
+#define OSAL_MS2I(msecs)                                                    \\r
+  ((sysinterval_t)((((((uint32_t)(msecs)) *                                 \\r
+                  ((uint32_t)OSAL_ST_FREQUENCY)) - 1UL) / 1000UL) + 1UL))\r
+\r
+/**\r
+ * @brief   Microseconds to system ticks.\r
+ * @details Converts from microseconds to system ticks number.\r
+ * @note    The result is rounded upward to the next tick boundary.\r
+ *\r
+ * @param[in] usecs     number of microseconds\r
+ * @return              The number of ticks.\r
+ *\r
+ * @api\r
+ */\r
+#define OSAL_US2I(usecs)                                                    \\r
+  ((sysinterval_t)((((((uint32_t)(usecs)) *                                 \\r
+                  ((uint32_t)OSAL_ST_FREQUENCY)) - 1UL) / 1000000UL) + 1UL))\r
+/** @} */\r
+\r
+/**\r
+ * @name    Time conversion utilities for the realtime counter\r
+ * @{\r
+ */\r
+/**\r
+ * @brief   Seconds to realtime counter.\r
+ * @details Converts from seconds to realtime counter cycles.\r
+ * @note    The macro assumes that @p freq >= @p 1.\r
+ *\r
+ * @param[in] freq      clock frequency, in Hz, of the realtime counter\r
+ * @param[in] sec       number of seconds\r
+ * @return              The number of cycles.\r
+ *\r
+ * @api\r
+ */\r
+#define OSAL_S2RTC(freq, sec) ((freq) * (sec))\r
+\r
+/**\r
+ * @brief   Milliseconds to realtime counter.\r
+ * @details Converts from milliseconds to realtime counter cycles.\r
+ * @note    The result is rounded upward to the next millisecond boundary.\r
+ * @note    The macro assumes that @p freq >= @p 1000.\r
+ *\r
+ * @param[in] freq      clock frequency, in Hz, of the realtime counter\r
+ * @param[in] msec      number of milliseconds\r
+ * @return              The number of cycles.\r
+ *\r
+ * @api\r
+ */\r
+#define OSAL_MS2RTC(freq, msec) (rtcnt_t)((((freq) + 999UL) / 1000UL) * (msec))\r
+\r
+/**\r
+ * @brief   Microseconds to realtime counter.\r
+ * @details Converts from microseconds to realtime counter cycles.\r
+ * @note    The result is rounded upward to the next microsecond boundary.\r
+ * @note    The macro assumes that @p freq >= @p 1000000.\r
+ *\r
+ * @param[in] freq      clock frequency, in Hz, of the realtime counter\r
+ * @param[in] usec      number of microseconds\r
+ * @return              The number of cycles.\r
+ *\r
+ * @api\r
+ */\r
+#define OSAL_US2RTC(freq, usec) (rtcnt_t)((((freq) + 999999UL) / 1000000UL) * (usec))\r
+/** @} */\r
+\r
+/**\r
+ * @name    Sleep macros using absolute time\r
+ * @{\r
+ */\r
+/**\r
+ * @brief   Delays the invoking thread for the specified number of seconds.\r
+ * @note    The specified time is rounded up to a value allowed by the real\r
+ *          system tick clock.\r
+ * @note    The maximum specifiable value is implementation dependent.\r
+ *\r
+ * @param[in] secs      time in seconds, must be different from zero\r
+ *\r
+ * @api\r
+ */\r
+#define osalThreadSleepSeconds(secs) osalThreadSleep(OSAL_S2I(secs))\r
+\r
+/**\r
+ * @brief   Delays the invoking thread for the specified number of\r
+ *          milliseconds.\r
+ * @note    The specified time is rounded up to a value allowed by the real\r
+ *          system tick clock.\r
+ * @note    The maximum specifiable value is implementation dependent.\r
+ *\r
+ * @param[in] msecs     time in milliseconds, must be different from zero\r
+ *\r
+ * @api\r
+ */\r
+#define osalThreadSleepMilliseconds(msecs) osalThreadSleep(OSAL_MS2I(msecs))\r
+\r
+/**\r
+ * @brief   Delays the invoking thread for the specified number of\r
+ *          microseconds.\r
+ * @note    The specified time is rounded up to a value allowed by the real\r
+ *          system tick clock.\r
+ * @note    The maximum specifiable value is implementation dependent.\r
+ *\r
+ * @param[in] usecs     time in microseconds, must be different from zero\r
+ *\r
+ * @api\r
+ */\r
+#define osalThreadSleepMicroseconds(usecs) osalThreadSleep(OSAL_US2I(usecs))\r
+/** @} */\r
+\r
+/*===========================================================================*/\r
+/* External declarations.                                                    */\r
+/*===========================================================================*/\r
+\r
+extern const char *osal_halt_msg;\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+  void osalInit(void);\r
+  void osalSysHalt(const char *reason);\r
+  void osalSysPolledDelayX(rtcnt_t cycles);\r
+  void osalOsTimerHandlerI(void);\r
+  void osalOsRescheduleS(void);\r
+  systime_t osalOsGetSystemTimeX(void);\r
+  void osalThreadSleepS(sysinterval_t time);\r
+  void osalThreadSleep(sysinterval_t time);\r
+  msg_t osalThreadSuspendS(thread_reference_t *trp);\r
+  msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp, sysinterval_t timeout);\r
+  void osalThreadResumeI(thread_reference_t *trp, msg_t msg);\r
+  void osalThreadResumeS(thread_reference_t *trp, msg_t msg);\r
+  msg_t osalThreadEnqueueTimeoutS(threads_queue_t *tqp, sysinterval_t timeout);\r
+  void osalThreadDequeueNextI(threads_queue_t *tqp, msg_t msg);\r
+  void osalThreadDequeueAllI(threads_queue_t *tqp, msg_t msg);\r
+  void osalEventBroadcastFlagsI(event_source_t *esp, eventflags_t flags);\r
+  void osalEventBroadcastFlags(event_source_t *esp, eventflags_t flags);\r
+  void osalEventSetCallback(event_source_t *esp,\r
+                            eventcallback_t cb,\r
+                            void *param);\r
+  void osalMutexLock(mutex_t *mp);\r
+  void osalMutexUnlock(mutex_t *mp);\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+/*===========================================================================*/\r
+/* Module inline functions.                                                  */\r
+/*===========================================================================*/\r
+\r
+/**\r
+ * @brief   Disables interrupts globally.\r
+ *\r
+ * @special\r
+ */\r
+static inline void osalSysDisable(void) {\r
+\r
+  __disable_irq();\r
+}\r
+\r
+/**\r
+ * @brief   Enables interrupts globally.\r
+ *\r
+ * @special\r
+ */\r
+static inline void osalSysEnable(void) {\r
+\r
+  __enable_irq();\r
+}\r
+\r
+/**\r
+ * @brief   Enters a critical zone from thread context.\r
+ * @note    This function cannot be used for reentrant critical zones.\r
+ *\r
+ * @special\r
+ */\r
+static inline void osalSysLock(void) {\r
+\r
+#if CORTEX_MODEL == 0\r
+  __disable_irq();\r
+#else\r
+  __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY));\r
+#endif\r
+}\r
+\r
+/**\r
+ * @brief   Leaves a critical zone from thread context.\r
+ * @note    This function cannot be used for reentrant critical zones.\r
+ *\r
+ * @special\r
+ */\r
+static inline void osalSysUnlock(void) {\r
+\r
+#if CORTEX_MODEL == 0\r
+  __enable_irq();\r
+#else\r
+  __set_BASEPRI(0);\r
+#endif\r
+}\r
+\r
+/**\r
+ * @brief   Enters a critical zone from ISR context.\r
+ * @note    This function cannot be used for reentrant critical zones.\r
+ *\r
+ * @special\r
+ */\r
+static inline void osalSysLockFromISR(void) {\r
+\r
+#if CORTEX_MODEL == 0\r
+  __disable_irq();\r
+#else\r
+  __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY));\r
+#endif\r
+}\r
+\r
+/**\r
+ * @brief   Leaves a critical zone from ISR context.\r
+ * @note    This function cannot be used for reentrant critical zones.\r
+ *\r
+ * @special\r
+ */\r
+static inline void osalSysUnlockFromISR(void) {\r
+\r
+#if CORTEX_MODEL == 0\r
+  __enable_irq();\r
+#else\r
+  __set_BASEPRI(0);\r
+#endif\r
+}\r
+\r
+/**\r
+ * @brief   Returns the execution status and enters a critical zone.\r
+ * @details This functions enters into a critical zone and can be called\r
+ *          from any context. Because its flexibility it is less efficient\r
+ *          than @p chSysLock() which is preferable when the calling context\r
+ *          is known.\r
+ * @post    The system is in a critical zone.\r
+ *\r
+ * @return              The previous system status, the encoding of this\r
+ *                      status word is architecture-dependent and opaque.\r
+ *\r
+ * @xclass\r
+ */\r
+static inline syssts_t osalSysGetStatusAndLockX(void) {\r
+  syssts_t sts;\r
+\r
+#if CORTEX_MODEL == 0\r
+  sts = (syssts_t)__get_PRIMASK();\r
+  __disable_irq();\r
+#else\r
+  sts = (syssts_t)__get_BASEPRI();\r
+  __set_BASEPRI(OSAL_BASEPRI(OSAL_IRQ_MAXIMUM_PRIORITY));\r
+#endif\r
+  return sts;\r
+}\r
+\r
+/**\r
+ * @brief   Restores the specified execution status and leaves a critical zone.\r
+ * @note    A call to @p chSchRescheduleS() is automatically performed\r
+ *          if exiting the critical zone and if not in ISR context.\r
+ *\r
+ * @param[in] sts       the system status to be restored.\r
+ *\r
+ * @xclass\r
+ */\r
+static inline void osalSysRestoreStatusX(syssts_t sts) {\r
+\r
+#if CORTEX_MODEL == 0\r
+  if ((sts & (syssts_t)1) == (syssts_t)0) {\r
+    __enable_irq();\r
+  }\r
+#else\r
+  __set_BASEPRI(sts);\r
+#endif\r
+}\r
+\r
+/**\r
+ * @brief   Adds an interval to a system time returning a system time.\r
+ *\r
+ * @param[in] systime   base system time\r
+ * @param[in] interval  interval to be added\r
+ * @return              The new system time.\r
+ *\r
+ * @xclass\r
+ */\r
+static inline systime_t osalTimeAddX(systime_t systime,\r
+                                     sysinterval_t interval) {\r
+\r
+  return systime + (systime_t)interval;\r
+}\r
+\r
+/**\r
+ * @brief   Subtracts two system times returning an interval.\r
+ *\r
+ * @param[in] start     first system time\r
+ * @param[in] end       second system time\r
+ * @return              The interval representing the time difference.\r
+ *\r
+ * @xclass\r
+ */\r
+static inline sysinterval_t osalTimeDiffX(systime_t start, systime_t end) {\r
+\r
+  return (sysinterval_t)((systime_t)(end - start));\r
+}\r
+\r
+/**\r
+ * @brief   Checks if the specified time is within the specified time window.\r
+ * @note    When start==end then the function returns always false because the\r
+ *          time window has zero size.\r
+ * @note    This function can be called from any context.\r
+ *\r
+ * @param[in] time      the time to be verified\r
+ * @param[in] start     the start of the time window (inclusive)\r
+ * @param[in] end       the end of the time window (non inclusive)\r
+ * @retval true         current time within the specified time window.\r
+ * @retval false        current time not within the specified time window.\r
+ *\r
+ * @xclass\r
+ */\r
+static inline bool osalTimeIsInRangeX(systime_t time,\r
+                                      systime_t start,\r
+                                      systime_t end) {\r
+\r
+  return (bool)((systime_t)((systime_t)time - (systime_t)start) <\r
+                (systime_t)((systime_t)end - (systime_t)start));\r
+}\r
+\r
+/**\r
+ * @brief   Initializes a threads queue object.\r
+ *\r
+ * @param[out] tqp      pointer to the threads queue object\r
+ *\r
+ * @init\r
+ */\r
+static inline void osalThreadQueueObjectInit(threads_queue_t *tqp) {\r
+\r
+  osalDbgCheck(tqp != NULL);\r
+}\r
+\r
+/**\r
+ * @brief   Initializes an event source object.\r
+ *\r
+ * @param[out] esp      pointer to the event source object\r
+ *\r
+ * @init\r
+ */\r
+static inline void osalEventObjectInit(event_source_t *esp) {\r
+\r
+  osalDbgCheck(esp != NULL);\r
+\r
+  esp->flags = (eventflags_t)0;\r
+  esp->cb    = NULL;\r
+  esp->param = NULL;\r
+}\r
+\r
+/**\r
+ * @brief   Initializes s @p mutex_t object.\r
+ *\r
+ * @param[out] mp       pointer to the @p mutex_t object\r
+ *\r
+ * @init\r
+ */\r
+static inline void osalMutexObjectInit(mutex_t *mp) {\r
+\r
+  osalDbgCheck(mp != NULL);\r
+\r
+  *mp = 0;\r
+}\r
+\r
+#endif /* OSAL_H */\r
+\r
+/** @} */\r