aboutsummaryrefslogtreecommitdiffstats
path: root/os/common/abstractions/cmsis_os
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2016-02-23 09:31:25 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2016-02-23 09:31:25 +0000
commit430facf5652c09fee1d77ebad2fb1cca641de544 (patch)
tree1491d02fb14ef5bbd21ea1d464658a0332802d32 /os/common/abstractions/cmsis_os
parent2240934707a4e434c76329ad3051a6ba5c09e299 (diff)
downloadChibiOS-430facf5652c09fee1d77ebad2fb1cca641de544.tar.gz
ChibiOS-430facf5652c09fee1d77ebad2fb1cca641de544.tar.bz2
ChibiOS-430facf5652c09fee1d77ebad2fb1cca641de544.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8931 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/common/abstractions/cmsis_os')
-rw-r--r--os/common/abstractions/cmsis_os/cmsis_os.c555
-rw-r--r--os/common/abstractions/cmsis_os/cmsis_os.h522
-rw-r--r--os/common/abstractions/cmsis_os/cmsis_os.mk4
3 files changed, 1081 insertions, 0 deletions
diff --git a/os/common/abstractions/cmsis_os/cmsis_os.c b/os/common/abstractions/cmsis_os/cmsis_os.c
new file mode 100644
index 000000000..04bebeb1d
--- /dev/null
+++ b/os/common/abstractions/cmsis_os/cmsis_os.c
@@ -0,0 +1,555 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
+
+ This file is part of ChibiOS.
+
+ ChibiOS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ Concepts and parts of this file have been contributed by Andre R.
+ */
+
+/**
+ * @file cmsis_os.c
+ * @brief CMSIS RTOS module code.
+ *
+ * @addtogroup CMSIS_OS
+ * @{
+ */
+
+#include "cmsis_os.h"
+#include <string.h>
+
+/*===========================================================================*/
+/* Module local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module exported variables. */
+/*===========================================================================*/
+
+int32_t cmsis_os_started;
+
+/*===========================================================================*/
+/* Module local types. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Module local variables. */
+/*===========================================================================*/
+
+static memory_pool_t sempool;
+static semaphore_t semaphores[CMSIS_CFG_NUM_SEMAPHORES];
+
+static memory_pool_t timpool;
+static struct os_timer_cb timers[CMSIS_CFG_NUM_TIMERS];
+
+/*===========================================================================*/
+/* Module local functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Virtual timers common callback.
+ */
+static void timer_cb(void const *arg) {
+
+ osTimerId timer_id = (osTimerId)arg;
+ timer_id->ptimer(timer_id->argument);
+ if (timer_id->type == osTimerPeriodic) {
+ chSysLockFromISR();
+ chVTDoSetI(&timer_id->vt, MS2ST(timer_id->millisec),
+ (vtfunc_t)timer_cb, timer_id);
+ chSysUnlockFromISR();
+ }
+}
+
+/*===========================================================================*/
+/* Module exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Kernel initialization.
+ */
+osStatus osKernelInitialize(void) {
+
+ cmsis_os_started = 0;
+
+ chSysInit();
+ chThdSetPriority(HIGHPRIO);
+
+ chPoolObjectInit(&sempool, sizeof(semaphore_t), chCoreAllocAligned);
+ chPoolLoadArray(&sempool, semaphores, CMSIS_CFG_NUM_SEMAPHORES);
+
+ chPoolObjectInit(&timpool, sizeof(virtual_timer_t), chCoreAllocAligned);
+ chPoolLoadArray(&timpool, timers, CMSIS_CFG_NUM_TIMERS);
+
+ return osOK;
+}
+
+/**
+ * @brief Kernel start.
+ */
+osStatus osKernelStart(void) {
+
+ cmsis_os_started = 1;
+
+ chThdSetPriority(NORMALPRIO);
+
+ return osOK;
+}
+
+/**
+ * @brief Creates a thread.
+ */
+osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument) {
+ size_t size;
+
+ size = thread_def->stacksize == 0 ? CMSIS_CFG_DEFAULT_STACK :
+ thread_def->stacksize;
+ return (osThreadId)chThdCreateFromHeap(0,
+ THD_WORKING_AREA_SIZE(size),
+ thread_def->name,
+ NORMALPRIO+thread_def->tpriority,
+ (tfunc_t)thread_def->pthread,
+ argument);
+}
+
+/**
+ * @brief Thread termination.
+ * @note The thread is not really terminated but asked to terminate which
+ * is not compliant.
+ */
+osStatus osThreadTerminate(osThreadId thread_id) {
+
+ if (thread_id == osThreadGetId()) {
+ /* Note, no memory will be recovered unless a cleaner thread is
+ implemented using the registry.*/
+ chThdExit(0);
+ }
+ chEvtSignal((thread_t *)thread_id, CH_EVENT_TERMINATE);
+ chThdWait((thread_t *)thread_id);
+
+ return osOK;
+}
+
+/**
+ * @brief Change thread priority.
+ * @note This can interfere with the priority inheritance mechanism.
+ */
+osStatus osThreadSetPriority(osThreadId thread_id, osPriority newprio) {
+ osPriority oldprio;
+ thread_t * tp = (thread_t *)thread_id;
+
+ chSysLock();
+
+ /* Changing priority.*/
+#if CH_CFG_USE_MUTEXES
+ oldprio = (osPriority)tp->realprio;
+ if ((tp->prio == tp->realprio) || ((tprio_t)newprio > tp->prio))
+ tp->prio = (tprio_t)newprio;
+ tp->realprio = (tprio_t)newprio;
+#else
+ oldprio = tp->prio;
+ tp->prio = (tprio_t)newprio;
+#endif
+
+ /* The following states need priority queues reordering.*/
+ switch (tp->state) {
+#if CH_CFG_USE_MUTEXES | \
+ CH_CFG_USE_CONDVARS | \
+ (CH_CFG_USE_SEMAPHORES && CH_CFG_USE_SEMAPHORES_PRIORITY) | \
+ (CH_CFG_USE_MESSAGES && CH_CFG_USE_MESSAGES_PRIORITY)
+#if CH_CFG_USE_MUTEXES
+ case CH_STATE_WTMTX:
+#endif
+#if CH_CFG_USE_CONDVARS
+ case CH_STATE_WTCOND:
+#endif
+#if CH_CFG_USE_SEMAPHORES && CH_CFG_USE_SEMAPHORES_PRIORITY
+ case CH_STATE_WTSEM:
+#endif
+#if CH_CFG_USE_MESSAGES && CH_CFG_USE_MESSAGES_PRIORITY
+ case CH_STATE_SNDMSGQ:
+#endif
+ /* Re-enqueues tp with its new priority on the queue.*/
+ queue_prio_insert(queue_dequeue(tp),
+ (threads_queue_t *)tp->u.wtobjp);
+ break;
+#endif
+ case CH_STATE_READY:
+#if CH_DBG_ENABLE_ASSERTS
+ /* Prevents an assertion in chSchReadyI().*/
+ tp->state = CH_STATE_CURRENT;
+#endif
+ /* Re-enqueues tp with its new priority on the ready list.*/
+ chSchReadyI(queue_dequeue(tp));
+ break;
+ }
+
+ /* Rescheduling.*/
+ chSchRescheduleS();
+
+ chSysUnlock();
+
+ return oldprio;
+}
+
+/**
+ * @brief Create a timer.
+ */
+osTimerId osTimerCreate(const osTimerDef_t *timer_def,
+ os_timer_type type,
+ void *argument) {
+
+ osTimerId timer = chPoolAlloc(&timpool);
+ chVTObjectInit(&timer->vt);
+ timer->ptimer = timer_def->ptimer;
+ timer->type = type;
+ timer->argument = argument;
+ return timer;
+}
+
+/**
+ * @brief Start a timer.
+ */
+osStatus osTimerStart(osTimerId timer_id, uint32_t millisec) {
+
+ if ((millisec == 0) || (millisec == osWaitForever))
+ return osErrorValue;
+
+ timer_id->millisec = millisec;
+ chVTSet(&timer_id->vt, MS2ST(millisec), (vtfunc_t)timer_cb, timer_id);
+
+ return osOK;
+}
+
+/**
+ * @brief Stop a timer.
+ */
+osStatus osTimerStop(osTimerId timer_id) {
+
+ chVTReset(&timer_id->vt);
+
+ return osOK;
+}
+
+/**
+ * @brief Delete a timer.
+ */
+osStatus osTimerDelete(osTimerId timer_id) {
+
+ chVTReset(&timer_id->vt);
+ chPoolFree(&timpool, (void *)timer_id);
+
+ return osOK;
+}
+
+/**
+ * @brief Send signals.
+ */
+int32_t osSignalSet(osThreadId thread_id, int32_t signals) {
+ int32_t oldsignals;
+
+ syssts_t sts = chSysGetStatusAndLockX();
+ oldsignals = (int32_t)thread_id->epending;
+ chEvtSignalI((thread_t *)thread_id, (eventmask_t)signals);
+ chSysRestoreStatusX(sts);
+
+ return oldsignals;
+}
+
+/**
+ * @brief Clear signals.
+ */
+int32_t osSignalClear(osThreadId thread_id, int32_t signals) {
+ eventmask_t m;
+
+ chSysLock();
+
+ m = thread_id->epending & (eventmask_t)signals;
+ thread_id->epending &= ~(eventmask_t)signals;
+
+ chSysUnlock();
+
+ return (int32_t)m;
+}
+
+/**
+ * @brief Wait for signals.
+ */
+osEvent osSignalWait(int32_t signals, uint32_t millisec) {
+ osEvent event;
+ systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ?
+ TIME_INFINITE : MS2ST(millisec);
+
+ if (signals == 0)
+ event.value.signals = (uint32_t)chEvtWaitAnyTimeout(ALL_EVENTS, timeout);
+ else
+ event.value.signals = (uint32_t)chEvtWaitAllTimeout((eventmask_t)signals,
+ timeout);
+
+ /* Type of event.*/
+ if (event.value.signals == 0)
+ event.status = osEventTimeout;
+ else
+ event.status = osEventSignal;
+
+ return event;
+}
+
+/**
+ * @brief Create a semaphore.
+ * @note @p semaphore_def is not used.
+ * @note Can involve memory allocation.
+ */
+osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def,
+ int32_t count) {
+
+ (void)semaphore_def;
+
+ semaphore_t *sem = chPoolAlloc(&sempool);
+ chSemObjectInit(sem, (cnt_t)count);
+ return sem;
+}
+
+/**
+ * @brief Wait on a semaphore.
+ */
+int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec) {
+ systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ?
+ TIME_INFINITE : MS2ST(millisec);
+
+ msg_t msg = chSemWaitTimeout((semaphore_t *)semaphore_id, timeout);
+ switch (msg) {
+ case MSG_OK:
+ return osOK;
+ case MSG_TIMEOUT:
+ return osErrorTimeoutResource;
+ }
+ return osErrorResource;
+}
+
+/**
+ * @brief Release a semaphore.
+ */
+osStatus osSemaphoreRelease(osSemaphoreId semaphore_id) {
+
+ syssts_t sts = chSysGetStatusAndLockX();
+ chSemSignalI((semaphore_t *)semaphore_id);
+ chSysRestoreStatusX(sts);
+
+ return osOK;
+}
+
+/**
+ * @brief Deletes a semaphore.
+ * @note After deletion there could be references in the system to a
+ * non-existent semaphore.
+ */
+osStatus osSemaphoreDelete(osSemaphoreId semaphore_id) {
+
+ chSemReset((semaphore_t *)semaphore_id, 0);
+ chPoolFree(&sempool, (void *)semaphore_id);
+
+ return osOK;
+}
+
+/**
+ * @brief Create a mutex.
+ * @note @p mutex_def is not used.
+ * @note Can involve memory allocation.
+ */
+osMutexId osMutexCreate(const osMutexDef_t *mutex_def) {
+
+ (void)mutex_def;
+
+ binary_semaphore_t *mtx = chPoolAlloc(&sempool);
+ chBSemObjectInit(mtx, false);
+ return mtx;
+}
+
+/**
+ * @brief Wait on a mutex.
+ */
+osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec) {
+ systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ?
+ TIME_INFINITE : MS2ST(millisec);
+
+ msg_t msg = chBSemWaitTimeout((binary_semaphore_t *)mutex_id, timeout);
+ switch (msg) {
+ case MSG_OK:
+ return osOK;
+ case MSG_TIMEOUT:
+ return osErrorTimeoutResource;
+ }
+ return osErrorResource;
+}
+
+/**
+ * @brief Release a mutex.
+ */
+osStatus osMutexRelease(osMutexId mutex_id) {
+
+ syssts_t sts = chSysGetStatusAndLockX();
+ chBSemSignalI((binary_semaphore_t *)mutex_id);
+ chSysRestoreStatusX(sts);
+
+ return osOK;
+}
+
+/**
+ * @brief Deletes a mutex.
+ * @note After deletion there could be references in the system to a
+ * non-existent semaphore.
+ */
+osStatus osMutexDelete(osMutexId mutex_id) {
+
+ chSemReset((semaphore_t *)mutex_id, 0);
+ chPoolFree(&sempool, (void *)mutex_id);
+
+ return osOK;
+}
+
+/**
+ * @brief Create a memory pool.
+ * @note The pool is not really created because it is allocated statically,
+ * this function just re-initializes it.
+ */
+osPoolId osPoolCreate(const osPoolDef_t *pool_def) {
+
+ chPoolObjectInit(pool_def->pool, (size_t)pool_def->item_sz, NULL);
+ chPoolLoadArray(pool_def->pool, pool_def->items, (size_t)pool_def->pool_sz);
+
+ return (osPoolId)pool_def->pool;
+}
+
+/**
+ * @brief Allocate an object.
+ */
+void *osPoolAlloc(osPoolId pool_id) {
+ void *object;
+
+ syssts_t sts = chSysGetStatusAndLockX();
+ object = chPoolAllocI((memory_pool_t *)pool_id);
+ chSysRestoreStatusX(sts);
+
+ return object;
+}
+
+/**
+ * @brief Allocate an object clearing it.
+ */
+void *osPoolCAlloc(osPoolId pool_id) {
+ void *object;
+
+ object = chPoolAllocI((memory_pool_t *)pool_id);
+ memset(object, 0, pool_id->object_size);
+ return object;
+}
+
+/**
+ * @brief Free an object.
+ */
+osStatus osPoolFree(osPoolId pool_id, void *block) {
+
+ syssts_t sts = chSysGetStatusAndLockX();
+ chPoolFreeI((memory_pool_t *)pool_id, block);
+ chSysRestoreStatusX(sts);
+
+ return osOK;
+}
+
+/**
+ * @brief Create a message queue.
+ * @note The queue is not really created because it is allocated statically,
+ * this function just re-initializes it.
+ */
+osMessageQId osMessageCreate(const osMessageQDef_t *queue_def,
+ osThreadId thread_id) {
+
+ /* Ignoring this parameter for now.*/
+ (void)thread_id;
+
+ if (queue_def->item_sz > sizeof (msg_t))
+ return NULL;
+
+ chMBObjectInit(queue_def->mailbox,
+ queue_def->items,
+ (size_t)queue_def->queue_sz);
+
+ return (osMessageQId) queue_def->mailbox;
+}
+
+/**
+ * @brief Put a message in the queue.
+ */
+osStatus osMessagePut(osMessageQId queue_id,
+ uint32_t info,
+ uint32_t millisec) {
+ msg_t msg;
+ systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ?
+ TIME_INFINITE : MS2ST(millisec);
+
+ if (port_is_isr_context()) {
+
+ /* Waiting makes no sense in ISRs so any value except "immediate"
+ makes no sense.*/
+ if (millisec != 0)
+ return osErrorValue;
+
+ chSysLockFromISR();
+ msg = chMBPostI((mailbox_t *)queue_id, (msg_t)info);
+ chSysUnlockFromISR();
+ }
+ else
+ msg = chMBPost((mailbox_t *)queue_id, (msg_t)info, timeout);
+
+ return msg == MSG_OK ? osOK : osEventTimeout;
+}
+
+/**
+ * @brief Get a message from the queue.
+ */
+osEvent osMessageGet(osMessageQId queue_id,
+ uint32_t millisec) {
+ msg_t msg;
+ osEvent event;
+ systime_t timeout = ((millisec == 0) || (millisec == osWaitForever)) ?
+ TIME_INFINITE : MS2ST(millisec);
+
+ event.def.message_id = queue_id;
+
+ if (port_is_isr_context()) {
+
+ /* Waiting makes no sense in ISRs so any value except "immediate"
+ makes no sense.*/
+ if (millisec != 0) {
+ event.status = osErrorValue;
+ return event;
+ }
+
+ chSysLockFromISR();
+ msg = chMBFetchI((mailbox_t *)queue_id, (msg_t*)&event.value.v);
+ chSysUnlockFromISR();
+ }
+ else {
+ msg = chMBFetch((mailbox_t *)queue_id, (msg_t*)&event.value.v, timeout);
+ }
+
+ /* Returned event type.*/
+ event.status = msg == MSG_OK ? osEventMessage : osEventTimeout;
+ return event;
+}
+
+/** @} */
diff --git a/os/common/abstractions/cmsis_os/cmsis_os.h b/os/common/abstractions/cmsis_os/cmsis_os.h
new file mode 100644
index 000000000..1c0998baf
--- /dev/null
+++ b/os/common/abstractions/cmsis_os/cmsis_os.h
@@ -0,0 +1,522 @@
+/*
+ ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio.
+
+ This file is part of ChibiOS.
+
+ ChibiOS is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ Concepts and parts of this file have been contributed by Andre R.
+ */
+
+/**
+ * @file cmsis_os.h
+ * @brief CMSIS RTOS module macros and structures.
+ *
+ * @addtogroup CMSIS_OS
+ * @{
+ */
+
+#ifndef _CMSIS_OS_H_
+#define _CMSIS_OS_H_
+
+#include "ch.h"
+
+/*===========================================================================*/
+/* Module constants. */
+/*===========================================================================*/
+
+/**
+ * @brief API version.
+ */
+#define osCMSIS 0x10002
+
+/**
+ * @brief Kernel version.
+ */
+#define osKernelSystemId "KERNEL V1.00"
+
+/**
+ * @brief ChibiOS/RT version encoded for CMSIS.
+ */
+#define osCMSIS_KERNEL ((CH_KERNEL_MAJOR << 16) | \
+ (CH_KERNEL_MINOR << 8) | \
+ (CH_KERNEL_PATCH))
+
+/**
+ * @name CMSIS Capabilities
+ * @{
+ */
+#define osFeature_MainThread 1
+#define osFeature_Pool 1
+#define osFeature_MailQ 0
+#define osFeature_MessageQ 1
+#define osFeature_Signals 24
+#define osFeature_Semaphore ((1U << 31) - 1U)
+#define osFeature_Wait 0
+#define osFeature_SysTick 1
+/**< @} */
+
+/**
+ * @brief Wait forever specification for timeouts.
+ */
+#define osWaitForever TIME_INFINITE
+
+/**
+ * @brief System tick frequency.
+ */
+#define osKernelSysTickFrequency CH_CFG_FREQUENCY
+
+/*===========================================================================*/
+/* Module pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @brief Number of pre-allocated static semaphores/mutexes.
+ */
+#if !defined(CMSIS_CFG_DEFAULT_STACK)
+#define CMSIS_CFG_DEFAULT_STACK 256
+#endif
+
+/**
+ * @brief Number of pre-allocated static semaphores/mutexes.
+ */
+#if !defined(CMSIS_CFG_NUM_SEMAPHORES)
+#define CMSIS_CFG_NUM_SEMAPHORES 4
+#endif
+
+/**
+ * @brief Number of pre-allocated static timers.
+ */
+#if !defined(CMSIS_CFG_NUM_TIMERS)
+#define CMSIS_CFG_NUM_TIMERS 4
+#endif
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !CH_CFG_USE_MEMPOOLS
+#error "CMSIS RTOS requires CH_CFG_USE_MEMPOOLS"
+#endif
+
+#if !CH_CFG_USE_EVENTS
+#error "CMSIS RTOS requires CH_CFG_USE_EVENTS"
+#endif
+
+#if !CH_CFG_USE_EVENTS_TIMEOUT
+#error "CMSIS RTOS requires CH_CFG_USE_EVENTS_TIMEOUT"
+#endif
+
+#if !CH_CFG_USE_SEMAPHORES
+#error "CMSIS RTOS requires CH_CFG_USE_SEMAPHORES"
+#endif
+
+#if !CH_CFG_USE_DYNAMIC
+#error "CMSIS RTOS requires CH_CFG_USE_DYNAMIC"
+#endif
+
+/*===========================================================================*/
+/* Module data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type of priority levels.
+ */
+typedef enum {
+ osPriorityIdle = -3,
+ osPriorityLow = -2,
+ osPriorityBelowNormal = -1,
+ osPriorityNormal = 0,
+ osPriorityAboveNormal = +1,
+ osPriorityHigh = +2,
+ osPriorityRealtime = +3,
+ osPriorityError = 0x84
+} osPriority;
+
+/**
+ * @brief Type of error codes.
+ */
+typedef enum {
+ osOK = 0,
+ osEventSignal = 0x08,
+ osEventMessage = 0x10,
+ osEventMail = 0x20,
+ osEventTimeout = 0x40,
+ osErrorParameter = 0x80,
+ osErrorResource = 0x81,
+ osErrorTimeoutResource = 0xC1,
+ osErrorISR = 0x82,
+ osErrorISRRecursive = 0x83,
+ osErrorPriority = 0x84,
+ osErrorNoMemory = 0x85,
+ osErrorValue = 0x86,
+ osErrorOS = 0xFF,
+ os_status_reserved = 0x7FFFFFFF
+} osStatus;
+
+/**
+ * @brief Type of a timer mode.
+ */
+typedef enum {
+ osTimerOnce = 0,
+ osTimerPeriodic = 1
+} os_timer_type;
+
+/**
+ * @brief Type of thread functions.
+ */
+typedef void (*os_pthread) (void const *argument);
+
+/**
+ * @brief Type of timer callback.
+ */
+typedef void (*os_ptimer) (void const *argument);
+
+/**
+ * @brief Type of pointer to thread control block.
+ */
+typedef thread_t *osThreadId;
+
+/**
+ * @brief Type of pointer to timer control block.
+ */
+typedef struct os_timer_cb {
+ virtual_timer_t vt;
+ os_timer_type type;
+ os_ptimer ptimer;
+ void *argument;
+ uint32_t millisec;
+} *osTimerId;
+
+/**
+ * @brief Type of pointer to mutex control block.
+ */
+typedef binary_semaphore_t *osMutexId;
+
+/**
+ * @brief Type of pointer to semaphore control block.
+ */
+typedef semaphore_t *osSemaphoreId;
+
+/**
+ * @brief Type of pointer to memory pool control block.
+ */
+typedef memory_pool_t *osPoolId;
+
+/**
+ * @brief Type of pointer to message queue control block.
+ */
+typedef struct mailbox *osMessageQId;
+
+/**
+ * @brief Type of an event.
+ */
+typedef struct {
+ osStatus status;
+ union {
+ uint32_t v;
+ void *p;
+ int32_t signals;
+ } value;
+ union {
+/* osMailQId mail_id;*/
+ osMessageQId message_id;
+ } def;
+} osEvent;
+
+/**
+ * @brief Type of a thread definition block.
+ */
+typedef struct os_thread_def {
+ os_pthread pthread;
+ osPriority tpriority;
+ uint32_t stacksize;
+ const char *name;
+} osThreadDef_t;
+
+/**
+ * @brief Type of a timer definition block.
+ */
+typedef struct os_timer_def {
+ os_ptimer ptimer;
+} osTimerDef_t;
+
+/**
+ * @brief Type of a mutex definition block.
+ */
+typedef struct os_mutex_def {
+ uint32_t dummy;
+} osMutexDef_t;
+
+/**
+ * @brief Type of a semaphore definition block.
+ */
+typedef struct os_semaphore_def {
+ uint32_t dummy;
+} osSemaphoreDef_t;
+
+/**
+ * @brief Type of a memory pool definition block.
+ */
+typedef struct os_pool_def {
+ uint32_t pool_sz;
+ uint32_t item_sz;
+ memory_pool_t *pool;
+ void *items;
+} osPoolDef_t;
+
+/**
+ * @brief Type of a message queue definition block.
+ */
+typedef struct os_messageQ_def {
+ uint32_t queue_sz;
+ uint32_t item_sz;
+ mailbox_t *mailbox;
+ void *items;
+} osMessageQDef_t;
+
+/*===========================================================================*/
+/* Module macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Convert a microseconds value to a RTOS kernel system timer value.
+ */
+#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * \
+ (osKernelSysTickFrequency)) / \
+ 1000000)
+
+/**
+ * @brief Create a Thread definition.
+ */
+#if defined(osObjectsExternal)
+#define osThreadDef(thd, priority, stacksz, name) \
+ extern const osThreadDef_t os_thread_def_##thd
+#else
+#define osThreadDef(thd, priority, stacksz, name) \
+const osThreadDef_t os_thread_def_##thd = { \
+ (thd), \
+ (priority), \
+ (stacksz), \
+ (name) \
+}
+#endif
+
+/**
+ * @brief Access a Thread definition.
+ */
+#define osThread(name) &os_thread_def_##name
+
+/**
+ * @brief Define a Timer object.
+ */
+#if defined(osObjectsExternal)
+#define osTimerDef(name, function) \
+ extern const osTimerDef_t os_timer_def_##name
+#else
+#define osTimerDef(name, function) \
+const osTimerDef_t os_timer_def_##name = { \
+ (function) \
+}
+#endif
+
+/**
+ * @brief Access a Timer definition.
+ */
+#define osTimer(name) &os_timer_def_##name
+
+/**
+ * @brief Define a Mutex.
+ */
+#if defined(osObjectsExternal)
+#define osMutexDef(name) extern const osMutexDef_t os_mutex_def_##name
+#else
+#define osMutexDef(name) const osMutexDef_t os_mutex_def_##name = {0}
+#endif
+
+/**
+ * @brief Access a Mutex definition.
+ */
+#define osMutex(name) &os_mutex_def_##name
+
+/**
+ * @brief Define a Semaphore.
+ */
+#if defined(osObjectsExternal)
+#define osSemaphoreDef(name) \
+ extern const osSemaphoreDef_t os_semaphore_def_##name
+#else // define the object
+#define osSemaphoreDef(name) \
+ const osSemaphoreDef_t os_semaphore_def_##name = {0}
+#endif
+
+/**
+ * @brief Access a Semaphore definition.
+ */
+#define osSemaphore(name) &os_semaphore_def_##name
+
+/**
+ * @brief Define a Memory Pool.
+ */
+#if defined(osObjectsExternal)
+#define osPoolDef(name, no, type) \
+ extern const osPoolDef_t os_pool_def_##name
+#else
+#define osPoolDef(name, no, type) \
+static const type os_pool_buf_##name[no]; \
+static memory_pool_t os_pool_obj_##name; \
+const osPoolDef_t os_pool_def_##name = { \
+ (no), \
+ sizeof (type), \
+ (void *)&os_pool_obj_##name, \
+ (void *)&os_pool_buf_##name[0] \
+}
+#endif
+
+/**
+ * @brief Access a Memory Pool definition.
+ */
+#define osPool(name) &os_pool_def_##name
+
+/**
+ * @brief Define a Message Queue.
+ */
+#if defined(osObjectsExternal)
+#define osMessageQDef(name, queue_sz, type) \
+ extern const osMessageQDef_t os_messageQ_def_##name
+#else
+#define osMessageQDef(name, queue_sz, type) \
+static const msg_t os_messageQ_buf_##name[queue_sz]; \
+static mailbox_t os_messageQ_obj_##name; \
+const osMessageQDef_t os_messageQ_def_##name = { \
+ (queue_sz), \
+ sizeof (type) \
+ (void *)&os_messageQ_obj_##name, \
+ (void *)&os_messageQ_buf_##name[0] \
+}
+#endif
+
+/**
+ * @brief Access a Message Queue definition.
+ */
+#define osMessageQ(name) &os_messageQ_def_##name
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+extern int32_t cmsis_os_started;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ osStatus osKernelInitialize(void);
+ osStatus osKernelStart(void);
+ osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument);
+ osStatus osThreadTerminate(osThreadId thread_id);
+ osStatus osThreadSetPriority(osThreadId thread_id, osPriority newprio);
+ /*osEvent osWait(uint32_t millisec);*/
+ osTimerId osTimerCreate(const osTimerDef_t *timer_def,
+ os_timer_type type,
+ void *argument);
+ osStatus osTimerStart(osTimerId timer_id, uint32_t millisec);
+ osStatus osTimerStop(osTimerId timer_id);
+ osStatus osTimerDelete(osTimerId timer_id);
+ int32_t osSignalSet(osThreadId thread_id, int32_t signals);
+ int32_t osSignalClear(osThreadId thread_id, int32_t signals);
+ osEvent osSignalWait(int32_t signals, uint32_t millisec);
+ osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def,
+ int32_t count);
+ int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec);
+ osStatus osSemaphoreRelease(osSemaphoreId semaphore_id);
+ osStatus osSemaphoreDelete(osSemaphoreId semaphore_id);
+ osMutexId osMutexCreate(const osMutexDef_t *mutex_def);
+ osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec);
+ osStatus osMutexRelease(osMutexId mutex_id);
+ osStatus osMutexDelete(osMutexId mutex_id);
+ osPoolId osPoolCreate(const osPoolDef_t *pool_def);
+ void *osPoolAlloc(osPoolId pool_id);
+ void *osPoolCAlloc(osPoolId pool_id);
+ osStatus osPoolFree(osPoolId pool_id, void *block);
+ osMessageQId osMessageCreate(const osMessageQDef_t *queue_def,
+ osThreadId thread_id);
+ osStatus osMessagePut(osMessageQId queue_id,
+ uint32_t info,
+ uint32_t millisec);
+ osEvent osMessageGet(osMessageQId queue_id,
+ uint32_t millisec);
+#ifdef __cplusplus
+}
+#endif
+
+/*===========================================================================*/
+/* Module inline functions. */
+/*===========================================================================*/
+
+/**
+ * @brief To be or not to be.
+ */
+static inline int32_t osKernelRunning(void) {
+
+ return cmsis_os_started;
+}
+
+/**
+ * @brief System ticks since start.
+ */
+static inline uint32_t osKernelSysTick(void) {
+
+ return (uint32_t)chVTGetSystemTimeX();
+}
+
+/**
+ * @brief Returns the current thread.
+ */
+static inline osThreadId osThreadGetId(void) {
+
+ return (osThreadId)chThdGetSelfX();
+}
+
+/**
+ * @brief Thread time slice yield.
+ */
+static inline osStatus osThreadYield(void) {
+
+ chThdYield();
+
+ return osOK;
+}
+
+/**
+ * @brief Returns priority of a thread.
+ */
+static inline osPriority osThreadGetPriority(osThreadId thread_id) {
+
+ return thread_id->prio;
+}
+
+/**
+ * @brief Thread delay in milliseconds.
+ */
+static inline osStatus osDelay(uint32_t millisec) {
+
+ chThdSleepMilliseconds(millisec);
+
+ return osOK;
+}
+
+#endif /* _CMSIS_OS_H_ */
+
+/** @} */
diff --git a/os/common/abstractions/cmsis_os/cmsis_os.mk b/os/common/abstractions/cmsis_os/cmsis_os.mk
new file mode 100644
index 000000000..eb35bc574
--- /dev/null
+++ b/os/common/abstractions/cmsis_os/cmsis_os.mk
@@ -0,0 +1,4 @@
+# List of the ChibiOS/RT CMSIS RTOS wrapper.
+CMSISRTOSSRC = ${CHIBIOS}/os/common/abstractions/cmsis_os/cmsis_os.c
+
+CMSISRTOSINC = ${CHIBIOS}/os/common/abstractions/cmsis_os