QMK/lib/chibios/os/common/abstractions/cmsis_os/cmsis_os.h

523 lines
15 KiB
C

/*
ChibiOS - Copyright (C) 2006..2018 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 ((uint32_t)-1)
/**
* @brief System tick frequency.
*/
#define osKernelSysTickFrequency CH_CFG_ST_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 (osPriority)(NORMALPRIO - thread_id->prio);
}
/**
* @brief Thread delay in milliseconds.
*/
static inline osStatus osDelay(uint32_t millisec) {
chThdSleepMilliseconds(millisec);
return osOK;
}
#endif /* CMSIS_OS_H */
/** @} */