0
mirror of https://github.com/OneOfEleven/uv-k5-firmware-custom.git synced 2025-06-20 15:08:37 +03:00

Initial commit

This commit is contained in:
OneOfEleven
2023-09-09 08:03:56 +01:00
parent 92305117f1
commit 54441e27d9
3388 changed files with 582553 additions and 0 deletions

View File

@ -0,0 +1,558 @@
/*----------------------------------------------------------------------------
* CMSIS-RTOS - RTX
*----------------------------------------------------------------------------
* Name: RTX_CM_LIB.H
* Purpose: RTX Kernel System Configuration
* Rev.: V4.82
*----------------------------------------------------------------------------
*
* Copyright (c) 1999-2009 KEIL, 2009-2019 ARM Germany GmbH. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*---------------------------------------------------------------------------*/
#if defined (__CC_ARM)
#pragma O3
#define __USED __attribute__((used))
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __USED __attribute__((used))
#elif defined (__GNUC__)
#pragma GCC optimize ("O3")
#define __USED __attribute__((used))
#elif defined (__ICCARM__)
#define __USED __root
#endif
/*----------------------------------------------------------------------------
* Definitions
*---------------------------------------------------------------------------*/
#define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3]
#define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2]
#define OS_TCB_SIZE 52
#define OS_TMR_SIZE 8
#if (( defined(__CC_ARM) || \
(defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && \
!defined(__MICROLIB))
typedef void *OS_ID;
typedef uint32_t OS_TID;
typedef uint32_t OS_MUT[4];
typedef uint32_t OS_RESULT;
#define runtask_id() rt_tsk_self()
#define mutex_init(m) rt_mut_init(m)
#define mutex_wait(m) os_mut_wait(m,0xFFFFU)
#define mutex_rel(m) os_mut_release(m)
extern uint8_t os_running;
extern OS_TID rt_tsk_self (void);
extern void rt_mut_init (OS_ID mutex);
extern OS_RESULT rt_mut_release (OS_ID mutex);
extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout);
#if defined(__CC_ARM)
#define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout)
#define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex)
OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0);
OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0);
#else
__attribute__((always_inline))
static __inline OS_RESULT os_mut_release (OS_ID mutex) {
register uint32_t __rf __asm("r12") = (uint32_t)rt_mut_release;
register uint32_t __r0 __asm("r0") = (uint32_t)mutex;
__asm volatile \
( \
"svc 0" \
: "=r" (__r0) \
: "r" (__rf), "r" (__r0) \
: "r1", "r2" \
);
return (OS_RESULT)__r0;
}
__attribute__((always_inline))
static __inline OS_RESULT os_mut_wait (OS_ID mutex, uint16_t timeout) {
register uint32_t __rf __asm("r12") = (uint32_t)rt_mut_wait;
register uint32_t __r0 __asm("r0") = (uint32_t)mutex;
register uint32_t __r1 __asm("r1") = (uint32_t)timeout;
__asm volatile \
( \
"svc 0" \
: "=r" (__r0) \
: "r" (__rf), "r" (__r0), "r" (__r1) \
: "r2" \
);
return (OS_RESULT)__r0;
}
#endif
#endif
/*----------------------------------------------------------------------------
* Global Variables
*---------------------------------------------------------------------------*/
#if (OS_TASKCNT == 0)
#error "Invalid number of concurrent running threads!"
#endif
#if (OS_PRIVCNT >= OS_TASKCNT)
#error "Too many threads with user-provided stack size!"
#endif
#if (OS_TIMERS != 0)
#define OS_TASK_CNT (OS_TASKCNT + 1)
#define OS_PRIV_CNT (OS_PRIVCNT + 2)
#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ))
#else
#define OS_TASK_CNT OS_TASKCNT
#define OS_PRIV_CNT (OS_PRIVCNT + 1)
#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE))
#endif
#ifndef OS_STKINIT
#define OS_STKINIT 0
#endif
extern uint16_t const os_maxtaskrun;
extern uint32_t const os_stackinfo;
extern uint32_t const os_rrobin;
extern uint32_t const os_trv;
extern uint8_t const os_flags;
uint16_t const os_maxtaskrun = OS_TASK_CNT;
uint32_t const os_stackinfo = (OS_STKINIT<<28) | (OS_STKCHECK<<24) | (OS_PRIV_CNT<<16) | (OS_STKSIZE*4);
uint32_t const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT;
uint32_t const os_tickfreq = OS_CLOCK;
uint16_t const os_tickus_i = OS_CLOCK/1000000;
uint16_t const os_tickus_f = (((uint64_t)(OS_CLOCK-1000000*(OS_CLOCK/1000000)))<<16)/1000000;
uint32_t const os_trv = OS_TRV;
uint8_t const os_flags = OS_RUNPRIV;
/* Export following defines to uVision debugger. */
extern uint32_t const CMSIS_RTOS_API_Version;
__USED uint32_t const CMSIS_RTOS_API_Version = osCMSIS;
extern uint32_t const CMSIS_RTOS_RTX_Version;
__USED uint32_t const CMSIS_RTOS_RTX_Version = osCMSIS_RTX;
extern uint32_t const os_clockrate;
__USED uint32_t const os_clockrate = OS_TICK;
extern uint32_t const os_timernum;
__USED uint32_t const os_timernum = 0U;
/* Memory pool for TCB allocation */
extern
uint32_t mp_tcb[];
_declare_box (mp_tcb, OS_TCB_SIZE, OS_TASK_CNT);
extern
uint16_t const mp_tcb_size;
uint16_t const mp_tcb_size = sizeof(mp_tcb);
/* Memory pool for System stack allocation (+os_idle_demon). */
extern
uint64_t mp_stk[];
_declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1);
extern
uint32_t const mp_stk_size;
uint32_t const mp_stk_size = sizeof(mp_stk);
/* Memory pool for user specified stack allocation (+main, +timer) */
extern
uint64_t os_stack_mem[];
uint64_t os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)];
extern
uint32_t const os_stack_sz;
uint32_t const os_stack_sz = sizeof(os_stack_mem);
#ifndef OS_FIFOSZ
#define OS_FIFOSZ 16
#endif
/* Fifo Queue buffer for ISR requests.*/
extern
uint32_t os_fifo[];
uint32_t os_fifo[OS_FIFOSZ*2+1];
extern
uint8_t const os_fifo_size;
uint8_t const os_fifo_size = OS_FIFOSZ;
/* An array of Active task pointers. */
extern
void *os_active_TCB[];
void *os_active_TCB[OS_TASK_CNT];
/* User Timers Resources */
#if (OS_TIMERS != 0)
extern void osTimerThread (void const *argument);
extern const osThreadDef_t os_thread_def_osTimerThread;
osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ);
extern
osThreadId osThreadId_osTimerThread;
osThreadId osThreadId_osTimerThread;
extern uint32_t os_messageQ_q_osTimerMessageQ[];
extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ;
osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *);
extern
osMessageQId osMessageQId_osTimerMessageQ;
osMessageQId osMessageQId_osTimerMessageQ;
#else
extern
const osThreadDef_t os_thread_def_osTimerThread;
const osThreadDef_t os_thread_def_osTimerThread = { NULL, osPriorityNormal, 0U, 0U };
extern
osThreadId osThreadId_osTimerThread;
osThreadId osThreadId_osTimerThread;
extern uint32_t os_messageQ_q_osTimerMessageQ[];
extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ;
osMessageQDef(osTimerMessageQ, 0U, void *);
extern
osMessageQId osMessageQId_osTimerMessageQ;
osMessageQId osMessageQId_osTimerMessageQ;
#endif
/* Legacy RTX User Timers not used */
extern
uint32_t os_tmr;
uint32_t os_tmr = 0U;
extern
uint32_t const *m_tmr;
uint32_t const *m_tmr = NULL;
extern
uint16_t const mp_tmr_size;
uint16_t const mp_tmr_size = 0U;
#if (( defined(__CC_ARM) || \
(defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && \
!defined(__MICROLIB))
/* A memory space for arm standard library. */
static uint32_t std_libspace[OS_TASK_CNT][96/4];
static OS_MUT std_libmutex[OS_MUTEXCNT];
static uint32_t nr_mutex;
extern void *__libspace_start;
#endif
/*----------------------------------------------------------------------------
* RTX Optimizations (empty functions)
*---------------------------------------------------------------------------*/
#if OS_ROBIN == 0
extern
void rt_init_robin (void);
void rt_init_robin (void) {;}
extern
void rt_chk_robin (void);
void rt_chk_robin (void) {;}
#endif
#if OS_STKCHECK == 0
extern
void rt_stk_check (void);
void rt_stk_check (void) {;}
#endif
/*----------------------------------------------------------------------------
* Standard Library multithreading interface
*---------------------------------------------------------------------------*/
#if (( defined(__CC_ARM) || \
(defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))) && \
!defined(__MICROLIB))
/*--------------------------- __user_perthread_libspace ---------------------*/
void *__user_perthread_libspace (void);
void *__user_perthread_libspace (void) {
/* Provide a separate libspace for each task. */
uint32_t idx;
idx = (os_running != 0U) ? runtask_id () : 0U;
if (idx == 0U) {
/* RTX not running yet. */
return (&__libspace_start);
}
return ((void *)&std_libspace[idx-1]);
}
/*--------------------------- _mutex_initialize -----------------------------*/
int _mutex_initialize (OS_ID *mutex);
int _mutex_initialize (OS_ID *mutex) {
/* Allocate and initialize a system mutex. */
if (nr_mutex >= OS_MUTEXCNT) {
/* If you are here, you need to increase the number OS_MUTEXCNT. */
for (;;);
}
*mutex = &std_libmutex[nr_mutex++];
mutex_init (*mutex);
return (1);
}
/*--------------------------- _mutex_acquire --------------------------------*/
__attribute__((used))
void _mutex_acquire (OS_ID *mutex);
void _mutex_acquire (OS_ID *mutex) {
/* Acquire a system mutex, lock stdlib resources. */
if (os_running) {
/* RTX running, acquire a mutex. */
mutex_wait (*mutex);
}
}
/*--------------------------- _mutex_release --------------------------------*/
__attribute__((used))
void _mutex_release (OS_ID *mutex);
void _mutex_release (OS_ID *mutex) {
/* Release a system mutex, unlock stdlib resources. */
if (os_running) {
/* RTX running, release a mutex. */
mutex_rel (*mutex);
}
}
#endif
/*----------------------------------------------------------------------------
* ARMCC6 Wrappers for ARMCC5 Binary
*---------------------------------------------------------------------------*/
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
typedef uint32_t __attribute__((vector_size(8))) vect64_t;
#undef osSignalWait
__attribute__((pcs("aapcs")))
vect64_t osSignalWait (int32_t signals, uint32_t millisec);
osEvent __osSignalWait (int32_t signals, uint32_t millisec) {
vect64_t v;
osEvent e;
v = osSignalWait(signals, millisec);
e.status = v[0];
e.value.v = v[1];
return e;
}
#undef osMessageGet
__attribute__((pcs("aapcs")))
vect64_t osMessageGet (osMessageQId queue_id, uint32_t millisec);
osEvent __osMessageGet (osMessageQId queue_id, uint32_t millisec) {
vect64_t v;
osEvent e;
v = osMessageGet(queue_id, millisec);
e.status = v[0];
e.value.v = v[1];
return e;
}
#undef osMailGet
__attribute__((pcs("aapcs")))
vect64_t osMailGet (osMailQId queue_id, uint32_t millisec);
osEvent __osMailGet (osMailQId queue_id, uint32_t millisec) {
vect64_t v;
osEvent e;
v = osMailGet(queue_id, millisec);
e.status = v[0];
e.value.v = v[1];
return e;
}
#endif
/*----------------------------------------------------------------------------
* RTX Startup
*---------------------------------------------------------------------------*/
/* Main Thread definition */
extern int main (void);
extern
const osThreadDef_t os_thread_def_main;
const osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1U, 4*OS_MAINSTKSIZE };
#if defined (__CC_ARM)
#ifdef __MICROLIB
__attribute__((section(".ARM.Collect$$$$000000FF")))
void _main_init (void);
void _main_init (void) {
osKernelInitialize();
osThreadCreate(&os_thread_def_main, NULL);
osKernelStart();
for (;;);
}
#else
__asm void _platform_post_lib_init (void) {
IMPORT os_thread_def_main
IMPORT osKernelInitialize
IMPORT osKernelStart
IMPORT osThreadCreate
IMPORT exit
ADD SP,#0x10
BL osKernelInitialize
LDR R0,=os_thread_def_main
MOVS R1,#0
BL osThreadCreate
BL osKernelStart
BL exit
ALIGN
}
#endif
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#ifdef __MICROLIB
__attribute__((noreturn, section(".ARM.Collect$$$$000000FF")))
void _main_init (void);
void _main_init (void) {
#else
__asm(" .global __ARM_use_no_argv\n");
__attribute__((noreturn))
void _platform_post_lib_init (void);
void _platform_post_lib_init (void) {
#endif
osKernelInitialize();
osThreadCreate(&os_thread_def_main, NULL);
osKernelStart();
for (;;);
}
#elif defined (__GNUC__)
#ifdef __CS3__
/* CS3 start_c routine.
*
* Copyright (c) 2006, 2007 CodeSourcery Inc
*
* The authors hereby grant permission to use, copy, modify, distribute,
* and license this software and its documentation for any purpose, provided
* that existing copyright notices are retained in all copies and that this
* notice is included verbatim in any distributions. No written agreement,
* license, or royalty fee is required for any of the authorized uses.
* Modifications to this software may be copyrighted by their authors
* and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
*/
#include "cs3.h"
extern void __libc_init_array (void);
__attribute ((noreturn)) void __cs3_start_c (void){
unsigned regions = __cs3_region_num;
const struct __cs3_region *rptr = __cs3_regions;
/* Initialize memory */
for (regions = __cs3_region_num, rptr = __cs3_regions; regions--; rptr++) {
long long *src = (long long *)rptr->init;
long long *dst = (long long *)rptr->data;
unsigned limit = rptr->init_size;
unsigned count;
if (src != dst)
for (count = 0; count != limit; count += sizeof (long long))
*dst++ = *src++;
else
dst = (long long *)((char *)dst + limit);
limit = rptr->zero_size;
for (count = 0; count != limit; count += sizeof (long long))
*dst++ = 0;
}
/* Run initializers. */
__libc_init_array ();
osKernelInitialize();
osThreadCreate(&os_thread_def_main, NULL);
osKernelStart();
for (;;);
}
#else
__attribute__((naked)) void software_init_hook (void) {
__asm (
".syntax unified\n"
".thumb\n"
"movs r0,#0\n"
"movs r1,#0\n"
"mov r4,r0\n"
"mov r5,r1\n"
"ldr r0,= __libc_fini_array\n"
"bl atexit\n"
"bl __libc_init_array\n"
"mov r0,r4\n"
"mov r1,r5\n"
"bl osKernelInitialize\n"
"ldr r0,=os_thread_def_main\n"
"movs r1,#0\n"
"bl osThreadCreate\n"
"bl osKernelStart\n"
"bl exit\n"
);
}
#endif
#elif defined (__ICCARM__)
extern int __low_level_init(void);
extern void __iar_data_init3(void);
extern void exit(int arg);
__noreturn __stackless void __cmain(void) {
int a;
if (__low_level_init() != 0) {
__iar_data_init3();
}
osKernelInitialize();
osThreadCreate(&os_thread_def_main, NULL);
a = osKernelStart();
exit(a);
}
#endif
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/

View File

@ -0,0 +1,677 @@
/* ----------------------------------------------------------------------
* $Date: 5. February 2013
* $Revision: V1.02
*
* Project: CMSIS-RTOS API
* Title: cmsis_os.h RTX header file
*
* Version 0.02
* Initial Proposal Phase
* Version 0.03
* osKernelStart added, optional feature: main started as thread
* osSemaphores have standard behavior
* osTimerCreate does not start the timer, added osTimerStart
* osThreadPass is renamed to osThreadYield
* Version 1.01
* Support for C++ interface
* - const attribute removed from the osXxxxDef_t typedef's
* - const attribute added to the osXxxxDef macros
* Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
* Added: osKernelInitialize
* Version 1.02
* Control functions for short timeouts in microsecond resolution:
* Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
* Removed: osSignalGet
*----------------------------------------------------------------------------
*
* Copyright (c) 2013-2017 ARM LIMITED. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*---------------------------------------------------------------------------*/
#ifndef _CMSIS_OS_H
#define _CMSIS_OS_H
#define osCMSIS 0x10002U ///< CMSIS-RTOS API version (main [31:16] .sub [15:0])
#define osCMSIS_RTX ((4<<16)|82) ///< RTOS identification and version (main [31:16] .sub [15:0])
#define osKernelSystemId "RTX V4.82" ///< RTOS identification string
#define osFeature_MainThread 1 ///< main can be thread
#define osFeature_Pool 1 ///< Memory Pools available
#define osFeature_MailQ 1 ///< Mail Queues available
#define osFeature_MessageQ 1 ///< Message Queues available
#define osFeature_Signals 16 ///< 16 Signal Flags available per thread
#define osFeature_Semaphore 65535 ///< Maximum count for \ref osSemaphoreCreate function
#define osFeature_Wait 0 ///< osWait not available
#define osFeature_SysTick 1 ///< osKernelSysTick functions available
#if defined(__CC_ARM)
#define os_InRegs __value_in_regs // Compiler specific: force struct in registers
#else
#define os_InRegs
#endif
#if defined(__CC_ARM)
#define __NO_RETURN __declspec(noreturn)
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __NO_RETURN __attribute__((noreturn))
#elif defined(__GNUC__)
#define __NO_RETURN __attribute__((noreturn))
#elif defined(__ICCARM__)
#define __NO_RETURN __noreturn
#else
#define __NO_RETURN
#endif
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C"
{
#endif
// ==== Enumeration, structures, defines ====
/// Priority used for thread control.
typedef enum {
osPriorityIdle = -3, ///< priority: idle (lowest)
osPriorityLow = -2, ///< priority: low
osPriorityBelowNormal = -1, ///< priority: below normal
osPriorityNormal = 0, ///< priority: normal (default)
osPriorityAboveNormal = +1, ///< priority: above normal
osPriorityHigh = +2, ///< priority: high
osPriorityRealtime = +3, ///< priority: realtime (highest)
osPriorityError = 0x84, ///< system cannot determine priority or thread has illegal priority
os_priority_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization.
} osPriority;
/// Timeout value.
#define osWaitForever 0xFFFFFFFFU ///< wait forever timeout value
/// Status code values returned by CMSIS-RTOS functions.
typedef enum {
osOK = 0, ///< function completed; no error or event occurred.
osEventSignal = 0x08, ///< function completed; signal event occurred.
osEventMessage = 0x10, ///< function completed; message event occurred.
osEventMail = 0x20, ///< function completed; mail event occurred.
osEventTimeout = 0x40, ///< function completed; timeout occurred.
osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object.
osErrorResource = 0x81, ///< resource not available: a specified resource was not available.
osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period.
osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines.
osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object.
osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority.
osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.
osErrorValue = 0x86, ///< value of a parameter is out of range.
osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits.
os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization.
} osStatus;
/// Timer type value for the timer definition.
typedef enum {
osTimerOnce = 0, ///< one-shot timer
osTimerPeriodic = 1 ///< repeating timer
} os_timer_type;
/// Entry point of a thread.
typedef void (*os_pthread) (void const *argument);
/// Entry point of a timer call back function.
typedef void (*os_ptimer) (void const *argument);
// >>> the following data type definitions may shall adapted towards a specific RTOS
/// Thread ID identifies the thread (pointer to a thread control block).
typedef struct os_thread_cb *osThreadId;
/// Timer ID identifies the timer (pointer to a timer control block).
typedef struct os_timer_cb *osTimerId;
/// Mutex ID identifies the mutex (pointer to a mutex control block).
typedef struct os_mutex_cb *osMutexId;
/// Semaphore ID identifies the semaphore (pointer to a semaphore control block).
typedef struct os_semaphore_cb *osSemaphoreId;
/// Pool ID identifies the memory pool (pointer to a memory pool control block).
typedef struct os_pool_cb *osPoolId;
/// Message ID identifies the message queue (pointer to a message queue control block).
typedef struct os_messageQ_cb *osMessageQId;
/// Mail ID identifies the mail queue (pointer to a mail queue control block).
typedef struct os_mailQ_cb *osMailQId;
/// Thread Definition structure contains startup information of a thread.
typedef struct os_thread_def {
os_pthread pthread; ///< start address of thread function
osPriority tpriority; ///< initial thread priority
uint32_t instances; ///< maximum number of instances of that thread function
uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size
} osThreadDef_t;
/// Timer Definition structure contains timer parameters.
typedef struct os_timer_def {
os_ptimer ptimer; ///< start address of a timer function
void *timer; ///< pointer to internal data
} osTimerDef_t;
/// Mutex Definition structure contains setup information for a mutex.
typedef struct os_mutex_def {
void *mutex; ///< pointer to internal data
} osMutexDef_t;
/// Semaphore Definition structure contains setup information for a semaphore.
typedef struct os_semaphore_def {
void *semaphore; ///< pointer to internal data
} osSemaphoreDef_t;
/// Definition structure for memory block allocation.
typedef struct os_pool_def {
uint32_t pool_sz; ///< number of items (elements) in the pool
uint32_t item_sz; ///< size of an item
void *pool; ///< pointer to memory for pool
} osPoolDef_t;
/// Definition structure for message queue.
typedef struct os_messageQ_def {
uint32_t queue_sz; ///< number of elements in the queue
void *pool; ///< memory array for messages
} osMessageQDef_t;
/// Definition structure for mail queue.
typedef struct os_mailQ_def {
uint32_t queue_sz; ///< number of elements in the queue
uint32_t item_sz; ///< size of an item
void *pool; ///< memory array for mail
} osMailQDef_t;
/// Event structure contains detailed information about an event.
typedef struct {
osStatus status; ///< status code: event or error information
union {
uint32_t v; ///< message as 32-bit value
void *p; ///< message or mail as void pointer
int32_t signals; ///< signal flags
} value; ///< event value
union {
osMailQId mail_id; ///< mail id obtained by \ref osMailCreate
osMessageQId message_id; ///< message id obtained by \ref osMessageCreate
} def; ///< event definition
} osEvent;
// ==== Kernel Control Functions ====
/// Initialize the RTOS Kernel for creating objects.
/// \return status code that indicates the execution status of the function.
osStatus osKernelInitialize (void);
/// Start the RTOS Kernel.
/// \return status code that indicates the execution status of the function.
osStatus osKernelStart (void);
/// Check if the RTOS kernel is already started.
/// \return 0 RTOS is not started, 1 RTOS is started.
int32_t osKernelRunning(void);
#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available
/// \cond INTERNAL_VARIABLES
extern uint32_t const os_tickfreq;
extern uint16_t const os_tickus_i;
extern uint16_t const os_tickus_f;
/// \endcond
/// Get the RTOS kernel system timer counter.
/// \return RTOS kernel system timer as 32-bit value
uint32_t osKernelSysTick (void);
/// The RTOS kernel system timer frequency in Hz.
/// \note Reflects the system timer setting and is typically defined in a configuration file.
#define osKernelSysTickFrequency os_tickfreq
/// Convert a microseconds value to a RTOS kernel system timer value.
/// \param microsec time value in microseconds.
/// \return time value normalized to the \ref osKernelSysTickFrequency
/*
#define osKernelSysTickMicroSec(microsec) (((uint64_t)microsec * (osKernelSysTickFrequency)) / 1000000)
*/
#define osKernelSysTickMicroSec(microsec) ((microsec * os_tickus_i) + ((microsec * os_tickus_f) >> 16))
#endif // System Timer available
// ==== Thread Management ====
/// Create a Thread Definition with function, priority, and stack requirements.
/// \param name name of the thread function.
/// \param priority initial priority of the thread function.
/// \param instances number of possible thread instances.
/// \param stacksz stack size (in bytes) requirements for the thread function.
/// macro body is implementation specific in every CMSIS-RTOS.
#if defined (osObjectsExternal) // object is external
#define osThreadDef(name, priority, instances, stacksz) \
extern const osThreadDef_t os_thread_def_##name
#else // define the object
#define osThreadDef(name, priority, instances, stacksz) \
const osThreadDef_t os_thread_def_##name = \
{ (name), (priority), (instances), (stacksz) }
#endif
/// Access a Thread definition.
/// \param name name of the thread definition object.
/// macro body is implementation specific in every CMSIS-RTOS.
#define osThread(name) \
&os_thread_def_##name
/// Create a thread and add it to Active Threads and set it to state READY.
/// \param[in] thread_def thread definition referenced with \ref osThread.
/// \param[in] argument pointer that is passed to the thread function as start argument.
/// \return thread ID for reference by other functions or NULL in case of error.
osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument);
/// Return the thread ID of the current running thread.
/// \return thread ID for reference by other functions or NULL in case of error.
osThreadId osThreadGetId (void);
/// Terminate execution of a thread and remove it from Active Threads.
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
osStatus osThreadTerminate (osThreadId thread_id);
/// Pass control to next thread that is in state \b READY.
/// \return status code that indicates the execution status of the function.
osStatus osThreadYield (void);
/// Change priority of an active thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
/// \param[in] priority new priority value for the thread function.
/// \return status code that indicates the execution status of the function.
osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority);
/// Get current priority of an active thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
/// \return current priority value of the thread function.
osPriority osThreadGetPriority (osThreadId thread_id);
// ==== Generic Wait Functions ====
/// Wait for Timeout (Time Delay).
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "Time delay" value
/// \return status code that indicates the execution status of the function.
osStatus osDelay (uint32_t millisec);
#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available
/// Wait for Signal, Message, Mail, or Timeout.
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
/// \return event that contains signal, message, or mail information or error code.
os_InRegs osEvent osWait (uint32_t millisec);
#endif // Generic Wait available
// ==== Timer Management Functions ====
/// Define a Timer object.
/// \param name name of the timer object.
/// \param function name of the timer call back function.
#if defined (osObjectsExternal) // object is external
#define osTimerDef(name, function) \
extern const osTimerDef_t os_timer_def_##name
#else // define the object
#define osTimerDef(name, function) \
uint32_t os_timer_cb_##name[6]; \
const osTimerDef_t os_timer_def_##name = \
{ (function), (os_timer_cb_##name) }
#endif
/// Access a Timer definition.
/// \param name name of the timer object.
#define osTimer(name) \
&os_timer_def_##name
/// Create a timer.
/// \param[in] timer_def timer object referenced with \ref osTimer.
/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
/// \param[in] argument argument to the timer call back function.
/// \return timer ID for reference by other functions or NULL in case of error.
osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument);
/// Start or restart a timer.
/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "Time delay" value of the timer.
/// \return status code that indicates the execution status of the function.
osStatus osTimerStart (osTimerId timer_id, uint32_t millisec);
/// Stop the timer.
/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
/// \return status code that indicates the execution status of the function.
osStatus osTimerStop (osTimerId timer_id);
/// Delete a timer that was created by \ref osTimerCreate.
/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
/// \return status code that indicates the execution status of the function.
osStatus osTimerDelete (osTimerId timer_id);
// ==== Signal Management ====
/// Set the specified Signal Flags of an active thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
/// \param[in] signals specifies the signal flags of the thread that should be set.
/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
int32_t osSignalSet (osThreadId thread_id, int32_t signals);
/// Clear the specified Signal Flags of an active thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
/// \param[in] signals specifies the signal flags of the thread that shall be cleared.
/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters or call from ISR.
int32_t osSignalClear (osThreadId thread_id, int32_t signals);
/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag.
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return event flag information or error code.
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define osSignalWait __osSignalWait
osEvent __osSignalWait (int32_t signals, uint32_t millisec);
#else
os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec);
#endif
// ==== Mutex Management ====
/// Define a Mutex.
/// \param name name of the mutex object.
#if defined (osObjectsExternal) // object is external
#define osMutexDef(name) \
extern const osMutexDef_t os_mutex_def_##name
#else // define the object
#define osMutexDef(name) \
uint32_t os_mutex_cb_##name[4] = { 0 }; \
const osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) }
#endif
/// Access a Mutex definition.
/// \param name name of the mutex object.
#define osMutex(name) \
&os_mutex_def_##name
/// Create and Initialize a Mutex object.
/// \param[in] mutex_def mutex definition referenced with \ref osMutex.
/// \return mutex ID for reference by other functions or NULL in case of error.
osMutexId osMutexCreate (const osMutexDef_t *mutex_def);
/// Wait until a Mutex becomes available.
/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return status code that indicates the execution status of the function.
osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec);
/// Release a Mutex that was obtained by \ref osMutexWait.
/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
/// \return status code that indicates the execution status of the function.
osStatus osMutexRelease (osMutexId mutex_id);
/// Delete a Mutex that was created by \ref osMutexCreate.
/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
/// \return status code that indicates the execution status of the function.
osStatus osMutexDelete (osMutexId mutex_id);
// ==== Semaphore Management Functions ====
#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available
/// Define a Semaphore object.
/// \param name name of the semaphore object.
#if defined (osObjectsExternal) // object is external
#define osSemaphoreDef(name) \
extern const osSemaphoreDef_t os_semaphore_def_##name
#else // define the object
#define osSemaphoreDef(name) \
uint32_t os_semaphore_cb_##name[2] = { 0 }; \
const osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) }
#endif
/// Access a Semaphore definition.
/// \param name name of the semaphore object.
#define osSemaphore(name) \
&os_semaphore_def_##name
/// Create and Initialize a Semaphore object used for managing resources.
/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore.
/// \param[in] count number of available resources.
/// \return semaphore ID for reference by other functions or NULL in case of error.
osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count);
/// Wait until a Semaphore token becomes available.
/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return number of available tokens, or -1 in case of incorrect parameters.
int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec);
/// Release a Semaphore token.
/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
/// \return status code that indicates the execution status of the function.
osStatus osSemaphoreRelease (osSemaphoreId semaphore_id);
/// Delete a Semaphore that was created by \ref osSemaphoreCreate.
/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
/// \return status code that indicates the execution status of the function.
osStatus osSemaphoreDelete (osSemaphoreId semaphore_id);
#endif // Semaphore available
// ==== Memory Pool Management Functions ====
#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available
/// \brief Define a Memory Pool.
/// \param name name of the memory pool.
/// \param no maximum number of blocks (objects) in the memory pool.
/// \param type data type of a single block (object).
#if defined (osObjectsExternal) // object is external
#define osPoolDef(name, no, type) \
extern const osPoolDef_t os_pool_def_##name
#else // define the object
#define osPoolDef(name, no, type) \
uint32_t os_pool_m_##name[3+((sizeof(type)+3)/4)*(no)]; \
const osPoolDef_t os_pool_def_##name = \
{ (no), sizeof(type), (os_pool_m_##name) }
#endif
/// \brief Access a Memory Pool definition.
/// \param name name of the memory pool
#define osPool(name) \
&os_pool_def_##name
/// Create and Initialize a memory pool.
/// \param[in] pool_def memory pool definition referenced with \ref osPool.
/// \return memory pool ID for reference by other functions or NULL in case of error.
osPoolId osPoolCreate (const osPoolDef_t *pool_def);
/// Allocate a memory block from a memory pool.
/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
/// \return address of the allocated memory block or NULL in case of no memory available.
void *osPoolAlloc (osPoolId pool_id);
/// Allocate a memory block from a memory pool and set memory block to zero.
/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
/// \return address of the allocated memory block or NULL in case of no memory available.
void *osPoolCAlloc (osPoolId pool_id);
/// Return an allocated memory block back to a specific memory pool.
/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
/// \param[in] block address of the allocated memory block that is returned to the memory pool.
/// \return status code that indicates the execution status of the function.
osStatus osPoolFree (osPoolId pool_id, void *block);
#endif // Memory Pool Management available
// ==== Message Queue Management Functions ====
#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available
/// \brief Create a Message Queue Definition.
/// \param name name of the queue.
/// \param queue_sz maximum number of messages in the queue.
/// \param type data type of a single message element (for debugger).
#if defined (osObjectsExternal) // object is external
#define osMessageQDef(name, queue_sz, type) \
extern const osMessageQDef_t os_messageQ_def_##name
#else // define the object
#define osMessageQDef(name, queue_sz, type) \
uint32_t os_messageQ_q_##name[4+(queue_sz)] = { 0 }; \
const osMessageQDef_t os_messageQ_def_##name = \
{ (queue_sz), (os_messageQ_q_##name) }
#endif
/// \brief Access a Message Queue Definition.
/// \param name name of the queue
#define osMessageQ(name) \
&os_messageQ_def_##name
/// Create and Initialize a Message Queue.
/// \param[in] queue_def queue definition referenced with \ref osMessageQ.
/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
/// \return message queue ID for reference by other functions or NULL in case of error.
osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
/// Put a Message to a Queue.
/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate.
/// \param[in] info message information.
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return status code that indicates the execution status of the function.
osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
/// Get a Message or Wait for a Message from a Queue.
/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate.
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return event information that includes status code.
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define osMessageGet __osMessageGet
osEvent __osMessageGet (osMessageQId queue_id, uint32_t millisec);
#else
os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec);
#endif
#endif // Message Queues available
// ==== Mail Queue Management Functions ====
#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available
/// \brief Create a Mail Queue Definition.
/// \param name name of the queue
/// \param queue_sz maximum number of messages in queue
/// \param type data type of a single message element
#if defined (osObjectsExternal) // object is external
#define osMailQDef(name, queue_sz, type) \
extern const osMailQDef_t os_mailQ_def_##name
#else // define the object
#define osMailQDef(name, queue_sz, type) \
uint32_t os_mailQ_q_##name[4+(queue_sz)] = { 0 }; \
uint32_t os_mailQ_m_##name[3+((sizeof(type)+3)/4)*(queue_sz)]; \
void * os_mailQ_p_##name[2] = { (os_mailQ_q_##name), os_mailQ_m_##name }; \
const osMailQDef_t os_mailQ_def_##name = \
{ (queue_sz), sizeof(type), (os_mailQ_p_##name) }
#endif
/// \brief Access a Mail Queue Definition.
/// \param name name of the queue
#define osMailQ(name) \
&os_mailQ_def_##name
/// Create and Initialize mail queue.
/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ
/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
/// \return mail queue ID for reference by other functions or NULL in case of error.
osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id);
/// Allocate a memory block from a mail.
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
/// \return pointer to memory block that can be filled with mail or NULL in case of error.
void *osMailAlloc (osMailQId queue_id, uint32_t millisec);
/// Allocate a memory block from a mail and set memory block to zero.
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
/// \return pointer to memory block that can be filled with mail or NULL in case of error.
void *osMailCAlloc (osMailQId queue_id, uint32_t millisec);
/// Put a mail to a queue.
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
/// \return status code that indicates the execution status of the function.
osStatus osMailPut (osMailQId queue_id, void *mail);
/// Get a mail from a queue.
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out
/// \return event that contains mail information or error code.
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define osMailGet __osMailGet
osEvent __osMailGet (osMailQId queue_id, uint32_t millisec);
#else
os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec);
#endif
/// Free a memory block from a mail.
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet.
/// \return status code that indicates the execution status of the function.
osStatus osMailFree (osMailQId queue_id, void *mail);
#endif // Mail Queues available
// ==== RTX Extensions ====
/// Suspend the RTX task scheduler.
/// \return number of ticks, for how long the system can sleep or power-down.
uint32_t os_suspend (void);
/// Resume the RTX task scheduler.
/// \param[in] sleep_time specifies how long the system was in sleep or power-down mode.
void os_resume (uint32_t sleep_time);
/// OS idle demon (running when no other thread is ready to run).
__NO_RETURN void os_idle_demon (void);
/// OS error callback (called when a runtime error is detected).
/// \param[in] error_code actual error code that has been detected.
__NO_RETURN void os_error (uint32_t error_code);
#ifdef __cplusplus
}
#endif
#endif // _CMSIS_OS_H