diff --git a/libraries/net/lwip/lwip-sys/arch/sys_arch.c b/libraries/net/lwip/lwip-sys/arch/sys_arch.c index 8eead45b27..25e2f14ef5 100644 --- a/libraries/net/lwip/lwip-sys/arch/sys_arch.c +++ b/libraries/net/lwip/lwip-sys/arch/sys_arch.c @@ -285,7 +285,7 @@ void sys_sem_free(sys_sem_t *sem) {} * @return a new mutex */ err_t sys_mutex_new(sys_mutex_t *mutex) { #ifdef CMSIS_OS_RTX -#ifdef __MBED_CMSIS_RTOS_CA9 +#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) memset(mutex->data, 0, sizeof(int32_t)*4); #else memset(mutex->data, 0, sizeof(int32_t)*3); diff --git a/libraries/net/lwip/lwip-sys/arch/sys_arch.h b/libraries/net/lwip/lwip-sys/arch/sys_arch.h index 620b734b30..7678e24eab 100644 --- a/libraries/net/lwip/lwip-sys/arch/sys_arch.h +++ b/libraries/net/lwip/lwip-sys/arch/sys_arch.h @@ -40,7 +40,7 @@ typedef struct { osMutexId id; osMutexDef_t def; #ifdef CMSIS_OS_RTX -#ifdef __MBED_CMSIS_RTOS_CA9 +#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) int32_t data[4]; #else int32_t data[3]; diff --git a/libraries/rtos/rtos/Mutex.h b/libraries/rtos/rtos/Mutex.h index 5275339113..841d10a840 100644 --- a/libraries/rtos/rtos/Mutex.h +++ b/libraries/rtos/rtos/Mutex.h @@ -57,7 +57,7 @@ private: osMutexId _osMutexId; osMutexDef_t _osMutexDef; #ifdef CMSIS_OS_RTX -#ifdef __MBED_CMSIS_RTOS_CA9 +#if defined(__MBED_CMSIS_RTOS_CA9) || defined(__MBED_CMSIS_RTOS_CM) int32_t _mutex_data[4]; #else int32_t _mutex_data[3]; diff --git a/libraries/rtos/rtos/RtosTimer.h b/libraries/rtos/rtos/RtosTimer.h index 9e7004c84d..4fc2eae53b 100644 --- a/libraries/rtos/rtos/RtosTimer.h +++ b/libraries/rtos/rtos/RtosTimer.h @@ -61,8 +61,10 @@ public: private: osTimerId _timer_id; osTimerDef_t _timer; -#ifdef CMSIS_OS_RTX +#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) uint32_t _timer_data[5]; +#else + uint32_t _timer_data[6]; #endif }; diff --git a/libraries/rtos/rtos/Thread.cpp b/libraries/rtos/rtos/Thread.cpp index 2f6d002ed1..3af476ce60 100644 --- a/libraries/rtos/rtos/Thread.cpp +++ b/libraries/rtos/rtos/Thread.cpp @@ -24,11 +24,17 @@ #include "mbed_error.h" #include "rtos_idle.h" +// rt_tid2ptcb is an internal function which we exposed to get TCB for thread id +#undef NULL //Workaround for conflicting macros in rt_TypeDef.h and stdio.h +#include "rt_TypeDef.h" + +extern "C" P_TCB rt_tid2ptcb(osThreadId thread_id); + namespace rtos { Thread::Thread(void (*task)(void const *argument), void *argument, osPriority priority, uint32_t stack_size, unsigned char *stack_pointer) { -#ifdef CMSIS_OS_RTX +#ifdef __MBED_CMSIS_RTOS_CM _thread_def.pthread = task; _thread_def.tpriority = priority; _thread_def.stacksize = stack_size; @@ -71,8 +77,10 @@ int32_t Thread::signal_clr(int32_t signals) { } Thread::State Thread::get_state() { -#ifndef __MBED_CMSIS_RTOS_CA9 +#if !defined(__MBED_CMSIS_RTOS_CA9) && !defined(__MBED_CMSIS_RTOS_CM) +#ifdef CMSIS_OS_RTX return ((State)_thread_def.tcb.state); +#endif #else uint8_t status; status = osThreadGetState(_tid); @@ -82,7 +90,12 @@ Thread::State Thread::get_state() { uint32_t Thread::stack_size() { #ifndef __MBED_CMSIS_RTOS_CA9 +#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) return _thread_def.tcb.priv_stack; +#else + P_TCB tcb = rt_tid2ptcb(_tid); + return tcb->priv_stack; +#endif #else return 0; #endif @@ -90,8 +103,14 @@ uint32_t Thread::stack_size() { uint32_t Thread::free_stack() { #ifndef __MBED_CMSIS_RTOS_CA9 +#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) uint32_t bottom = (uint32_t)_thread_def.tcb.stack; return _thread_def.tcb.tsk_stack - bottom; +#else + P_TCB tcb = rt_tid2ptcb(_tid); + uint32_t bottom = (uint32_t)tcb->stack; + return tcb->tsk_stack - bottom; +#endif #else return 0; #endif @@ -99,8 +118,14 @@ uint32_t Thread::free_stack() { uint32_t Thread::used_stack() { #ifndef __MBED_CMSIS_RTOS_CA9 +#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) uint32_t top = (uint32_t)_thread_def.tcb.stack + _thread_def.tcb.priv_stack; return top - _thread_def.tcb.tsk_stack; +#else + P_TCB tcb = rt_tid2ptcb(_tid); + uint32_t top = (uint32_t)tcb->stack + tcb->priv_stack; + return top - tcb->tsk_stack; +#endif #else return 0; #endif @@ -108,10 +133,18 @@ uint32_t Thread::used_stack() { uint32_t Thread::max_stack() { #ifndef __MBED_CMSIS_RTOS_CA9 +#if defined(CMSIS_OS_RTX) && !defined(__MBED_CMSIS_RTOS_CM) uint32_t high_mark = 0; while (_thread_def.tcb.stack[high_mark] == 0xE25A2EA5) high_mark++; return _thread_def.tcb.priv_stack - (high_mark * 4); +#else + P_TCB tcb = rt_tid2ptcb(_tid); + uint32_t high_mark = 0; + while (tcb->stack[high_mark] == 0xE25A2EA5) + high_mark++; + return tcb->priv_stack - (high_mark * 4); +#endif #else return 0; #endif @@ -139,9 +172,11 @@ void Thread::attach_idle_hook(void (*fptr)(void)) { Thread::~Thread() { terminate(); +#ifdef __MBED_CMSIS_RTOS_CM if (_dynamic_stack) { delete[] (_thread_def.stack_pointer); } +#endif } } diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/HAL_CM.c b/libraries/rtos/rtx/TARGET_CORTEX_M/HAL_CM.c index efbe04c68f..97e12b1ddd 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/HAL_CM.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/HAL_CM.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: HAL_CM.C * Purpose: Hardware Abstraction Layer for Cortex-M - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_HAL_CM.h" @@ -58,12 +58,15 @@ void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { /* Prepare a complete interrupt frame for first task start */ size = p_TCB->priv_stack >> 2; + if (size == 0U) { + size = (U16)os_stackinfo >> 2; + } /* Write to the top of stack. */ stk = &p_TCB->stack[size]; /* Auto correct to 8-byte ARM stack alignment. */ - if ((U32)stk & 0x04) { + if ((U32)stk & 0x04U) { stk--; } @@ -74,8 +77,8 @@ void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { stk[14] = (U32)task_body; /* Clear R4-R11,R0-R3,R12,LR registers. */ - for (i = 0; i < 14; i++) { - stk[i] = 0; + for (i = 0U; i < 14U; i++) { + stk[i] = 0U; } /* Assign a void pointer to R0. */ @@ -87,13 +90,49 @@ void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { /* Task entry point. */ p_TCB->ptask = task_body; + +#ifdef __MBED_CMSIS_RTOS_CM /* Set a magic word for checking of stack overflow. - For the main thread (ID: 0x01) the stack is in a memory area shared with the + For the main thread (ID: 0x02) the stack is in a memory area shared with the heap, therefore the last word of the stack is a moving target. We want to do stack/heap collision detection instead. + Similar applies to stack filling for the magic pattern. */ - if (p_TCB->task_id != 0x01) - p_TCB->stack[0] = MAGIC_WORD; + if (p_TCB->task_id != 0x02) { + p_TCB->stack[0] = MAGIC_WORD; + + /* Initialize stack with magic pattern. */ + if (os_stackinfo & 0x10000000U) { + if (size > (16U+1U)) { + for (i = ((size - 16U)/2U) - 1U; i; i--) { + stk -= 2U; + stk[1] = MAGIC_PATTERN; + stk[0] = MAGIC_PATTERN; + } + if (--stk > p_TCB->stack) { + *stk = MAGIC_PATTERN; + } + } + } + } +#else + /* Initialize stack with magic pattern. */ + if (os_stackinfo & 0x10000000U) { + if (size > (16U+1U)) { + for (i = ((size - 16U)/2U) - 1U; i; i--) { + stk -= 2U; + stk[1] = MAGIC_PATTERN; + stk[0] = MAGIC_PATTERN; + } + if (--stk > p_TCB->stack) { + *stk = MAGIC_PATTERN; + } + } + } + + /* Set a magic word for checking of stack overflow. */ + p_TCB->stack[0] = MAGIC_WORD; +#endif } @@ -101,17 +140,17 @@ void rt_init_stack (P_TCB p_TCB, FUNCP task_body) { static __inline U32 *rt_ret_regs (P_TCB p_TCB) { /* Get pointer to task return value registers (R0..R3) in Stack */ -#if (__TARGET_FPU_VFP) +#if defined(__TARGET_FPU_VFP) if (p_TCB->stack_frame) { /* Extended Stack Frame: R4-R11,S16-S31,R0-R3,R12,LR,PC,xPSR,S0-S15,FPSCR */ - return (U32 *)(p_TCB->tsk_stack + 8*4 + 16*4); + return (U32 *)(p_TCB->tsk_stack + (8U*4U) + (16U*4U)); } else { /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + 8*4); + return (U32 *)(p_TCB->tsk_stack + (8U*4U)); } #else /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */ - return (U32 *)(p_TCB->tsk_stack + 8*4); + return (U32 *)(p_TCB->tsk_stack + (8U*4U)); #endif } @@ -135,9 +174,9 @@ void rt_ret_val2(P_TCB p_TCB, U32 v0, U32 v1) { #ifdef DBG_MSG void dbg_init (void) { - if ((DEMCR & DEMCR_TRCENA) && - (ITM_CONTROL & ITM_ITMENA) && - (ITM_ENABLE & (1UL << 31))) { + if (((DEMCR & DEMCR_TRCENA) != 0U) && + ((ITM_CONTROL & ITM_ITMENA) != 0U) && + ((ITM_ENABLE & (1UL << 31)) != 0U)) { dbg_msg = __TRUE; } } @@ -147,10 +186,10 @@ void dbg_init (void) { #ifdef DBG_MSG void dbg_task_notify (P_TCB p_tcb, BOOL create) { - while (ITM_PORT31_U32 == 0); + while (ITM_PORT31_U32 == 0U); ITM_PORT31_U32 = (U32)p_tcb->ptask; - while (ITM_PORT31_U32 == 0); - ITM_PORT31_U16 = (create << 8) | p_tcb->task_id; + while (ITM_PORT31_U32 == 0U); + ITM_PORT31_U16 = (U16)((create << 8) | p_tcb->task_id); } #endif @@ -158,13 +197,11 @@ void dbg_task_notify (P_TCB p_tcb, BOOL create) { #ifdef DBG_MSG void dbg_task_switch (U32 task_id) { - while (ITM_PORT31_U32 == 0); - ITM_PORT31_U8 = task_id; + while (ITM_PORT31_U32 == 0U); + ITM_PORT31_U8 = (U8)task_id; } #endif - /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/ - diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h b/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h index bf676375a7..5f5970f13b 100755 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_CM_lib.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RTX_CM_LIB.H * Purpose: RTX Kernel System Configuration - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -51,21 +51,22 @@ #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 48 +#define OS_TCB_SIZE 52 #define OS_TMR_SIZE 8 #if defined (__CC_ARM) && !defined (__MICROLIB) typedef void *OS_ID; typedef uint32_t OS_TID; -typedef uint32_t OS_MUT[3]; +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,0xFFFF) +#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); @@ -84,24 +85,68 @@ OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indi * 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) +#ifndef __MBED_CMSIS_RTOS_CM +#define OS_PRIV_CNT (OS_PRIVCNT + 2) +#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ)) +#endif #else #define OS_TASK_CNT OS_TASKCNT +#ifndef __MBED_CMSIS_RTOS_CM +#define OS_PRIV_CNT (OS_PRIVCNT + 1) +#define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE)) +#endif +#endif + +#ifndef OS_STKINIT +#define OS_STKINIT 0 #endif uint16_t const os_maxtaskrun = OS_TASK_CNT; +#ifdef __MBED_CMSIS_RTOS_CM +uint32_t const os_stackinfo = (OS_STKINIT<<28) | (OS_STKCHECK<<24) | (OS_IDLESTKSIZE*4); +#else +uint32_t const os_stackinfo = (OS_STKINIT<<28) | (OS_STKCHECK<<24) | (OS_PRIV_CNT<<16) | (OS_STKSIZE*4); +#endif 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. */ +__USED uint32_t const CMSIS_RTOS_API_Version = osCMSIS; +__USED uint32_t const CMSIS_RTOS_RTX_Version = osCMSIS_RTX; __USED uint32_t const os_clockrate = OS_TICK; -__USED uint32_t const os_timernum = 0; +__USED uint32_t const os_timernum = 0U; -/* Stack for the os_idle_demon */ -unsigned int idle_task_stack[OS_IDLESTKSIZE]; -unsigned short const idle_task_stack_size = OS_IDLESTKSIZE; +/* Memory pool for TCB allocation */ +_declare_box (mp_tcb, OS_TCB_SIZE, OS_TASK_CNT); +uint16_t const mp_tcb_size = sizeof(mp_tcb); + +#ifdef __MBED_CMSIS_RTOS_CM +/* Memory pool for os_idle_demon stack allocation. */ +_declare_box8 (mp_stk, OS_IDLESTKSIZE*4, 1); +uint32_t const mp_stk_size = sizeof(mp_stk); +#else +/* Memory pool for System stack allocation (+os_idle_demon). */ +_declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1); +uint32_t const mp_stk_size = sizeof(mp_stk); + +/* Memory pool for user specified stack allocation (+main, +timer) */ +uint64_t os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)]; +uint32_t const os_stack_sz = sizeof(os_stack_mem); +#endif #ifndef OS_FIFOSZ #define OS_FIFOSZ 16 @@ -117,17 +162,34 @@ void *os_active_TCB[OS_TASK_CNT]; /* User Timers Resources */ #if (OS_TIMERS != 0) extern void osTimerThread (void const *argument); +#ifdef __MBED_CMSIS_RTOS_CM osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ); +#else +osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ); +#endif osThreadId osThreadId_osTimerThread; osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *); osMessageQId osMessageQId_osTimerMessageQ; #else osThreadDef_t os_thread_def_osTimerThread = { NULL }; osThreadId osThreadId_osTimerThread; -osMessageQDef(osTimerMessageQ, 0, void *); +osMessageQDef(osTimerMessageQ, 0U, void *); osMessageQId osMessageQId_osTimerMessageQ; #endif +/* Legacy RTX User Timers not used */ +uint32_t os_tmr = 0U; +uint32_t const *m_tmr = NULL; +uint16_t const mp_tmr_size = 0U; + +#if defined (__CC_ARM) && !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) @@ -148,10 +210,22 @@ osMessageQId osMessageQId_osTimerMessageQ; *---------------------------------------------------------------------------*/ #if defined (__CC_ARM) && !defined (__MICROLIB) - static OS_MUT std_libmutex[OS_MUTEXCNT]; - static uint32_t nr_mutex; - /*--------------------------- _mutex_initialize -----------------------------*/ +/*--------------------------- __user_perthread_libspace ---------------------*/ + +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) { /* Allocate and initialize a system mutex. */ @@ -170,7 +244,7 @@ int _mutex_initialize (OS_ID *mutex) { __attribute__((used)) void _mutex_acquire (OS_ID *mutex) { /* Acquire a system mutex, lock stdlib resources. */ - if (runtask_id ()) { + if (os_running) { /* RTX running, acquire a mutex. */ mutex_wait (*mutex); } @@ -181,7 +255,7 @@ __attribute__((used)) void _mutex_acquire (OS_ID *mutex) { __attribute__((used)) void _mutex_release (OS_ID *mutex) { /* Release a system mutex, unlock stdlib resources. */ - if (runtask_id ()) { + if (os_running) { /* RTX running, release a mutex. */ mutex_rel (*mutex); } @@ -196,7 +270,7 @@ __attribute__((used)) void _mutex_release (OS_ID *mutex) { /* Main Thread definition */ extern int main (void); -osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 0, NULL}; +osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1U, 0U, NULL}; // This define should be probably moved to the CMSIS layer #if defined(TARGET_LPC1768) @@ -367,16 +441,19 @@ void set_main_stack(void) { // That is the bottom of the main stack block: no collision detection os_thread_def_main.stack_pointer = HEAP_START; - // Leave OS_SCHEDULERSTKSIZE words for the scheduler and interrupts - os_thread_def_main.stacksize = (INITIAL_SP - (unsigned int)HEAP_START) - (OS_SCHEDULERSTKSIZE * 4); + // Leave OS_MAINSTKSIZE words for the scheduler and interrupts + os_thread_def_main.stacksize = (INITIAL_SP - (unsigned int)HEAP_START) - (OS_MAINSTKSIZE * 4); } #if defined (__CC_ARM) + #ifdef __MICROLIB void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF"))); void _main_init (void) { osKernelInitialize(); +#ifdef __MBED_CMSIS_RTOS_CM set_main_stack(); +#endif osThreadCreate(&os_thread_def_main, NULL); osKernelStart(); for (;;); @@ -397,7 +474,9 @@ __asm void __rt_entry (void) { IMPORT __rt_lib_init IMPORT os_thread_def_main IMPORT osKernelInitialize +#ifdef __MBED_CMSIS_RTOS_CM IMPORT set_main_stack +#endif IMPORT osKernelStart IMPORT osThreadCreate IMPORT exit @@ -406,7 +485,9 @@ __asm void __rt_entry (void) { MOV R1,R2 BL __rt_lib_init BL osKernelInitialize +#ifdef __MBED_CMSIS_RTOS_CM BL set_main_stack +#endif LDR R0,=os_thread_def_main MOVS R1,#0 BL osThreadCreate @@ -415,6 +496,7 @@ __asm void __rt_entry (void) { ALIGN } + #endif #elif defined (__GNUC__) @@ -465,7 +547,9 @@ __attribute ((noreturn)) void __cs3_start_c (void){ __libc_init_array (); osKernelInitialize(); +#ifdef __MBED_CMSIS_RTOS_CM set_main_stack(); +#endif osThreadCreate(&os_thread_def_main, NULL); osKernelStart(); for (;;); @@ -487,7 +571,9 @@ __attribute__((naked)) void software_init_hook (void) { "mov r0,r4\n" "mov r1,r5\n" "bl osKernelInitialize\n" +#ifdef __MBED_CMSIS_RTOS_CM "bl set_main_stack\n" +#endif "ldr r0,=os_thread_def_main\n" "movs r1,#0\n" "bl osThreadCreate\n" @@ -512,6 +598,7 @@ extern void exit(int arg); #pragma required=__vector_table void __iar_program_start( void ) { +#ifdef __MBED_CMSIS_RTOS_CM __iar_init_core(); __iar_init_vfp(); @@ -522,8 +609,11 @@ void __iar_program_start( void ) mbed_sdk_init(); __iar_dynamic_initialization(); } +#endif osKernelInitialize(); +#ifdef __MBED_CMSIS_RTOS_CM set_main_stack(); +#endif osThreadCreate(&os_thread_def_main, NULL); a = osKernelStart(); exit(a); diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c b/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c index cad4e04bfe..5adfa364f5 100755 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_Conf_CM.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RTX_Conf_CM.C * Purpose: Configuration of CMSIS RTX Kernel for Cortex-M - * Rev.: V4.60 + * Rev.: V4.70.1 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -44,9 +44,8 @@ // Thread Configuration // ======================= // -// Number of concurrent running threads <0-250> -// Defines max. number of threads that will run at the same time. -// counting "main", but not counting "osTimerThread" +// Number of concurrent running user threads <1-250> +// Defines max. number of user threads that will run at the same time. // Default: 6 #ifndef OS_TASKCNT # if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) || defined(TARGET_LPC4330) || defined(TARGET_LPC4337) || defined(TARGET_LPC1347) || defined(TARGET_K64F) || defined(TARGET_STM32F401RE)\ @@ -65,60 +64,93 @@ # endif #endif -// Scheduler (+ interrupts) stack size [bytes] <64-4096:8><#/4> -#ifndef OS_SCHEDULERSTKSIZE +#ifdef __MBED_CMSIS_RTOS_CM +// Idle stack size [bytes] <64-4096:8><#/4> +// Defines default stack size for the Idle thread. +#ifndef OS_IDLESTKSIZE + #define OS_IDLESTKSIZE 128 +#endif +#else // __MBED_CMSIS_RTOS_CM +// Default Thread stack size [bytes] <64-4096:8><#/4> +// Defines default stack size for threads with osThreadDef stacksz = 0 +// Default: 200 +#ifndef OS_STKSIZE + #define OS_STKSIZE 200 +#endif +#endif // __MBED_CMSIS_RTOS_CM + +// Main Thread stack size [bytes] <64-32768:8><#/4> +#ifndef OS_MAINSTKSIZE # if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_LPC4088) || defined(TARGET_LPC4088_DM) || defined(TARGET_LPC4330) || defined(TARGET_LPC4337) || defined(TARGET_LPC1347) || defined(TARGET_K64F) || defined(TARGET_STM32F401RE)\ || defined(TARGET_STM32F410RB) || defined(TARGET_KL46Z) || defined(TARGET_KL43Z) || defined(TARGET_STM32F407) || defined(TARGET_F407VG) || defined(TARGET_STM32F303VC) || defined(TARGET_LPC1549) || defined(TARGET_LPC11U68) \ || defined(TARGET_STM32F411RE) || defined(TARGET_STM32F405RG) || defined(TARGET_K22F) || defined(TARGET_STM32F429ZI) || defined(TARGET_STM32F401VC) || defined(TARGET_MAX32610) || defined(TARGET_MAX32600) || defined(TARGET_TEENSY3_1) \ || defined(TARGET_STM32L152RE) || defined(TARGET_STM32F446RE) || defined(TARGET_STM32F446VE) || defined(TARGET_STM32L476VG) || defined(TARGET_STM32L476RG) || defined(TARGET_STM32F469NI) || defined(TARGET_STM32F746NG) || defined(TARGET_STM32F746ZG) || defined(TARGET_STM32L152RC) -# define OS_SCHEDULERSTKSIZE 256 +# define OS_MAINSTKSIZE 256 # elif defined(TARGET_LPC11U24) || defined(TARGET_LPC11U35_401) || defined(TARGET_LPC11U35_501) || defined(TARGET_LPCCAPPUCCINO) || defined(TARGET_LPC1114) \ || defined(TARGET_LPC812) || defined(TARGET_KL25Z) || defined(TARGET_KL26Z) || defined(TARGET_KL27Z) || defined(TARGET_KL05Z) || defined(TARGET_STM32F100RB) || defined(TARGET_STM32F051R8) \ || defined(TARGET_STM32F103RB) || defined(TARGET_LPC824) || defined(TARGET_STM32F302R8) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F091RC) || defined(TARGET_NZ32_SC151) \ || defined(TARGET_SSCI824) || defined(TARGET_STM32F030R8) || defined(TARGET_STM32F070RB) -# define OS_SCHEDULERSTKSIZE 128 +# define OS_MAINSTKSIZE 128 # elif defined(TARGET_STM32F334R8) || defined(TARGET_STM32F303RE) || defined(TARGET_STM32F303K8) || defined(TARGET_STM32F334C8) || defined(TARGET_STM32L031K6) || defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8) || defined(TARGET_STM32L073RZ) -# define OS_SCHEDULERSTKSIZE 112 +# define OS_MAINSTKSIZE 112 # else # error "no target defined" # endif #endif -// Idle stack size [bytes] <64-4096:8><#/4> -// Defines default stack size for the Idle thread. -#ifndef OS_IDLESTKSIZE - #define OS_IDLESTKSIZE 128 +#ifndef __MBED_CMSIS_RTOS_CM +// Number of threads with user-provided stack size <0-250> +// Defines the number of threads with user-provided stack size. +// Default: 0 +#ifndef OS_PRIVCNT + #define OS_PRIVCNT 0 #endif - -// Timer Thread stack size [bytes] <64-4096:8><#/4> -// Defines stack size for Timer thread. -// Default: 200 -#ifndef OS_TIMERSTKSZ - #define OS_TIMERSTKSZ WORDS_STACK_SIZE + +// Total stack size [bytes] for threads with user-provided stack size <0-1048576:8><#/4> +// Defines the combined stack size for threads with user-provided stack size. +// Default: 0 +#ifndef OS_PRIVSTKSIZE + #define OS_PRIVSTKSIZE 0 // this stack size value is in words #endif +#endif // __MBED_CMSIS_RTOS_CM -// Check for stack overflow -// Includes the stack checking code for stack overflow. -// Note that additional code reduces the Kernel performance. +// Stack overflow checking +// Enable stack overflow checks at thread switch. +// Enabling this option increases slightly the execution time of a thread switch. #ifndef OS_STKCHECK #define OS_STKCHECK 1 #endif - -// Processor mode for thread execution -// <0=> Unprivileged mode -// <1=> Privileged mode -// Default: Privileged mode + +// Stack usage watermark +// Initialize thread stack with watermark pattern for analyzing stack usage (current/maximum) in System and Thread Viewer. +// Enabling this option increases significantly the execution time of osThreadCreate. +#ifndef OS_STKINIT +#define OS_STKINIT 0 +#endif + +// Processor mode for thread execution +// <0=> Unprivileged mode +// <1=> Privileged mode +// Default: Privileged mode #ifndef OS_RUNPRIV #define OS_RUNPRIV 1 #endif // -// SysTick Timer Configuration -// ============================== + +// RTX Kernel Timer Tick Configuration +// ====================================== +// Use Cortex-M SysTick timer as RTX Kernel Timer +// Cortex-M processors provide in most cases a SysTick timer that can be used as +// as time-base for RTX. +#ifndef OS_SYSTICK + #define OS_SYSTICK 1 +#endif // -// Timer clock value [Hz] <1-1000000000> -// Defines the timer clock value. -// Default: 6000000 (6MHz) +// RTOS Kernel Timer input clock frequency [Hz] <1-1000000000> +// Defines the input frequency of the RTOS Kernel Timer. +// When the Cortex-M SysTick timer is used, the input clock +// is on most systems identical with the core clock. #ifndef OS_CLOCK # if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) || defined(TARGET_TEENSY3_1) # define OS_CLOCK 96000000 @@ -212,9 +244,10 @@ # error "no target defined" # endif #endif - -// Timer tick value [us] <1-1000000> -// Defines the timer tick value. + +// RTX Timer tick interval value [us] <1-1000000> +// The RTX Timer tick interval value is used to calculate timeout values. +// When the Cortex-M SysTick timer is enabled, the value also configures the SysTick timer. // Default: 1000 (1ms) #ifndef OS_TICK #define OS_TICK 1000 @@ -251,9 +284,7 @@ // Timer Thread Priority // <1=> Low -// <2=> Below Normal -// <3=> Normal -// <4=> Above Normal +// <2=> Below Normal <3=> Normal <4=> Above Normal // <5=> High // <6=> Realtime (highest) // Defines priority for Timer Thread @@ -261,11 +292,18 @@ #ifndef OS_TIMERPRIO #define OS_TIMERPRIO 5 #endif - + +// Timer Thread stack size [bytes] <64-4096:8><#/4> +// Defines stack size for Timer thread. +// Default: 200 +#ifndef OS_TIMERSTKSZ + #define OS_TIMERSTKSZ 200 +#endif + // Timer Callback Queue size <1-32> // Number of concurrent active timer callback functions. // Default: 4 -#ifndef OS_TIMERCBQSZ +#ifndef OS_TIMERCBQS #define OS_TIMERCBQS 4 #endif @@ -316,12 +354,16 @@ void os_idle_demon (void) { /*---------------------------------------------------------------------------- * RTX Errors *---------------------------------------------------------------------------*/ -extern void mbed_die(void); +extern void error(const char* format, ...); +extern osThreadId svcThreadGetId (void); + +#include "stdio.h" void os_error (uint32_t err_code) { /* This function is called when a runtime error is detected. Parameter */ - /* 'err_code' holds the runtime error code (defined in RTX_Conf.h). */ - mbed_die(); + /* 'err_code' holds the runtime error code (defined in RTX_Config.h). */ + osThreadId err_task = svcThreadGetId(); + error("CMSIS RTX error code: 0x%08X, task ID: 0x%08X\n", err_code, (uint32_t)err_task); } void sysThreadError(osStatus status) { diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_Conf.h b/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_Config.h similarity index 79% rename from libraries/rtos/rtx/TARGET_CORTEX_M/RTX_Conf.h rename to libraries/rtos/rtx/TARGET_CORTEX_M/RTX_Config.h index 0b0d4613cd..d6f5161c47 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_Conf.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/RTX_Config.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RTX_CONFIG.H * Purpose: Exported functions of RTX_Config.c - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -15,37 +15,39 @@ * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without * specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *---------------------------------------------------------------------------*/ /* Error Codes */ -#define OS_ERR_STK_OVF 1 -#define OS_ERR_FIFO_OVF 2 -#define OS_ERR_MBX_OVF 3 +#define OS_ERR_STK_OVF 1U +#define OS_ERR_FIFO_OVF 2U +#define OS_ERR_MBX_OVF 3U +#define OS_ERR_TIMER_OVF 4U /* Definitions */ -#define BOX_ALIGN_8 0x80000000 +#define BOX_ALIGN_8 0x80000000U #define _declare_box(pool,size,cnt) U32 pool[(((size)+3)/4)*(cnt) + 3] #define _declare_box8(pool,size,cnt) U64 pool[(((size)+7)/8)*(cnt) + 2] #define _init_box8(pool,size,bsize) _init_box (pool,size,(bsize) | BOX_ALIGN_8) /* Variables */ -extern U32 idle_task_stack[]; +extern U32 mp_tcb[]; +extern U64 mp_stk[]; extern U32 os_fifo[]; extern void *os_active_TCB[]; @@ -53,16 +55,21 @@ extern void *os_active_TCB[]; extern U16 const os_maxtaskrun; extern U32 const os_trv; extern U8 const os_flags; +extern U32 const os_stackinfo; extern U32 const os_rrobin; extern U32 const os_clockrate; extern U32 const os_timernum; -extern U16 const idle_task_stack_size; - +extern U16 const mp_tcb_size; +extern U32 const mp_stk_size; +extern U32 const *m_tmr; +extern U16 const mp_tmr_size; extern U8 const os_fifo_size; /* Functions */ extern void os_idle_demon (void); -extern int os_tick_init (void); +extern S32 os_tick_init (void); +extern U32 os_tick_val (void); +extern U32 os_tick_ovf (void); extern void os_tick_irqack (void); extern void os_tmr_call (U16 info); extern void os_error (U32 err_code); diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c index 492e94a197..59351c2e23 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/HAL_CM0.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: HAL_CM0.C * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_System.h" #include "rt_HAL_CM.h" #include "rt_Task.h" @@ -106,7 +106,7 @@ PrivilegedA /*--------------------------- _free_box -------------------------------------*/ -__asm int _free_box (void *box_mem, void *box) { +__asm U32 _free_box (void *box_mem, void *box) { /* Function wrapper for Unprivileged/Privileged mode. */ LDR R3,=__cpp(rt_free_box) MOV R12,R3 diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S index 78c39bbe40..3ba439bca8 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_ARM/SVC_Table.S @@ -1,9 +1,9 @@ ;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX +; * CMSIS-RTOS - RTX ; *---------------------------------------------------------------------------- ; * Name: SVC_TABLE.S ; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 +; * Rev.: V4.70 ; *---------------------------------------------------------------------------- ; * ; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S index ce4c3d7f24..a9f1ff17c0 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/HAL_CM0.S @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: HAL_CM0.S * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,7 +35,7 @@ .file "HAL_CM0.S" .syntax unified - .equ TCB_TSTACK, 40 + .equ TCB_TSTACK, 44 /*---------------------------------------------------------------------------- @@ -145,7 +145,7 @@ PrivilegedA: /*--------------------------- _free_box -------------------------------------*/ -# int _free_box (void *box_mem, void *box); +# U32 _free_box (void *box_mem, void *box); /* Function wrapper for Unprivileged/Privileged mode. */ .thumb_func diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S index 6cafc0019f..d583df1332 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_GCC/SVC_Table.S @@ -1,12 +1,12 @@ ;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX +; * CMSIS-RTOS - RTX ; *---------------------------------------------------------------------------- ; * Name: SVC_TABLE.S ; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 +; * Rev.: V4.70 ; *---------------------------------------------------------------------------- ; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH ; * All rights reserved. ; * Redistribution and use in source and binary forms, with or without ; * modification, are permitted provided that the following conditions are met: diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S index c39fcdd397..d0dc85374c 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0/TOOLCHAIN_IAR/HAL_CM0.S @@ -34,7 +34,7 @@ NAME HAL_CM0.S - #define TCB_TSTACK 40 + #define TCB_TSTACK 44 EXTERN os_flags EXTERN os_tsk @@ -123,7 +123,7 @@ PrivilegedA: /*--------------------------- _free_box -------------------------------------*/ -; int _free_box (void *box_mem, void *box); +; U32 _free_box (void *box_mem, void *box); /* Function wrapper for Unprivileged/Privileged mode. */ PUBLIC _free_box diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c index 492e94a197..59351c2e23 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/HAL_CM0.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: HAL_CM0.C * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_System.h" #include "rt_HAL_CM.h" #include "rt_Task.h" @@ -106,7 +106,7 @@ PrivilegedA /*--------------------------- _free_box -------------------------------------*/ -__asm int _free_box (void *box_mem, void *box) { +__asm U32 _free_box (void *box_mem, void *box) { /* Function wrapper for Unprivileged/Privileged mode. */ LDR R3,=__cpp(rt_free_box) MOV R12,R3 diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S index 78c39bbe40..3ba439bca8 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_ARM/SVC_Table.S @@ -1,9 +1,9 @@ ;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX +; * CMSIS-RTOS - RTX ; *---------------------------------------------------------------------------- ; * Name: SVC_TABLE.S ; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 +; * Rev.: V4.70 ; *---------------------------------------------------------------------------- ; * ; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S index ce4c3d7f24..a9f1ff17c0 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/HAL_CM0.S @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: HAL_CM0.S * Purpose: Hardware Abstraction Layer for Cortex-M0 - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,7 +35,7 @@ .file "HAL_CM0.S" .syntax unified - .equ TCB_TSTACK, 40 + .equ TCB_TSTACK, 44 /*---------------------------------------------------------------------------- @@ -145,7 +145,7 @@ PrivilegedA: /*--------------------------- _free_box -------------------------------------*/ -# int _free_box (void *box_mem, void *box); +# U32 _free_box (void *box_mem, void *box); /* Function wrapper for Unprivileged/Privileged mode. */ .thumb_func diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S index 6cafc0019f..d583df1332 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_GCC/SVC_Table.S @@ -1,12 +1,12 @@ ;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX +; * CMSIS-RTOS - RTX ; *---------------------------------------------------------------------------- ; * Name: SVC_TABLE.S ; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 +; * Rev.: V4.70 ; *---------------------------------------------------------------------------- ; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH ; * All rights reserved. ; * Redistribution and use in source and binary forms, with or without ; * modification, are permitted provided that the following conditions are met: diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S index c39fcdd397..d0dc85374c 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M0P/TOOLCHAIN_IAR/HAL_CM0.S @@ -34,7 +34,7 @@ NAME HAL_CM0.S - #define TCB_TSTACK 40 + #define TCB_TSTACK 44 EXTERN os_flags EXTERN os_tsk @@ -123,7 +123,7 @@ PrivilegedA: /*--------------------------- _free_box -------------------------------------*/ -; int _free_box (void *box_mem, void *box); +; U32 _free_box (void *box_mem, void *box); /* Function wrapper for Unprivileged/Privileged mode. */ PUBLIC _free_box diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c index feb1457913..5c90f73608 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/HAL_CM3.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: HAL_CM3.C * Purpose: Hardware Abstraction Layer for Cortex-M3 - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_System.h" #include "rt_HAL_CM.h" #include "rt_Task.h" @@ -99,7 +99,7 @@ __asm void *_alloc_box (void *box_mem) { /*--------------------------- _free_box -------------------------------------*/ -__asm int _free_box (void *box_mem, void *box) { +__asm U32 _free_box (void *box_mem, void *box) { /* Function wrapper for Unprivileged/Privileged mode. */ LDR R12,=__cpp(rt_free_box) MRS R3,IPSR @@ -124,6 +124,11 @@ __asm void SVC_Handler (void) { IMPORT SVC_Table IMPORT rt_stk_check +#ifdef IFX_XMC4XXX + EXPORT SVC_Handler_Veneer +SVC_Handler_Veneer +#endif + MRS R0,PSP ; Read PSP LDR R1,[R0,#24] ; Read Saved PC from Stack LDRB R1,[R1,#-2] ; Load SVC Number @@ -157,7 +162,12 @@ SVC_Next SVC_Exit MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value +#ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} +#else BX LR +#endif /*------------------- User SVC ------------------------------*/ @@ -188,6 +198,11 @@ SVC_Done __asm void PendSV_Handler (void) { PRESERVE8 +#ifdef IFX_XMC4XXX + EXPORT PendSV_Handler_Veneer +PendSV_Handler_Veneer +#endif + BL __cpp(rt_pop_req) Sys_Switch @@ -212,7 +227,12 @@ Sys_Switch Sys_Exit MVN LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value +#ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} +#else BX LR ; Return to Thread Mode +#endif ALIGN } @@ -223,6 +243,11 @@ Sys_Exit __asm void SysTick_Handler (void) { PRESERVE8 +#ifdef IFX_XMC4XXX + EXPORT SysTick_Handler_Veneer +SysTick_Handler_Veneer +#endif + BL __cpp(rt_systick) B Sys_Switch diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S index 78c39bbe40..e1289a53bc 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_ARM/SVC_Table.S @@ -1,12 +1,12 @@ ;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX +; * CMSIS-RTOS - RTX ; *---------------------------------------------------------------------------- ; * Name: SVC_TABLE.S ; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 +; * Rev.: V4.70 ; *---------------------------------------------------------------------------- ; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH ; * All rights reserved. ; * Redistribution and use in source and binary forms, with or without ; * modification, are permitted provided that the following conditions are met: diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S index 5f12fd371d..e218b0559d 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/HAL_CM3.S @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: HAL_CM3.S * Purpose: Hardware Abstraction Layer for Cortex-M3 - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,7 +35,7 @@ .file "HAL_CM3.S" .syntax unified - .equ TCB_TSTACK, 40 + .equ TCB_TSTACK, 44 /*---------------------------------------------------------------------------- @@ -141,7 +141,7 @@ _alloc_box: /*--------------------------- _free_box -------------------------------------*/ -# int _free_box (void *box_mem, void *box); +# U32 _free_box (void *box_mem, void *box); /* Function wrapper for Unprivileged/Privileged mode. */ .thumb_func @@ -175,6 +175,10 @@ _free_box: .type SVC_Handler, %function .global SVC_Handler SVC_Handler: + .ifdef IFX_XMC4XXX + .global SVC_Handler_Veneer +SVC_Handler_Veneer: + .endif .fnstart .cantunwind @@ -211,7 +215,12 @@ SVC_Next: SVC_Exit: MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + .ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} + .else BX LR + .endif /*------------------- User SVC ------------------------------*/ @@ -246,6 +255,10 @@ SVC_Done: .global PendSV_Handler .global Sys_Switch PendSV_Handler: + .ifdef IFX_XMC4XXX + .global PendSV_Handler_Veneer +PendSV_Handler_Veneer: + .endif .fnstart .cantunwind @@ -273,7 +286,12 @@ Sys_Switch: Sys_Exit: MVN LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + .ifdef IFX_XMC4XXX + PUSH {LR} + POP {PC} + .else BX LR /* Return to Thread Mode */ + .endif .fnend .size PendSV_Handler, .-PendSV_Handler @@ -287,6 +305,10 @@ Sys_Exit: .type SysTick_Handler, %function .global SysTick_Handler SysTick_Handler: + .ifdef IFX_XMC4XXX + .global SysTick_Handler_Veneer +SysTick_Handler_Veneer: + .endif .fnstart .cantunwind diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S index 6cafc0019f..d583df1332 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_GCC/SVC_Table.S @@ -1,12 +1,12 @@ ;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX +; * CMSIS-RTOS - RTX ; *---------------------------------------------------------------------------- ; * Name: SVC_TABLE.S ; * Purpose: Pre-defined SVC Table for Cortex-M -; * Rev.: V4.60 +; * Rev.: V4.70 ; *---------------------------------------------------------------------------- ; * -; * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH +; * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH ; * All rights reserved. ; * Redistribution and use in source and binary forms, with or without ; * modification, are permitted provided that the following conditions are met: diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S index 57015af8a1..587cc089f2 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_M3/TOOLCHAIN_IAR/HAL_CM3.S @@ -1,5 +1,5 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: HAL_CM3.S * Purpose: Hardware Abstraction Layer for Cortex-M3 @@ -34,7 +34,7 @@ NAME HAL_CM3.S - #define TCB_TSTACK 40 + #define TCB_TSTACK 44 EXTERN os_flags EXTERN os_tsk @@ -119,7 +119,7 @@ _alloc_box: /*--------------------------- _free_box -------------------------------------*/ -; int _free_box (void *box_mem, void *box); +; U32 _free_box (void *box_mem, void *box); /* Function wrapper for Unprivileged/Privileged mode. */ PUBLIC _free_box diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c index 32327d83d0..e1366a006d 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/HAL_CM4.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: HAL_CM4.C * Purpose: Hardware Abstraction Layer for Cortex-M4 - * Rev.: V4.70 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_System.h" #include "rt_HAL_CM.h" #include "rt_Task.h" @@ -99,7 +99,7 @@ __asm void *_alloc_box (void *box_mem) { /*--------------------------- _free_box -------------------------------------*/ -__asm int _free_box (void *box_mem, void *box) { +__asm U32 _free_box (void *box_mem, void *box) { /* Function wrapper for Unprivileged/Privileged mode. */ LDR R12,=__cpp(rt_free_box) MRS R3,IPSR @@ -152,7 +152,17 @@ SVC_Handler_Veneer BXEQ LR ; RETI, no task switch #endif - CBZ R1,SVC_Next ; Runtask deleted? + CBNZ R1,SVC_ContextSave ; Runtask not deleted? + + TST LR,#0x10 ; is it extended frame? + BNE SVC_ContextRestore + LDR R1,=0xE000EF34 + LDR R0,[R1] ; Load FPCCR + BIC R0,#1 ; Clear LSPACT (Lazy state) + STR R0,[R1] ; Store FPCCR + B SVC_ContextRestore + +SVC_ContextSave TST LR,#0x10 ; is it extended frame? VSTMDBEQ R12!,{S16-S31} ; yes, stack also VFP hi-regs MOVEQ R0,#0x01 ; os_tsk->stack_frame val @@ -165,16 +175,16 @@ SVC_Handler_Veneer BL rt_stk_check ; Check for Stack overflow POP {R2,R3} -SVC_Next +SVC_ContextRestore STR R2,[R3] ; os_tsk.run = os_tsk.new LDR R12,[R2,#TCB_TSTACK] ; os_tsk.new->tsk_stack LDMIA R12!,{R4-R11} ; Restore New Context LDRB R0,[R2,#TCB_STACKF] ; Stack Frame CMP R0,#0 ; Basic/Extended Stack Frame + MVNEQ LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value + MVNNE LR,#:NOT:0xFFFFFFED VLDMIANE R12!,{S16-S31} ; restore VFP hi-registers - MVNNE LR,#:NOT:0xFFFFFFED ; set EXC_RETURN value - MVNEQ LR,#:NOT:0xFFFFFFFD MSR PSP,R12 ; Write PSP SVC_Exit @@ -254,9 +264,9 @@ Sys_Switch LDMIA R12!,{R4-R11} ; Restore New Context LDRB R0,[R2,#TCB_STACKF] ; Stack Frame CMP R0,#0 ; Basic/Extended Stack Frame + MVNEQ LR,#:NOT:0xFFFFFFFD ; set EXC_RETURN value + MVNNE LR,#:NOT:0xFFFFFFED VLDMIANE R12!,{S16-S31} ; restore VFP hi-regs - MVNNE LR,#:NOT:0xFFFFFFED ; set EXC_RETURN value - MVNEQ LR,#:NOT:0xFFFFFFFD MSR PSP,R12 ; Write PSP Sys_Exit diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/SVC_Table.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/SVC_Table.S index d6df830394..e1289a53bc 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/SVC_Table.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_ARM/SVC_Table.S @@ -1,5 +1,5 @@ ;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX +; * CMSIS-RTOS - RTX ; *---------------------------------------------------------------------------- ; * Name: SVC_TABLE.S ; * Purpose: Pre-defined SVC Table for Cortex-M diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/HAL_CM4.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/HAL_CM4.S index ce3242bcbb..fc6e31f56a 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/HAL_CM4.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/HAL_CM4.S @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: HAL_CM4.S * Purpose: Hardware Abstraction Layer for Cortex-M4 - * Rev.: V4.70 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,8 +35,8 @@ .file "HAL_CM4.S" .syntax unified - .equ TCB_STACKF, 32 - .equ TCB_TSTACK, 40 + .equ TCB_STACKF, 37 + .equ TCB_TSTACK, 44 /*---------------------------------------------------------------------------- @@ -142,7 +142,7 @@ _alloc_box: /*--------------------------- _free_box -------------------------------------*/ -# int _free_box (void *box_mem, void *box); +# U32 _free_box (void *box_mem, void *box); /* Function wrapper for Unprivileged/Privileged mode. */ .thumb_func @@ -208,14 +208,24 @@ SVC_Handler_Veneer: BXEQ LR /* RETI, no task switch */ .endif - CBZ R1,SVC_Next /* Runtask deleted? */ + CBNZ R1,SVC_ContextSave /* Runtask not deleted? */ + TST LR,#0x10 /* is it extended frame? */ - #ifdef __FPU_PRESENT + BNE SVC_ContextRestore + LDR R1,=0xE000EF34 + LDR R0,[R1] /* Load FPCCR */ + BIC R0,#1 /* Clear LSPACT (Lazy state) */ + STR R0,[R1] /* Store FPCCR */ + B SVC_ContextRestore + +SVC_ContextSave: + TST LR,#0x10 /* is it extended frame? */ +#ifdef __FPU_PRESENT ITTE EQ VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ - #else - ITE EQ - #endif +#else + ITE EQ +#endif MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ MOVNE R0,#0x00 STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ @@ -226,21 +236,23 @@ SVC_Handler_Veneer: BL rt_stk_check /* Check for Stack overflow */ POP {R2,R3} -SVC_Next: +SVC_ContextRestore: STR R2,[R3] /* os_tsk.run = os_tsk.new */ LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ LDMIA R12!,{R4-R11} /* Restore New Context */ LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ CMP R0,#0 /* Basic/Extended Stack Frame */ - #ifdef __FPU_PRESENT - ITTE NE +#ifdef __FPU_PRESENT + ITEE EQ +#else + ITE EQ +#endif + MVNEQ LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + MVNNE LR,#~0xFFFFFFED +#ifdef __FPU_PRESENT VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ - #else - ITE NE - #endif - MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ - MVNEQ LR,#~0xFFFFFFFD +#endif MSR PSP,R12 /* Write PSP */ SVC_Exit: @@ -311,12 +323,12 @@ Sys_Switch: MRS R12,PSP /* Read PSP */ TST LR,#0x10 /* is it extended frame? */ - #ifdef __FPU_PRESENT +#ifdef __FPU_PRESENT ITTE EQ VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ - #else - ITE EQ - #endif +#else + ITE EQ +#endif MOVEQ R0,#0x01 /* os_tsk->stack_frame val */ MOVNE R0,#0x00 STRB R0,[R1,#TCB_STACKF] /* os_tsk.run->stack_frame = val */ @@ -333,14 +345,16 @@ Sys_Switch: LDMIA R12!,{R4-R11} /* Restore New Context */ LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ CMP R0,#0 /* Basic/Extended Stack Frame */ - #ifdef __FPU_PRESENT - ITTE NE +#ifdef __FPU_PRESENT + ITEE EQ +#else + ITE EQ +#endif + MVNEQ LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + MVNNE LR,#~0xFFFFFFED +#ifdef __FPU_PRESENT VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ - #else - ITE NE - #endif - MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ - MVNEQ LR,#~0xFFFFFFFD +#endif MSR PSP,R12 /* Write PSP */ Sys_Exit: diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/SVC_Table.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/SVC_Table.S index 2b99321285..d583df1332 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/SVC_Table.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/SVC_Table.S @@ -1,5 +1,5 @@ ;/*---------------------------------------------------------------------------- -; * RL-ARM - RTX +; * CMSIS-RTOS - RTX ; *---------------------------------------------------------------------------- ; * Name: SVC_TABLE.S ; * Purpose: Pre-defined SVC Table for Cortex-M diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S index a8d6b23330..9ba85225f4 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/TARGET_RTOS_M4_M7/TOOLCHAIN_IAR/HAL_CM4.S @@ -3,10 +3,10 @@ *---------------------------------------------------------------------------- * Name: HAL_CM4.S * Purpose: Hardware Abstraction Layer for Cortex-M4 - * Rev.: V4.70 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -34,8 +34,8 @@ NAME HAL_CM4.S - #define TCB_STACKF 32 - #define TCB_TSTACK 40 + #define TCB_STACKF 37 + #define TCB_TSTACK 44 EXTERN os_flags EXTERN os_tsk @@ -120,7 +120,7 @@ _alloc_box: /*--------------------------- _free_box -------------------------------------*/ -; int _free_box (void *box_mem, void *box); +; U32 _free_box (void *box_mem, void *box); /* Function wrapper for Unprivileged/Privileged mode. */ PUBLIC _free_box @@ -176,7 +176,17 @@ SVC_Handler_Veneer: BXEQ LR /* RETI, no task switch */ #endif - CBZ R1,SVC_Next /* Runtask deleted? */ + CBNZ R1,SVC_ContextSave /* Runtask not deleted? */ + + TST LR,#0x10 /* is it extended frame? */ + BNE SVC_ContextRestore + LDR R1,=0xE000EF34 + LDR R0,[R1] /* Load FPCCR */ + BIC R0,R0,#1 /* Clear LSPACT (Lazy state) */ + STR R0,[R1] /* Store FPCCR */ + B SVC_ContextRestore + +SVC_ContextSave: TST LR,#0x10 /* is it extended frame? */ ITTE EQ VSTMDBEQ R12!,{S16-S31} /* yes, stack also VFP hi-regs */ @@ -190,17 +200,17 @@ SVC_Handler_Veneer: BL rt_stk_check /* Check for Stack overflow */ POP {R2,R3} -SVC_Next: +SVC_ContextRestore: STR R2,[R3] /* os_tsk.run = os_tsk.new */ LDR R12,[R2,#TCB_TSTACK] /* os_tsk.new->tsk_stack */ LDMIA R12!,{R4-R11} /* Restore New Context */ LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ CMP R0,#0 /* Basic/Extended Stack Frame */ - ITTE NE + ITEE EQ + MVNEQ LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + MVNNE LR,#~0xFFFFFFED VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ - MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ - MVNEQ LR,#~0xFFFFFFFD MSR PSP,R12 /* Write PSP */ SVC_Exit: @@ -282,10 +292,10 @@ Sys_Switch: LDMIA R12!,{R4-R11} /* Restore New Context */ LDRB R0,[R2,#TCB_STACKF] /* Stack Frame */ CMP R0,#0 /* Basic/Extended Stack Frame */ - ITTE NE + ITEE EQ + MVNEQ LR,#~0xFFFFFFFD /* set EXC_RETURN value */ + MVNNE LR,#~0xFFFFFFED VLDMIANE R12!,{S16-S31} /* restore VFP hi-registers */ - MVNNE LR,#~0xFFFFFFED /* set EXC_RETURN value */ - MVNEQ LR,#~0xFFFFFFFD MSR PSP,R12 /* Write PSP */ Sys_Exit: diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/cmsis_os.h b/libraries/rtos/rtx/TARGET_CORTEX_M/cmsis_os.h index d1e719890b..c0171169b0 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/cmsis_os.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/cmsis_os.h @@ -1,8 +1,6 @@ /* ---------------------------------------------------------------------- - * Copyright (C) 2012 ARM Limited. All rights reserved. - * - * $Date: 5. June 2012 - * $Revision: V1.01 + * $Date: 5. February 2013 + * $Revision: V1.02 * * Project: CMSIS-RTOS API * Title: cmsis_os.h RTX header file @@ -20,98 +18,42 @@ * - 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 ARM LIMITED + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ -/** -\page cmsis_os_h Header File Template: cmsis_os.h - -The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS). -Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents -its implementation. - -The file cmsis_os.h contains: - - CMSIS-RTOS API function definitions - - struct definitions for parameters and return types - - status and priority values used by CMSIS-RTOS API functions - - macros for defining threads and other kernel objects - - -Name conventions and header file modifications - -All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions. -Definitions that are prefixed \b os_ are not used in the application code but local to this header file. -All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread. - -Definitions that are marked with CAN BE CHANGED can be adapted towards the needs of the actual CMSIS-RTOS implementation. -These definitions can be specific to the underlying RTOS kernel. - -Definitions that are marked with MUST REMAIN UNCHANGED cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer -compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation. - - -Function calls from interrupt service routines - -The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR): - - \ref osSignalSet - - \ref osSemaphoreRelease - - \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree - - \ref osMessagePut, \ref osMessageGet - - \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree - -Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called -from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector. - -Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time. -If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive. - - -Define and reference object definitions - -With \#define osObjectsExternal objects are defined as external symbols. This allows to create a consistent header file -that is used throughout a project as shown below: - -Header File -\code -#include // CMSIS RTOS header file - -// Thread definition -extern void thread_sample (void const *argument); // function prototype -osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100); - -// Pool definition -osPoolDef(MyPool, 10, long); -\endcode - - -This header file defines all objects when included in a C/C++ source file. When \#define osObjectsExternal is -present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be -used throughout the whole project. - -Example -\code -#include "osObjects.h" // Definition of the CMSIS-RTOS objects -\endcode - -\code -#define osObjectExternal // Objects will be defined as external symbols -#include "osObjects.h" // Reference to the CMSIS-RTOS objects -\endcode - -*/ #ifndef _CMSIS_OS_H #define _CMSIS_OS_H -/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version. -#define osCMSIS 0x10001 ///< API version (main [31:16] .sub [15:0]) - -/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. -#define osCMSIS_RTX ((4<<16)|61) ///< RTOS identification and version (main [31:16] .sub [15:0]) - -/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS. -#define osKernelSystemId "RTX V4.61" ///< RTOS identification string - - #define CMSIS_OS_RTX // The stack space occupied is mainly dependent on the underling C standard library @@ -123,15 +65,21 @@ used throughout the whole project. #define DEFAULT_STACK_SIZE (WORDS_STACK_SIZE*4) +#define osCMSIS 0x10002U ///< CMSIS-RTOS API version (main [31:16] .sub [15:0]) -/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS. -#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available -#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available -#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available -#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available -#define osFeature_Signals 16 ///< maximum number of Signal Flags available per thread -#define osFeature_Semaphore 65535 ///< maximum count for \ref osSemaphoreCreate function -#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available +#define osCMSIS_RTX ((4<<16)|80) ///< RTOS identification and version (main [31:16] .sub [15:0]) + +#define osKernelSystemId "RTX V4.80" ///< 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 @@ -149,12 +97,9 @@ extern "C" { #endif -#include "os_tcb.h" - // ==== Enumeration, structures, defines ==== /// Priority used for thread control. -/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS. typedef enum { osPriorityIdle = -3, ///< priority: idle (lowest) osPriorityLow = -2, ///< priority: low @@ -167,11 +112,9 @@ typedef enum { } osPriority; /// Timeout value. -/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS. -#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value +#define osWaitForever 0xFFFFFFFFU ///< wait forever timeout value /// Status code values returned by CMSIS-RTOS functions. -/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS. typedef enum { osOK = 0, ///< function completed; no error or event occurred. osEventSignal = 0x08, ///< function completed; signal event occurred. @@ -192,82 +135,69 @@ typedef enum { /// Timer type value for the timer definition. -/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS. typedef enum { osTimerOnce = 0, ///< one-shot timer osTimerPeriodic = 1 ///< repeating timer } os_timer_type; /// Entry point of a thread. -/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. typedef void (*os_pthread) (void const *argument); /// Entry point of a timer call back function. -/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. 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). -/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS. typedef struct os_thread_cb *osThreadId; /// Timer ID identifies the timer (pointer to a timer control block). -/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS. typedef struct os_timer_cb *osTimerId; /// Mutex ID identifies the mutex (pointer to a mutex control block). -/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS. typedef struct os_mutex_cb *osMutexId; /// Semaphore ID identifies the semaphore (pointer to a semaphore control block). -/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS. typedef struct os_semaphore_cb *osSemaphoreId; /// Pool ID identifies the memory pool (pointer to a memory pool control block). -/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS. typedef struct os_pool_cb *osPoolId; /// Message ID identifies the message queue (pointer to a message queue control block). -/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS. typedef struct os_messageQ_cb *osMessageQId; /// Mail ID identifies the mail queue (pointer to a mail queue control block). -/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS. typedef struct os_mailQ_cb *osMailQId; /// Thread Definition structure contains startup information of a thread. -/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. typedef struct os_thread_def { - os_pthread pthread; ///< start address of thread function - osPriority tpriority; ///< initial thread priority - uint32_t stacksize; ///< stack size requirements in bytes + 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 +#ifdef __MBED_CMSIS_RTOS_CM uint32_t *stack_pointer; ///< pointer to the stack memory block - struct OS_TCB tcb; +#endif } osThreadDef_t; /// Timer Definition structure contains timer parameters. -/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS. 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. -/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS. typedef struct os_mutex_def { void *mutex; ///< pointer to internal data } osMutexDef_t; /// Semaphore Definition structure contains setup information for a semaphore. -/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS. typedef struct os_semaphore_def { void *semaphore; ///< pointer to internal data } osSemaphoreDef_t; /// Definition structure for memory block allocation. -/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS. typedef struct os_pool_def { uint32_t pool_sz; ///< number of items (elements) in the pool uint32_t item_sz; ///< size of an item @@ -275,14 +205,12 @@ typedef struct os_pool_def { } osPoolDef_t; /// Definition structure for message queue. -/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS. 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. -/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS. typedef struct os_mailQ_def { uint32_t queue_sz; ///< number of elements in the queue uint32_t item_sz; ///< size of an item @@ -290,8 +218,6 @@ typedef struct os_mailQ_def { } osMailQDef_t; /// Event structure contains detailed information about an event. -/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS. -/// However the struct may be extended at the end. typedef struct { osStatus status; ///< status code: event or error information union { @@ -310,41 +236,68 @@ typedef struct { /// Initialize the RTOS Kernel for creating objects. /// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS. osStatus osKernelInitialize (void); /// Start the RTOS Kernel. /// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS. osStatus osKernelStart (void); /// Check if the RTOS kernel is already started. -/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS. /// \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. -/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the /// macro body is implementation specific in every CMSIS-RTOS. #if defined (osObjectsExternal) // object is external -#define osThreadDef(name, priority, stacksz) \ -extern osThreadDef_t os_thread_def_##name +#define osThreadDef(name, priority, instances, stacksz) \ +extern const osThreadDef_t os_thread_def_##name #else // define the object +#ifdef __MBED_CMSIS_RTOS_CM #define osThreadDef(name, priority, stacksz) \ uint32_t os_thread_def_stack_##name [stacksz / sizeof(uint32_t)]; \ -osThreadDef_t os_thread_def_##name = \ -{ (name), (priority), (stacksz), (os_thread_def_stack_##name)} +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), 1, (stacksz), (os_thread_def_stack_##name) } +#else +#define osThreadDef(name, priority, instances, stacksz) \ +const osThreadDef_t os_thread_def_##name = \ +{ (name), (priority), (instances), (stacksz) } +#endif #endif /// Access a Thread definition. /// \param name name of the thread definition object. -/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the /// macro body is implementation specific in every CMSIS-RTOS. #define osThread(name) \ &os_thread_def_##name @@ -353,52 +306,49 @@ osThreadDef_t os_thread_def_##name = \ /// \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. -/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS. -osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument); +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. -/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS. osPriority osThreadGetPriority (osThreadId thread_id); +#ifdef __MBED_CMSIS_RTOS_CM +/// Get current thread state. +uint8_t osThreadGetState (osThreadId thread_id); +#endif // ==== Generic Wait Functions ==== /// Wait for Timeout (Time Delay). -/// \param[in] millisec time delay value +/// \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 timeout value or 0 in case of no time-out +/// \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. -/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS. os_InRegs osEvent osWait (uint32_t millisec); #endif // Generic Wait available @@ -408,22 +358,18 @@ os_InRegs osEvent osWait (uint32_t millisec); /// Define a Timer object. /// \param name name of the timer object. /// \param function name of the timer call back function. -/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #if defined (osObjectsExternal) // object is external #define osTimerDef(name, function) \ -extern osTimerDef_t os_timer_def_##name +extern const osTimerDef_t os_timer_def_##name #else // define the object #define osTimerDef(name, function) \ -uint32_t os_timer_cb_##name[5]; \ -osTimerDef_t os_timer_def_##name = \ +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. -/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #define osTimer(name) \ &os_timer_def_##name @@ -432,26 +378,22 @@ osTimerDef_t os_timer_def_##name = \ /// \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. -/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS. -osTimerId osTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument); +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 time delay value of the timer. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue "Time delay" value of the timer. /// \return status code that indicates the execution status of the function. -/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS. osStatus osTimerDelete (osTimerId timer_id); @@ -461,27 +403,18 @@ osStatus osTimerDelete (osTimerId timer_id); /// \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. -/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS. +/// \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); -/// Get Signal Flags status of an active thread. -/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId. -/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters. -/// \note MUST REMAIN UNCHANGED: \b osSignalGet shall be consistent in every CMSIS-RTOS. -int32_t osSignalGet (osThreadId thread_id); - /// 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 timeout value or 0 in case of no time-out. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. /// \return event flag information or error code. -/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS. os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); @@ -489,47 +422,39 @@ os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec); /// Define a Mutex. /// \param name name of the mutex object. -/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #if defined (osObjectsExternal) // object is external #define osMutexDef(name) \ -extern osMutexDef_t os_mutex_def_##name +extern const osMutexDef_t os_mutex_def_##name #else // define the object #define osMutexDef(name) \ -uint32_t os_mutex_cb_##name[3]; \ -osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##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. -/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #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. -/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS. -osMutexId osMutexCreate (osMutexDef_t *mutex_def); +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 timeout value or 0 in case of no time-out. +/// \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. -/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS. osStatus osMutexDelete (osMutexId mutex_id); @@ -539,21 +464,17 @@ osStatus osMutexDelete (osMutexId mutex_id); /// Define a Semaphore object. /// \param name name of the semaphore object. -/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #if defined (osObjectsExternal) // object is external #define osSemaphoreDef(name) \ -extern osSemaphoreDef_t os_semaphore_def_##name +extern const osSemaphoreDef_t os_semaphore_def_##name #else // define the object #define osSemaphoreDef(name) \ -uint32_t os_semaphore_cb_##name[2]; \ -osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##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. -/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #define osSemaphore(name) \ &os_semaphore_def_##name @@ -561,26 +482,22 @@ osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) } /// \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. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS. -osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count); +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 timeout value or 0 in case of no time-out. +/// \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. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS. osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); #endif // Semaphore available @@ -594,48 +511,40 @@ osStatus osSemaphoreDelete (osSemaphoreId semaphore_id); /// \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). -/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #if defined (osObjectsExternal) // object is external #define osPoolDef(name, no, type) \ -extern osPoolDef_t os_pool_def_##name +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)]; \ -osPoolDef_t os_pool_def_##name = \ +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 -/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #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. -/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS. -osPoolId osPoolCreate (osPoolDef_t *pool_def); +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. -/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS. osStatus osPoolFree (osPoolId pool_id, void *block); #endif // Memory Pool Management available @@ -649,22 +558,18 @@ osStatus osPoolFree (osPoolId pool_id, void *block); /// \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). -/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #if defined (osObjectsExternal) // object is external #define osMessageQDef(name, queue_sz, type) \ -extern osMessageQDef_t os_messageQ_def_##name +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)]; \ -osMessageQDef_t os_messageQ_def_##name = \ +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 -/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #define osMessageQ(name) \ &os_messageQ_def_##name @@ -672,22 +577,19 @@ osMessageQDef_t os_messageQ_def_##name = \ /// \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. -/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS. -osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); +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 timeout value or 0 in case of no time-out. +/// \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. -/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS. 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 timeout value or 0 in case of no time-out. +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. /// \return event information that includes status code. -/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS. os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); #endif // Message Queues available @@ -701,24 +603,20 @@ os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec); /// \param name name of the queue /// \param queue_sz maximum number of messages in queue /// \param type data type of a single message element -/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #if defined (osObjectsExternal) // object is external #define osMailQDef(name, queue_sz, type) \ -extern osMailQDef_t os_mailQ_def_##name +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)]; \ +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 }; \ -osMailQDef_t os_mailQ_def_##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 -/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the -/// macro body is implementation specific in every CMSIS-RTOS. #define osMailQ(name) \ &os_mailQ_def_##name @@ -726,47 +624,52 @@ osMailQDef_t os_mailQ_def_##name = \ /// \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. -/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS. -osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id); +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 timeout value or 0 in case of no time-out +/// \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. -/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS. 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 timeout value or 0 in case of no time-out +/// \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. -/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS. 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. -/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS. 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 timeout value or 0 in case of no time-out +/// \param[in] millisec \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out /// \return event that contains mail information or error code. -/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS. os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec); /// 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. -/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS. 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); + + #ifdef __cplusplus } #endif diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/os_tcb.h b/libraries/rtos/rtx/TARGET_CORTEX_M/os_tcb.h deleted file mode 100644 index 800f7f534a..0000000000 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/os_tcb.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef OS_TCB_H -#define OS_TCB_H - -/* Types */ -typedef char S8; -typedef unsigned char U8; -typedef short S16; -typedef unsigned short U16; -typedef int S32; -typedef unsigned int U32; -typedef long long S64; -typedef unsigned long long U64; -typedef unsigned char BIT; -typedef unsigned int BOOL; -typedef void (*FUNCP)(void); - -typedef struct OS_TCB { - /* General part: identical for all implementations. */ - U8 cb_type; /* Control Block Type */ - U8 state; /* Task state */ - U8 prio; /* Execution priority */ - U8 task_id; /* Task ID value for optimized TCB access */ - struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ - struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ - struct OS_TCB *p_dlnk; /* Link pointer for delay list */ - struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ - U16 delta_time; /* Time until time out */ - U16 interval_time; /* Time interval for periodic waits */ - U16 events; /* Event flags */ - U16 waits; /* Wait flags */ - void **msg; /* Direct message passing when task waits */ - - /* Hardware dependant part: specific for CM processor */ - U8 stack_frame; /* Stack frame: 0=Basic, 1=Extended */ - U8 reserved1; - U16 reserved2; - U32 priv_stack; /* Private stack size in bytes */ - U32 tsk_stack; /* Current task Stack pointer (R13) */ - U32 *stack; /* Pointer to Task Stack memory block */ - - /* Library dependant part */ -#if defined (__CC_ARM) && !defined (__MICROLIB) - /* A memory space for arm standard library. */ - U32 std_libspace[96/4]; -#endif - - /* Task entry point used for uVision debugger */ - FUNCP ptask; /* Task entry address */ -} *P_TCB; - -#endif diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c index a747caf31a..057fced7e3 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_CMSIS.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: rt_CMSIS.c * Purpose: CMSIS RTOS API - * Rev.: V4.60 + * Rev.: V4.80 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -49,7 +49,7 @@ #endif #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_System.h" #include "rt_Task.h" #include "rt_Event.h" @@ -59,6 +59,7 @@ #include "rt_Semaphore.h" #include "rt_Mailbox.h" #include "rt_MemBox.h" +#include "rt_Memory.h" #include "rt_HAL_CM.h" #define os_thread_cb OS_TCB @@ -101,6 +102,14 @@ static __inline t __##f (void) { \ return _##f(f); \ } +#define SVC_1_0(f,t,t1,...) \ +__svc_indirect(0) t _##f (t(*)(t1),t1); \ + t f (t1 a1); \ +__attribute__((always_inline)) \ +static __inline t __##f (t1 a1) { \ + _##f(f,a1); \ +} + #define SVC_1_1(f,t,t1,...) \ __svc_indirect(0) t _##f (t(*)(t1),t1); \ t f (t1 a1); \ @@ -133,9 +142,9 @@ static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ return _##f(f,a1,a2,a3,a4); \ } -#define SVC_1_2 SVC_1_1 -#define SVC_1_3 SVC_1_1 -#define SVC_2_3 SVC_2_1 +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 #elif defined (__GNUC__) /* GNU Compiler */ @@ -146,18 +155,19 @@ typedef uint32_t __attribute__((vector_size(16))) ret128; #define RET_pointer __r0 #define RET_int32_t __r0 +#define RET_uint32_t __r0 #define RET_osStatus __r0 #define RET_osPriority __r0 #define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}} #define RET_osCallback {(void *)__r0, (void *)__r1} -#define osEvent_type ret128 +#define osEvent_type __attribute__((pcs("aapcs"))) ret128 #define osEvent_ret_status (ret128){ret.status} #define osEvent_ret_value (ret128){ret.status, ret.value.v} #define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id} #define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id} -#define osCallback_type ret64 +#define osCallback_type __attribute__((pcs("aapcs"))) ret64 #define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg} #define SVC_ArgN(n) \ @@ -198,7 +208,7 @@ typedef uint32_t __attribute__((vector_size(16))) ret128; #if (defined (__CORTEX_M0)) || defined (__CORTEX_M0PLUS) #define SVC_Call(f) \ - __asm volatile \ + __asm volatile \ ( \ "ldr r7,="#f"\n\t" \ "mov r12,r7\n\t" \ @@ -209,7 +219,7 @@ typedef uint32_t __attribute__((vector_size(16))) ret128; ); #else #define SVC_Call(f) \ - __asm volatile \ + __asm volatile \ ( \ "ldr r12,="#f"\n\t" \ "svc 0" \ @@ -227,6 +237,13 @@ static inline t __##f (void) { \ return (t) rv; \ } +#define SVC_1_0(f,t,t1) \ +__attribute__((always_inline)) \ +static inline t __##f (t1 a1) { \ + SVC_Arg1(t1); \ + SVC_Call(f); \ +} + #define SVC_1_1(f,t,t1,rv) \ __attribute__((always_inline)) \ static inline t __##f (t1 a1) { \ @@ -259,9 +276,9 @@ static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ return (t) rv; \ } -#define SVC_1_2 SVC_1_1 -#define SVC_1_3 SVC_1_1 -#define SVC_2_3 SVC_2_1 +#define SVC_1_2 SVC_1_1 +#define SVC_1_3 SVC_1_1 +#define SVC_2_3 SVC_2_1 #elif defined (__ICCARM__) /* IAR Compiler */ @@ -285,6 +302,12 @@ static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \ :: "r"(&f): "r12" \ ); +#define SVC_Ret3() \ + __asm( \ + "ldr r0,[sp,#0]\n" \ + "ldr r1,[sp,#4]\n" \ + "ldr r2,[sp,#8]\n" \ + ); #define SVC_0_1(f,t,...) \ t f (void); \ @@ -294,6 +317,14 @@ static inline t __##f (void) { \ return _##f(); \ } +#define SVC_1_0(f,t,t1,...) \ +t f (t1 a1); \ +_Pragma("swi_number=0") __swi t _##f (t1 a1); \ +static inline t __##f (t1 a1) { \ + SVC_Setup(f); \ + _##f(a1); \ +} + #define SVC_1_1(f,t,t1,...) \ t f (t1 a1); \ _Pragma("swi_number=0") __swi t _##f (t1 a1); \ @@ -346,46 +377,53 @@ extern const uint32_t os_section_id$$Base; extern const uint32_t os_section_id$$Limit; #endif +#ifndef __MBED_CMSIS_RTOS_CM +// OS Stack Memory for Threads definitions +extern uint64_t os_stack_mem[]; +extern const uint32_t os_stack_sz; +#endif + // OS Timers external resources -extern osThreadDef_t os_thread_def_osTimerThread; -extern osThreadId osThreadId_osTimerThread; -extern osMessageQDef_t os_messageQ_def_osTimerMessageQ; -extern osMessageQId osMessageQId_osTimerMessageQ; +extern const osThreadDef_t os_thread_def_osTimerThread; +extern osThreadId osThreadId_osTimerThread; +extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ; +extern osMessageQId osMessageQId_osTimerMessageQ; // ==== Helper Functions ==== /// Convert timeout in millisec to system ticks -static uint32_t rt_ms2tick (uint32_t millisec) { +static uint16_t rt_ms2tick (uint32_t millisec) { uint32_t tick; - if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout - if (millisec > 4000000) return 0xFFFE; // Max ticks supported + if (millisec == 0U) { return 0x0U; } // No timeout + if (millisec == osWaitForever) { return 0xFFFFU; } // Indefinite timeout + if (millisec > 4000000U) { return 0xFFFEU; } // Max ticks supported - tick = ((1000 * millisec) + os_clockrate - 1) / os_clockrate; - if (tick > 0xFFFE) return 0xFFFE; - - return tick; + tick = ((1000U * millisec) + os_clockrate - 1U) / os_clockrate; + if (tick > 0xFFFEU) { return 0xFFFEU; } + + return (uint16_t)tick; } /// Convert Thread ID to TCB pointer -static P_TCB rt_tid2ptcb (osThreadId thread_id) { +P_TCB rt_tid2ptcb (osThreadId thread_id) { P_TCB ptcb; - if (thread_id == NULL) return NULL; + if (thread_id == NULL) { return NULL; } - if ((uint32_t)thread_id & 3) return NULL; + if ((uint32_t)thread_id & 3U) { return NULL; } #ifdef OS_SECTIONS_LINK_INFO - if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { - if (thread_id < (osThreadId)os_section_id$$Base) return NULL; - if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL; + if ((os_section_id$$Base != 0U) && (os_section_id$$Limit != 0U)) { + if (thread_id < (osThreadId)os_section_id$$Base) { return NULL; } + if (thread_id >= (osThreadId)os_section_id$$Limit) { return NULL; } } #endif ptcb = thread_id; - if (ptcb->cb_type != TCB) return NULL; + if (ptcb->cb_type != TCB) { return NULL; } return ptcb; } @@ -393,12 +431,12 @@ static P_TCB rt_tid2ptcb (osThreadId thread_id) { /// Convert ID pointer to Object pointer static void *rt_id2obj (void *id) { - if ((uint32_t)id & 3) return NULL; + if ((uint32_t)id & 3U) { return NULL; } #ifdef OS_SECTIONS_LINK_INFO - if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) { - if (id < (void *)os_section_id$$Base) return NULL; - if (id >= (void *)os_section_id$$Limit) return NULL; + if ((os_section_id$$Base != 0U) && (os_section_id$$Limit != 0U)) { + if (id < (void *)os_section_id$$Base) { return NULL; } + if (id >= (void *)os_section_id$$Limit) { return NULL; } } #endif @@ -415,23 +453,46 @@ uint8_t os_running; // Kernel Running flag SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus) SVC_0_1(svcKernelStart, osStatus, RET_osStatus) SVC_0_1(svcKernelRunning, int32_t, RET_int32_t) +SVC_0_1(svcKernelSysTick, uint32_t, RET_uint32_t) -extern void sysThreadError (osStatus status); -osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument); -osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id); +static void sysThreadError (osStatus status); +osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument); +osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id); // Kernel Control Service Calls /// Initialize the RTOS Kernel for creating objects osStatus svcKernelInitialize (void) { - if (os_initialized) return osOK; +#ifdef __MBED_CMSIS_RTOS_CM + if (!os_initialized) { + rt_sys_init(); // RTX System Initialization + } +#else + uint32_t ret; - rt_sys_init(); // RTX System Initialization - os_tsk.run->prio = 255; // Highest priority + if (os_initialized == 0U) { + + // Init Thread Stack Memory (must be 8-byte aligned) + if (((uint32_t)os_stack_mem & 7U) != 0U) { return osErrorNoMemory; } + ret = rt_init_mem(os_stack_mem, os_stack_sz); + if (ret != 0U) { return osErrorNoMemory; } + + rt_sys_init(); // RTX System Initialization + } +#endif + + os_tsk.run->prio = 255U; // Highest priority + + if (os_initialized == 0U) { + // Create OS Timers resources (Message Queue & Thread) + osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL); + osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL); + } sysThreadError(osOK); - os_initialized = 1; + os_initialized = 1U; + os_running = 0U; return osOK; } @@ -439,34 +500,53 @@ osStatus svcKernelInitialize (void) { /// Start the RTOS Kernel osStatus svcKernelStart (void) { - if (os_running) return osOK; + if (os_running) { return osOK; } - // Create OS Timers resources (Message Queue & Thread) - osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL); - osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL); - - rt_tsk_prio(0, 0); // Lowest priority - __set_PSP(os_tsk.run->tsk_stack + 8*4); // New context - os_tsk.run = NULL; // Force context switch + rt_tsk_prio(0U, os_tsk.run->prio_base); // Restore priority + if (os_tsk.run->task_id == 0xFFU) { // Idle Thread + __set_PSP(os_tsk.run->tsk_stack + (8U*4U)); // Setup PSP + } + if (os_tsk.new_tsk == NULL) { // Force context switch + os_tsk.new_tsk = os_tsk.run; + os_tsk.run = NULL; + } rt_sys_start(); - os_running = 1; + os_running = 1U; return osOK; } /// Check if the RTOS kernel is already started -int32_t svcKernelRunning(void) { - return os_running; +int32_t svcKernelRunning (void) { + return (int32_t)os_running; +} + +/// Get the RTOS kernel system timer counter +uint32_t svcKernelSysTick (void) { + uint32_t tick, tick0; + + tick = os_tick_val(); + if (os_tick_ovf()) { + tick0 = os_tick_val(); + if (tick0 < tick) { tick = tick0; } + tick += (os_trv + 1U) * (os_time + 1U); + } else { + tick += (os_trv + 1U) * os_time; + } + + return tick; } // Kernel Control Public API /// Initialize the RTOS Kernel for creating objects osStatus osKernelInitialize (void) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - if ((__get_CONTROL() & 1) == 0) { // Privileged mode + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } + if ((__get_CONTROL() & 1U) == 0U) { // Privileged mode return svcKernelInitialize(); } else { return __svcKernelInitialize(); @@ -477,95 +557,127 @@ osStatus osKernelInitialize (void) { osStatus osKernelStart (void) { uint32_t stack[8]; - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - switch (__get_CONTROL() & 0x03) { - case 0x00: // Privileged Thread mode & MSP + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } + switch (__get_CONTROL() & 0x03U) { + case 0x00U: // Privileged Thread mode & MSP __set_PSP((uint32_t)(stack + 8)); // Initial PSP - if (os_flags & 1) { - __set_CONTROL(0x02); // Set Privileged Thread mode & PSP + if (os_flags & 1U) { + __set_CONTROL(0x02U); // Set Privileged Thread mode & PSP } else { - __set_CONTROL(0x03); // Set Unprivileged Thread mode & PSP + __set_CONTROL(0x03U); // Set Unprivileged Thread mode & PSP } __DSB(); __ISB(); break; - case 0x01: // Unprivileged Thread mode & MSP + case 0x01U: // Unprivileged Thread mode & MSP return osErrorOS; - case 0x02: // Privileged Thread mode & PSP - if ((os_flags & 1) == 0) { // Unprivileged Thread mode requested - __set_CONTROL(0x03); // Set Unprivileged Thread mode & PSP + case 0x02U: // Privileged Thread mode & PSP + if ((os_flags & 1U) == 0U) { // Unprivileged Thread mode requested + __set_CONTROL(0x03U); // Set Unprivileged Thread mode & PSP __DSB(); __ISB(); } break; - case 0x03: // Unprivileged Thread mode & PSP - if (os_flags & 1) return osErrorOS; // Privileged Thread mode requested + case 0x03U: // Unprivileged Thread mode & PSP + if (os_flags & 1U) { return osErrorOS; } // Privileged Thread mode requested break; } return __svcKernelStart(); } /// Check if the RTOS kernel is already started -int32_t osKernelRunning(void) { - if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { +int32_t osKernelRunning (void) { + if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged - return os_running; + return (int32_t)os_running; } else { return __svcKernelRunning(); } } +/// Get the RTOS kernel system timer counter +uint32_t osKernelSysTick (void) { + if (__get_IPSR() != 0U) { return 0U; } // Not allowed in ISR + return __svcKernelSysTick(); +} + // ==== Thread Management ==== +/// Set Thread Error (for Create functions which return IDs) +static void sysThreadError (osStatus status) { + // To Do +} + __NO_RETURN void osThreadExit (void); // Thread Service Calls declarations -SVC_2_1(svcThreadCreate, osThreadId, osThreadDef_t *, void *, RET_pointer) -SVC_0_1(svcThreadGetId, osThreadId, RET_pointer) -SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus) -SVC_0_1(svcThreadYield, osStatus, RET_osStatus) -SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus) -SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority) +SVC_2_1(svcThreadCreate, osThreadId, const osThreadDef_t *, void *, RET_pointer) +SVC_0_1(svcThreadGetId, osThreadId, RET_pointer) +SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus) +SVC_0_1(svcThreadYield, osStatus, RET_osStatus) +SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus) +SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority) // Thread Service Calls -extern OS_TID rt_get_TID (void); -extern void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body); /// Create a thread and add it to Active Threads and set it to state READY -osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument) { +osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument) { P_TCB ptcb; + OS_TID tsk; + void *stk; if ((thread_def == NULL) || (thread_def->pthread == NULL) || (thread_def->tpriority < osPriorityIdle) || - (thread_def->tpriority > osPriorityRealtime) || - (thread_def->stacksize == 0) || - (thread_def->stack_pointer == NULL) ) { - sysThreadError(osErrorParameter); + (thread_def->tpriority > osPriorityRealtime)) { + sysThreadError(osErrorParameter); + return NULL; + } + +#ifdef __MBED_CMSIS_RTOS_CM + if (thread_def->stacksize != 0) { // Custom stack size + stk = (void *)thread_def->stack_pointer; + } else { // Default stack size + stk = NULL; + } +#else + if (thread_def->stacksize != 0) { // Custom stack size + stk = rt_alloc_mem( // Allocate stack + os_stack_mem, + thread_def->stacksize + ); + if (stk == NULL) { + sysThreadError(osErrorNoMemory); // Out of memory + return NULL; + } + } else { // Default stack size + stk = NULL; + } +#endif + + tsk = rt_tsk_create( // Create task + (FUNCP)thread_def->pthread, // Task function pointer + (uint32_t) + (thread_def->tpriority-osPriorityIdle+1) | // Task priority + (thread_def->stacksize << 8), // Task stack size in bytes + stk, // Pointer to task's stack + argument // Argument to the task + ); + + if (tsk == 0U) { // Invalid task ID +#ifndef __MBED_CMSIS_RTOS_CM + if (stk != NULL) { + rt_free_mem(os_stack_mem, stk); // Free allocated stack + } +#endif + sysThreadError(osErrorNoMemory); // Create task failed (Out of memory) return NULL; } - U8 priority = thread_def->tpriority - osPriorityIdle + 1; - P_TCB task_context = &thread_def->tcb; - - /* Utilize the user provided stack. */ - task_context->stack = (U32*)thread_def->stack_pointer; - task_context->priv_stack = thread_def->stacksize; - /* Find a free entry in 'os_active_TCB' table. */ - OS_TID tsk = rt_get_TID (); - os_active_TCB[tsk-1] = task_context; - task_context->task_id = tsk; - /* Pass parameter 'argv' to 'rt_init_context' */ - task_context->msg = argument; - /* Initialize thread context structure, including the thread's stack. */ - rt_init_context (task_context, priority, (FUNCP)thread_def->pthread); - - /* Dispatch this task to the scheduler for execution. */ - DBG_TASK_NOTIFY(task_context, __TRUE); - rt_dispatch (task_context); - - ptcb = (P_TCB)os_active_TCB[tsk - 1]; // TCB pointer + ptcb = (P_TCB)os_active_TCB[tsk - 1U]; // TCB pointer *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit; @@ -577,21 +689,38 @@ osThreadId svcThreadGetId (void) { OS_TID tsk; tsk = rt_tsk_self(); - if (tsk == 0) return NULL; - return (P_TCB)os_active_TCB[tsk - 1]; + if (tsk == 0U) { return NULL; } + return (P_TCB)os_active_TCB[tsk - 1U]; } /// Terminate execution of a thread and remove it from ActiveThreads osStatus svcThreadTerminate (osThreadId thread_id) { OS_RESULT res; P_TCB ptcb; +#ifndef __MBED_CMSIS_RTOS_CM + void *stk; +#endif ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return osErrorParameter; + if (ptcb == NULL) { + return osErrorParameter; + } + +#ifndef __MBED_CMSIS_RTOS_CM + stk = ptcb->priv_stack ? ptcb->stack : NULL; // Private stack +#endif res = rt_tsk_delete(ptcb->task_id); // Delete task - if (res == OS_R_NOK) return osErrorResource; // Delete task failed + if (res == OS_R_NOK) { + return osErrorResource; // Delete task failed + } + +#ifndef __MBED_CMSIS_RTOS_CM + if (stk != NULL) { + rt_free_mem(os_stack_mem, stk); // Free private stack + } +#endif return osOK; } @@ -608,7 +737,9 @@ osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) { P_TCB ptcb; ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return osErrorParameter; + if (ptcb == NULL) { + return osErrorParameter; + } if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) { return osErrorValue; @@ -616,10 +747,12 @@ osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) { res = rt_tsk_prio( // Change task priority ptcb->task_id, // Task ID - priority - osPriorityIdle + 1 // New task priority + (uint8_t)(priority - osPriorityIdle + 1) // New task priority ); - if (res == OS_R_NOK) return osErrorResource; // Change task priority failed + if (res == OS_R_NOK) { + return osErrorResource; // Change task priority failed + } return osOK; } @@ -629,18 +762,22 @@ osPriority svcThreadGetPriority (osThreadId thread_id) { P_TCB ptcb; ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return osPriorityError; + if (ptcb == NULL) { + return osPriorityError; + } - return (osPriority)(ptcb->prio - 1 + osPriorityIdle); + return (osPriority)(ptcb->prio - 1 + osPriorityIdle); } // Thread Public API /// Create a thread and add it to Active Threads and set it to state READY -osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { +osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) { + if (__get_IPSR() != 0U) { + return NULL; // Not allowed in ISR + } + if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { // Privileged and not running return svcThreadCreate(thread_def, argument); } else { @@ -650,41 +787,64 @@ osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument) { /// Return the thread ID of the current running thread osThreadId osThreadGetId (void) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return NULL; // Not allowed in ISR + } return __svcThreadGetId(); } /// Terminate execution of a thread and remove it from ActiveThreads osStatus osThreadTerminate (osThreadId thread_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } return __svcThreadTerminate(thread_id); } /// Pass control to next thread that is in state READY osStatus osThreadYield (void) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } return __svcThreadYield(); } /// Change priority of an active thread osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } return __svcThreadSetPriority(thread_id, priority); } /// Get current priority of an active thread osPriority osThreadGetPriority (osThreadId thread_id) { - if (__get_IPSR() != 0) return osPriorityError;// Not allowed in ISR + if (__get_IPSR() != 0U) { + return osPriorityError; // Not allowed in ISR + } return __svcThreadGetPriority(thread_id); } /// INTERNAL - Not Public /// Auto Terminate Thread on exit (used implicitly when thread exists) -__NO_RETURN void osThreadExit (void) { - __svcThreadTerminate(__svcThreadGetId()); +__NO_RETURN void osThreadExit (void) { + __svcThreadTerminate(__svcThreadGetId()); for (;;); // Should never come here } +#ifdef __MBED_CMSIS_RTOS_CM +/// Get current thread state +uint8_t osThreadGetState (osThreadId thread_id) { + P_TCB ptcb; + + if (__get_IPSR() != 0U) return osErrorISR; // Not allowed in ISR + + ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer + if (ptcb == NULL) return osErrorParameter; + + return ptcb->state; +} +#endif // ==== Generic Wait Functions ==== @@ -698,7 +858,7 @@ SVC_1_3(svcWait, os_InRegs osEvent, uint32_t, RET_osEvent) /// Wait for Timeout (Time Delay) osStatus svcDelay (uint32_t millisec) { - if (millisec == 0) return osOK; + if (millisec == 0U) { return osOK; } rt_dly_wait(rt_ms2tick(millisec)); return osEventTimeout; } @@ -708,7 +868,7 @@ osStatus svcDelay (uint32_t millisec) { os_InRegs osEvent_type svcWait (uint32_t millisec) { osEvent ret; - if (millisec == 0) { + if (millisec == 0U) { ret.status = osOK; return osEvent_ret_status; } @@ -726,7 +886,9 @@ os_InRegs osEvent_type svcWait (uint32_t millisec) { /// Wait for Timeout (Time Delay) osStatus osDelay (uint32_t millisec) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } return __svcDelay(millisec); } @@ -738,7 +900,7 @@ os_InRegs osEvent osWait (uint32_t millisec) { ret.status = osErrorOS; return ret; #else - if (__get_IPSR() != 0) { // Not allowed in ISR + if (__get_IPSR() != 0U) { // Not allowed in ISR ret.status = osErrorISR; return ret; } @@ -750,21 +912,21 @@ os_InRegs osEvent osWait (uint32_t millisec) { // ==== Timer Management ==== // Timer definitions -#define osTimerInvalid 0 -#define osTimerStopped 1 -#define osTimerRunning 2 +#define osTimerInvalid 0U +#define osTimerStopped 1U +#define osTimerRunning 2U -// Timer structures +// Timer structures typedef struct os_timer_cb_ { // Timer Control Block struct os_timer_cb_ *next; // Pointer to next active Timer uint8_t state; // Timer State uint8_t type; // Timer Type (Periodic/One-shot) uint16_t reserved; // Reserved - uint16_t tcnt; // Timer Delay Count - uint16_t icnt; // Timer Initial Count + uint32_t tcnt; // Timer Delay Count + uint32_t icnt; // Timer Initial Count void *arg; // Timer Function Argument - osTimerDef_t *timer; // Pointer to Timer definition + const osTimerDef_t *timer; // Pointer to Timer definition } os_timer_cb; // Timer variables @@ -780,13 +942,13 @@ static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) { prev = NULL; p = os_timer_head; while (p != NULL) { - if (tcnt < p->tcnt) break; + if (tcnt < p->tcnt) { break; } tcnt -= p->tcnt; prev = p; p = p->next; } pt->next = p; - pt->tcnt = (uint16_t)tcnt; + pt->tcnt = tcnt; if (p != NULL) { p->tcnt -= pt->tcnt; } @@ -798,17 +960,17 @@ static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) { } // Remove Timer from the list -static int rt_timer_remove (os_timer_cb *pt) { +static int32_t rt_timer_remove (os_timer_cb *pt) { os_timer_cb *p, *prev; prev = NULL; p = os_timer_head; while (p != NULL) { - if (p == pt) break; + if (p == pt) { break; } prev = p; p = p->next; } - if (p == NULL) return -1; + if (p == NULL) { return -1; } if (prev != NULL) { prev->next = pt->next; } else { @@ -823,16 +985,16 @@ static int rt_timer_remove (os_timer_cb *pt) { // Timer Service Calls declarations -SVC_3_1(svcTimerCreate, osTimerId, osTimerDef_t *, os_timer_type, void *, RET_pointer) -SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus) -SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus) -SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus) -SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback) +SVC_3_1(svcTimerCreate, osTimerId, const osTimerDef_t *, os_timer_type, void *, RET_pointer) +SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus) +SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus) +SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus) +SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback) // Timer Management Service Calls /// Create timer -osTimerId svcTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) { +osTimerId svcTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { os_timer_cb *pt; if ((timer_def == NULL) || (timer_def->ptimer == NULL)) { @@ -861,6 +1023,7 @@ osTimerId svcTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *arg return NULL; } + pt->next = NULL; pt->state = osTimerStopped; pt->type = (uint8_t)type; pt->arg = argument; @@ -875,10 +1038,13 @@ osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) { uint32_t tcnt; pt = rt_id2obj(timer_id); - if (pt == NULL) return osErrorParameter; + if (pt == NULL) { + return osErrorParameter; + } - tcnt = rt_ms2tick(millisec); - if (tcnt == 0) return osErrorValue; + if (millisec == 0U) { return osErrorValue; } + + tcnt = (uint32_t)(((1000U * (uint64_t)millisec) + os_clockrate - 1U) / os_clockrate); switch (pt->state) { case osTimerRunning: @@ -888,12 +1054,12 @@ osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) { break; case osTimerStopped: pt->state = osTimerRunning; - pt->icnt = (uint16_t)tcnt; + pt->icnt = tcnt; break; default: return osErrorResource; } - + rt_timer_insert(pt, tcnt); return osOK; @@ -904,9 +1070,11 @@ osStatus svcTimerStop (osTimerId timer_id) { os_timer_cb *pt; pt = rt_id2obj(timer_id); - if (pt == NULL) return osErrorParameter; + if (pt == NULL) { + return osErrorParameter; + } - if (pt->state != osTimerRunning) return osErrorResource; + if (pt->state != osTimerRunning) { return osErrorResource; } pt->state = osTimerStopped; @@ -922,7 +1090,9 @@ osStatus svcTimerDelete (osTimerId timer_id) { os_timer_cb *pt; pt = rt_id2obj(timer_id); - if (pt == NULL) return osErrorParameter; + if (pt == NULL) { + return osErrorParameter; + } switch (pt->state) { case osTimerRunning: @@ -957,22 +1127,26 @@ os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) { return osCallback_ret; } -static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); +osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec); /// Timer Tick (called each SysTick) void sysTimerTick (void) { os_timer_cb *pt, *p; + osStatus status; p = os_timer_head; - if (p == NULL) return; + if (p == NULL) { return; } p->tcnt--; - while ((p != NULL) && (p->tcnt == 0)) { + while ((p != NULL) && (p->tcnt == 0U)) { pt = p; p = p->next; os_timer_head = p; - isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0); - if (pt->type == osTimerPeriodic) { + status = isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0U); + if (status != osOK) { + os_error(OS_ERR_TIMER_OVF); + } + if (pt->type == (uint8_t)osTimerPeriodic) { rt_timer_insert(pt, pt->icnt); } else { pt->state = osTimerStopped; @@ -980,13 +1154,39 @@ void sysTimerTick (void) { } } +/// Get user timers wake-up time +uint32_t sysUserTimerWakeupTime (void) { + + if (os_timer_head) { + return os_timer_head->tcnt; + } + return 0xFFFFFFFFU; +} + +/// Update user timers on resume +void sysUserTimerUpdate (uint32_t sleep_time) { + + while ((os_timer_head != NULL) && (sleep_time != 0U)) { + if (sleep_time >= os_timer_head->tcnt) { + sleep_time -= os_timer_head->tcnt; + os_timer_head->tcnt = 1U; + sysTimerTick(); + } else { + os_timer_head->tcnt -= sleep_time; + break; + } + } +} + // Timer Management Public API /// Create timer -osTimerId osTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { +osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) { + if (__get_IPSR() != 0U) { + return NULL; // Not allowed in ISR + } + if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { // Privileged and not running return svcTimerCreate(timer_def, type, argument); } else { @@ -996,26 +1196,32 @@ osTimerId osTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argu /// Start or restart timer osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } return __svcTimerStart(timer_id, millisec); } /// Stop timer osStatus osTimerStop (osTimerId timer_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } return __svcTimerStop(timer_id); } /// Delete timer osStatus osTimerDelete (osTimerId timer_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } return __svcTimerDelete(timer_id); } /// INTERNAL - Not Public /// Get timer callback parameters (used by OS Timer Thread) -os_InRegs osCallback osTimerCall (osTimerId timer_id) { - return __svcTimerCall(timer_id); +os_InRegs osCallback osTimerCall (osTimerId timer_id) { + return __svcTimerCall(timer_id); } @@ -1041,7 +1247,6 @@ __NO_RETURN void osTimerThread (void const *argument) { // Signal Service Calls declarations SVC_2_1(svcSignalSet, int32_t, osThreadId, int32_t, RET_int32_t) SVC_2_1(svcSignalClear, int32_t, osThreadId, int32_t, RET_int32_t) -SVC_1_1(svcSignalGet, int32_t, osThreadId, RET_int32_t) SVC_2_3(svcSignalWait, os_InRegs osEvent, int32_t, uint32_t, RET_osEvent) // Signal Service Calls @@ -1052,13 +1257,17 @@ int32_t svcSignalSet (osThreadId thread_id, int32_t signals) { int32_t sig; ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; + if (ptcb == NULL) { + return (int32_t)0x80000000U; + } - if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) { + return (int32_t)0x80000000U; + } - sig = ptcb->events; // Previous signal flags + sig = (int32_t)ptcb->events; // Previous signal flags - rt_evt_set(signals, ptcb->task_id); // Set event flags + rt_evt_set((uint16_t)signals, ptcb->task_id); // Set event flags return sig; } @@ -1069,48 +1278,42 @@ int32_t svcSignalClear (osThreadId thread_id, int32_t signals) { int32_t sig; ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; + if (ptcb == NULL) { + return (int32_t)0x80000000U; + } - if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) { + return (int32_t)0x80000000U; + } - sig = ptcb->events; // Previous signal flags + sig = (int32_t)ptcb->events; // Previous signal flags - rt_evt_clr(signals, ptcb->task_id); // Clear event flags + rt_evt_clr((uint16_t)signals, ptcb->task_id); // Clear event flags return sig; } -/// Get Signal Flags status of an active thread -int32_t svcSignalGet (osThreadId thread_id) { - P_TCB ptcb; - - ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - return ptcb->events; // Return event flags -} - /// Wait for one or more Signal Flags to become signaled for the current RUNNING thread os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) { OS_RESULT res; osEvent ret; - if (signals & (0xFFFFFFFF << osFeature_Signals)) { + if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) { ret.status = osErrorValue; return osEvent_ret_status; } if (signals != 0) { // Wait for all specified signals - res = rt_evt_wait(signals, rt_ms2tick(millisec), __TRUE); + res = rt_evt_wait((uint16_t)signals, rt_ms2tick(millisec), __TRUE); } else { // Wait for any signal - res = rt_evt_wait(0xFFFF, rt_ms2tick(millisec), __FALSE); + res = rt_evt_wait(0xFFFFU, rt_ms2tick(millisec), __FALSE); } if (res == OS_R_EVT) { ret.status = osEventSignal; - ret.value.signals = signals ? signals : os_tsk.run->waits; + ret.value.signals = (signals != 0) ? signals : (int32_t)os_tsk.run->waits; } else { - ret.status = millisec ? osEventTimeout : osOK; + ret.status = (millisec != 0U) ? osEventTimeout : osOK; ret.value.signals = 0; } @@ -1121,18 +1324,22 @@ os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) { // Signal ISR Calls /// Set the specified Signal Flags of an active thread -static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) { +int32_t isrSignalSet (osThreadId thread_id, int32_t signals) { P_TCB ptcb; int32_t sig; ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; + if (ptcb == NULL) { + return (int32_t)0x80000000U; + } - if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) { + return (int32_t)0x80000000U; + } - sig = ptcb->events; // Previous signal flags + sig = (int32_t)ptcb->events; // Previous signal flags - isr_evt_set(signals, ptcb->task_id); // Set event flags + isr_evt_set((uint16_t)signals, ptcb->task_id);// Set event flags return sig; } @@ -1142,8 +1349,8 @@ static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) { /// Set the specified Signal Flags of an active thread int32_t osSignalSet (osThreadId thread_id, int32_t signals) { - if (__get_IPSR() != 0) { // in ISR - return isrSignalSet(thread_id, signals); + if (__get_IPSR() != 0U) { // in ISR + return isrSignalSet(thread_id, signals); } else { // in Thread return __svcSignalSet(thread_id, signals); } @@ -1151,21 +1358,17 @@ int32_t osSignalSet (osThreadId thread_id, int32_t signals) { /// Clear the specified Signal Flags of an active thread int32_t osSignalClear (osThreadId thread_id, int32_t signals) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return (int32_t)0x80000000U; // Not allowed in ISR + } return __svcSignalClear(thread_id, signals); } -/// Get Signal Flags status of an active thread -int32_t osSignalGet (osThreadId thread_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR - return __svcSignalGet(thread_id); -} - /// Wait for one or more Signal Flags to become signaled for the current RUNNING thread os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) { osEvent ret; - if (__get_IPSR() != 0) { // Not allowed in ISR + if (__get_IPSR() != 0U) { // Not allowed in ISR ret.status = osErrorISR; return ret; } @@ -1176,15 +1379,15 @@ os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) { // ==== Mutex Management ==== // Mutex Service Calls declarations -SVC_1_1(svcMutexCreate, osMutexId, osMutexDef_t *, RET_pointer) -SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus) -SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus) -SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus) +SVC_1_1(svcMutexCreate, osMutexId, const osMutexDef_t *, RET_pointer) +SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus) +SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus) +SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus) // Mutex Service Calls /// Create and Initialize a Mutex object -osMutexId svcMutexCreate (osMutexDef_t *mutex_def) { +osMutexId svcMutexCreate (const osMutexDef_t *mutex_def) { OS_ID mut; if (mutex_def == NULL) { @@ -1198,7 +1401,7 @@ osMutexId svcMutexCreate (osMutexDef_t *mutex_def) { return NULL; } - if (((P_MUCB)mut)->cb_type != 0) { + if (((P_MUCB)mut)->cb_type != 0U) { sysThreadError(osErrorParameter); return NULL; } @@ -1214,14 +1417,18 @@ osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) { OS_RESULT res; mut = rt_id2obj(mutex_id); - if (mut == NULL) return osErrorParameter; + if (mut == NULL) { + return osErrorParameter; + } - if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + if (((P_MUCB)mut)->cb_type != MUCB) { + return osErrorParameter; + } res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex if (res == OS_R_TMO) { - return (millisec ? osErrorTimeoutResource : osErrorResource); + return ((millisec != 0U) ? osErrorTimeoutResource : osErrorResource); } return osOK; @@ -1233,13 +1440,19 @@ osStatus svcMutexRelease (osMutexId mutex_id) { OS_RESULT res; mut = rt_id2obj(mutex_id); - if (mut == NULL) return osErrorParameter; + if (mut == NULL) { + return osErrorParameter; + } - if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + if (((P_MUCB)mut)->cb_type != MUCB) { + return osErrorParameter; + } res = rt_mut_release(mut); // Release Mutex - if (res == OS_R_NOK) return osErrorResource; // Thread not owner or Zero Counter + if (res == OS_R_NOK) { + return osErrorResource; // Thread not owner or Zero Counter + } return osOK; } @@ -1249,9 +1462,13 @@ osStatus svcMutexDelete (osMutexId mutex_id) { OS_ID mut; mut = rt_id2obj(mutex_id); - if (mut == NULL) return osErrorParameter; + if (mut == NULL) { + return osErrorParameter; + } - if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter; + if (((P_MUCB)mut)->cb_type != MUCB) { + return osErrorParameter; + } rt_mut_delete(mut); // Release Mutex @@ -1262,9 +1479,11 @@ osStatus svcMutexDelete (osMutexId mutex_id) { // Mutex Public API /// Create and Initialize a Mutex object -osMutexId osMutexCreate (osMutexDef_t *mutex_def) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { +osMutexId osMutexCreate (const osMutexDef_t *mutex_def) { + if (__get_IPSR() != 0U) { + return NULL; // Not allowed in ISR + } + if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { // Privileged and not running return svcMutexCreate(mutex_def); } else { @@ -1274,19 +1493,25 @@ osMutexId osMutexCreate (osMutexDef_t *mutex_def) { /// Wait until a Mutex becomes available osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } return __svcMutexWait(mutex_id, millisec); } /// Release a Mutex that was obtained with osMutexWait osStatus osMutexRelease (osMutexId mutex_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } return __svcMutexRelease(mutex_id); } /// Delete a Mutex that was created by osMutexCreate osStatus osMutexDelete (osMutexId mutex_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } return __svcMutexDelete(mutex_id); } @@ -1295,8 +1520,8 @@ osStatus osMutexDelete (osMutexId mutex_id) { // Semaphore Service Calls declarations SVC_2_1(svcSemaphoreCreate, osSemaphoreId, const osSemaphoreDef_t *, int32_t, RET_pointer) -SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t) -SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus) +SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t) +SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus) SVC_1_1(svcSemaphoreDelete, osStatus, osSemaphoreId, RET_osStatus) // Semaphore Service Calls @@ -1316,7 +1541,7 @@ osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t return NULL; } - if (((P_SCB)sem)->cb_type != 0) { + if (((P_SCB)sem)->cb_type != 0U) { sysThreadError(osErrorParameter); return NULL; } @@ -1326,8 +1551,8 @@ osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t return NULL; } - rt_sem_init(sem, count); // Initialize Semaphore - + rt_sem_init(sem, (uint16_t)count); // Initialize Semaphore + return sem; } @@ -1337,15 +1562,19 @@ int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { OS_RESULT res; sem = rt_id2obj(semaphore_id); - if (sem == NULL) return -1; + if (sem == NULL) { + return -1; + } - if (((P_SCB)sem)->cb_type != SCB) return -1; + if (((P_SCB)sem)->cb_type != SCB) { + return -1; + } res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore - if (res == OS_R_TMO) return 0; // Timeout + if (res == OS_R_TMO) { return 0; } // Timeout - return (((P_SCB)sem)->tokens + 1); + return (int32_t)(((P_SCB)sem)->tokens + 1U); } /// Release a Semaphore @@ -1353,12 +1582,18 @@ osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) { OS_ID sem; sem = rt_id2obj(semaphore_id); - if (sem == NULL) return osErrorParameter; + if (sem == NULL) { + return osErrorParameter; + } - if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; - - if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + if (((P_SCB)sem)->cb_type != SCB) { + return osErrorParameter; + } + if ((int32_t)((P_SCB)sem)->tokens == osFeature_Semaphore) { + return osErrorResource; + } + rt_sem_send(sem); // Release Semaphore return osOK; @@ -1369,9 +1604,13 @@ osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) { OS_ID sem; sem = rt_id2obj(semaphore_id); - if (sem == NULL) return osErrorParameter; + if (sem == NULL) { + return osErrorParameter; + } - if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + if (((P_SCB)sem)->cb_type != SCB) { + return osErrorParameter; + } rt_sem_delete(sem); // Delete Semaphore @@ -1382,15 +1621,21 @@ osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) { // Semaphore ISR Calls /// Release a Semaphore -static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) { +osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) { OS_ID sem; sem = rt_id2obj(semaphore_id); - if (sem == NULL) return osErrorParameter; + if (sem == NULL) { + return osErrorParameter; + } - if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter; + if (((P_SCB)sem)->cb_type != SCB) { + return osErrorParameter; + } - if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource; + if ((int32_t)((P_SCB)sem)->tokens == osFeature_Semaphore) { + return osErrorResource; + } isr_sem_send(sem); // Release Semaphore @@ -1401,9 +1646,11 @@ static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) { // Semaphore Public API /// Create and Initialize a Semaphore object -osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { +osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) { + if (__get_IPSR() != 0U) { + return NULL; // Not allowed in ISR + } + if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { // Privileged and not running return svcSemaphoreCreate(semaphore_def, count); } else { @@ -1413,13 +1660,15 @@ osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count) /// Wait until a Semaphore becomes available int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { - if (__get_IPSR() != 0) return -1; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return -1; // Not allowed in ISR + } return __svcSemaphoreWait(semaphore_id, millisec); } /// Release a Semaphore osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) { - if (__get_IPSR() != 0) { // in ISR + if (__get_IPSR() != 0U) { // in ISR return isrSemaphoreRelease(semaphore_id); } else { // in Thread return __svcSemaphoreRelease(semaphore_id); @@ -1428,7 +1677,9 @@ osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) { /// Delete a Semaphore that was created by osSemaphoreCreate osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) { - if (__get_IPSR() != 0) return osErrorISR; // Not allowed in ISR + if (__get_IPSR() != 0U) { + return osErrorISR; // Not allowed in ISR + } return __svcSemaphoreDelete(semaphore_id); } @@ -1441,18 +1692,18 @@ osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) { static void rt_clr_box (void *box_mem, void *box) { uint32_t *p, n; - if (box) { + if ((box_mem != NULL) && (box != NULL)) { p = box; - for (n = ((P_BM)box_mem)->blk_size; n; n -= 4) { - *p++ = 0; + for (n = ((P_BM)box_mem)->blk_size; n; n -= 4U) { + *p++ = 0U; } } } // Memory Management Service Calls declarations -SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer) -SVC_2_1(sysPoolAlloc, void *, osPoolId, uint32_t, RET_pointer) -SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus) +SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer) +SVC_1_1(sysPoolAlloc, void *, osPoolId, RET_pointer) +SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus) // Memory Management Service & ISR Calls @@ -1461,42 +1712,45 @@ osPoolId svcPoolCreate (const osPoolDef_t *pool_def) { uint32_t blk_sz; if ((pool_def == NULL) || - (pool_def->pool_sz == 0) || - (pool_def->item_sz == 0) || + (pool_def->pool_sz == 0U) || + (pool_def->item_sz == 0U) || (pool_def->pool == NULL)) { sysThreadError(osErrorParameter); return NULL; } - blk_sz = (pool_def->item_sz + 3) & ~3; + blk_sz = (pool_def->item_sz + 3U) & (uint32_t)~3U; - _init_box(pool_def->pool, sizeof(struct OS_BM) + pool_def->pool_sz * blk_sz, blk_sz); + _init_box(pool_def->pool, sizeof(struct OS_BM) + (pool_def->pool_sz * blk_sz), blk_sz); return pool_def->pool; } /// Allocate a memory block from a memory pool -void *sysPoolAlloc (osPoolId pool_id, uint32_t clr) { - void *ptr; +void *sysPoolAlloc (osPoolId pool_id) { + void *mem; - if (pool_id == NULL) return NULL; - - ptr = rt_alloc_box(pool_id); - if (clr) { - rt_clr_box(pool_id, ptr); + if (pool_id == NULL) { + return NULL; } - return ptr; + mem = rt_alloc_box(pool_id); + + return mem; } /// Return an allocated memory block back to a specific memory pool osStatus sysPoolFree (osPoolId pool_id, void *block) { - int32_t res; - - if (pool_id == NULL) return osErrorParameter; + uint32_t res; + + if (pool_id == NULL) { + return osErrorParameter; + } res = rt_free_box(pool_id, block); - if (res != 0) return osErrorValue; + if (res != 0) { + return osErrorValue; + } return osOK; } @@ -1505,9 +1759,11 @@ osStatus sysPoolFree (osPoolId pool_id, void *block) { // Memory Management Public API /// Create and Initialize memory pool -osPoolId osPoolCreate (osPoolDef_t *pool_def) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { +osPoolId osPoolCreate (const osPoolDef_t *pool_def) { + if (__get_IPSR() != 0U) { + return NULL; // Not allowed in ISR + } + if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { // Privileged and not running return svcPoolCreate(pool_def); } else { @@ -1517,25 +1773,31 @@ osPoolId osPoolCreate (osPoolDef_t *pool_def) { /// Allocate a memory block from a memory pool void *osPoolAlloc (osPoolId pool_id) { - if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged - return sysPoolAlloc(pool_id, 0); + if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged + return sysPoolAlloc(pool_id); } else { // in Thread - return __sysPoolAlloc(pool_id, 0); + return __sysPoolAlloc(pool_id); } } /// Allocate a memory block from a memory pool and set memory block to zero void *osPoolCAlloc (osPoolId pool_id) { - if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged - return sysPoolAlloc(pool_id, 1); + void *mem; + + if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged + mem = sysPoolAlloc(pool_id); } else { // in Thread - return __sysPoolAlloc(pool_id, 1); + mem = __sysPoolAlloc(pool_id); } + + rt_clr_box(pool_id, mem); + + return mem; } /// Return an allocated memory block back to a specific memory pool osStatus osPoolFree (osPoolId pool_id, void *block) { - if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) { // in ISR or Privileged + if ((__get_IPSR() != 0U) || ((__get_CONTROL() & 1U) == 0U)) { // in ISR or Privileged return sysPoolFree(pool_id, block); } else { // in Thread return __sysPoolFree(pool_id, block); @@ -1546,28 +1808,28 @@ osStatus osPoolFree (osPoolId pool_id, void *block) { // ==== Message Queue Management Functions ==== // Message Queue Management Service Calls declarations -SVC_2_1(svcMessageCreate, osMessageQId, osMessageQDef_t *, osThreadId, RET_pointer) -SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus) -SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent) +SVC_2_1(svcMessageCreate, osMessageQId, const osMessageQDef_t *, osThreadId, RET_pointer) +SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus) +SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent) // Message Queue Service Calls /// Create and Initialize Message Queue -osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) { +osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { if ((queue_def == NULL) || - (queue_def->queue_sz == 0) || + (queue_def->queue_sz == 0U) || (queue_def->pool == NULL)) { sysThreadError(osErrorParameter); return NULL; } - - if (((P_MCB)queue_def->pool)->cb_type != 0) { + + if (((P_MCB)queue_def->pool)->cb_type != 0U) { sysThreadError(osErrorParameter); return NULL; } - rt_mbx_init(queue_def->pool, 4*(queue_def->queue_sz + 4)); + rt_mbx_init(queue_def->pool, (uint16_t)(4U*(queue_def->queue_sz + 4U))); return queue_def->pool; } @@ -1576,14 +1838,18 @@ osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { OS_RESULT res; - if (queue_id == NULL) return osErrorParameter; + if (queue_id == NULL) { + return osErrorParameter; + } - if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + if (((P_MCB)queue_id)->cb_type != MCB) { + return osErrorParameter; + } res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec)); if (res == OS_R_TMO) { - return (millisec ? osErrorTimeoutResource : osErrorResource); + return ((millisec != 0U) ? osErrorTimeoutResource : osErrorResource); } return osOK; @@ -1605,9 +1871,9 @@ os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) } res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec)); - + if (res == OS_R_TMO) { - ret.status = millisec ? osEventTimeout : osOK; + ret.status = (millisec != 0U) ? osEventTimeout : osOK; return osEvent_ret_value; } @@ -1620,15 +1886,17 @@ os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) // Message Queue ISR Calls /// Put a Message to a Queue -static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { +osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { - if ((queue_id == NULL) || (millisec != 0)) { + if ((queue_id == NULL) || (millisec != 0U)) { return osErrorParameter; } - if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter; + if (((P_MCB)queue_id)->cb_type != MCB) { + return osErrorParameter; + } - if (rt_mbx_check(queue_id) == 0) { // Check if Queue is full + if (rt_mbx_check(queue_id) == 0U) { // Check if Queue is full return osErrorResource; } @@ -1638,11 +1906,11 @@ static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, ui } /// Get a Message or Wait for a Message from a Queue -static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) { +os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) { OS_RESULT res; osEvent ret; - if ((queue_id == NULL) || (millisec != 0)) { + if ((queue_id == NULL) || (millisec != 0U)) { ret.status = osErrorParameter; return ret; } @@ -1653,13 +1921,13 @@ static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t } res = isr_mbx_receive(queue_id, &ret.value.p); - + if (res != OS_R_MBX) { ret.status = osOK; return ret; } - ret.status = osEventMessage; + ret.status = osEventMessage; return ret; } @@ -1668,9 +1936,11 @@ static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t // Message Queue Management Public API /// Create and Initialize Message Queue -osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { +osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) { + if (__get_IPSR() != 0U) { + return NULL; // Not allowed in ISR + } + if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { // Privileged and not running return svcMessageCreate(queue_def, thread_id); } else { @@ -1680,7 +1950,7 @@ osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) /// Put a Message to a Queue osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) { - if (__get_IPSR() != 0) { // in ISR + if (__get_IPSR() != 0U) { // in ISR return isrMessagePut(queue_id, info, millisec); } else { // in Thread return __svcMessagePut(queue_id, info, millisec); @@ -1689,7 +1959,7 @@ osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) /// Get a Message or Wait for a Message from a Queue os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { - if (__get_IPSR() != 0) { // in ISR + if (__get_IPSR() != 0U) { // in ISR return isrMessageGet(queue_id, millisec); } else { // in Thread return __svcMessageGet(queue_id, millisec); @@ -1700,21 +1970,21 @@ os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) { // ==== Mail Queue Management Functions ==== // Mail Queue Management Service Calls declarations -SVC_2_1(svcMailCreate, osMailQId, osMailQDef_t *, osThreadId, RET_pointer) -SVC_4_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, uint32_t, RET_pointer) -SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus) +SVC_2_1(svcMailCreate, osMailQId, const osMailQDef_t *, osThreadId, RET_pointer) +SVC_3_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, RET_pointer) +SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus) // Mail Queue Management Service & ISR Calls /// Create and Initialize mail queue -osMailQId svcMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) { +osMailQId svcMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { uint32_t blk_sz; P_MCB pmcb; void *pool; if ((queue_def == NULL) || - (queue_def->queue_sz == 0) || - (queue_def->item_sz == 0) || + (queue_def->queue_sz == 0U) || + (queue_def->item_sz == 0U) || (queue_def->pool == NULL)) { sysThreadError(osErrorParameter); return NULL; @@ -1723,42 +1993,44 @@ osMailQId svcMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) { pmcb = *(((void **)queue_def->pool) + 0); pool = *(((void **)queue_def->pool) + 1); - if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0)) { + if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0U)) { sysThreadError(osErrorParameter); return NULL; } - blk_sz = (queue_def->item_sz + 3) & ~3; + blk_sz = (queue_def->item_sz + 3U) & (uint32_t)~3U; - _init_box(pool, sizeof(struct OS_BM) + queue_def->queue_sz * blk_sz, blk_sz); - - rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4)); + _init_box(pool, sizeof(struct OS_BM) + (queue_def->queue_sz * blk_sz), blk_sz); + rt_mbx_init(pmcb, (uint16_t)(4U*(queue_def->queue_sz + 4U))); return queue_def->pool; } /// Allocate a memory block from a mail -void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_t clr) { +void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr) { P_MCB pmcb; void *pool; void *mem; - if (queue_id == NULL) return NULL; + if (queue_id == NULL) { + return NULL; + } pmcb = *(((void **)queue_id) + 0); pool = *(((void **)queue_id) + 1); - if ((pool == NULL) || (pmcb == NULL)) return NULL; - - if (isr && (millisec != 0)) return NULL; - - mem = rt_alloc_box(pool); - if (clr) { - rt_clr_box(pool, mem); + if ((pool == NULL) || (pmcb == NULL)) { + return NULL; } - if ((mem == NULL) && (millisec != 0)) { + if ((isr != 0U) && (millisec != 0U)) { + return NULL; + } + + mem = rt_alloc_box(pool); + + if ((mem == NULL) && (millisec != 0U)) { // Put Task to sleep when Memory not available if (pmcb->p_lnk != NULL) { rt_put_prio((P_XCB)pmcb, os_tsk.run); @@ -1767,45 +2039,48 @@ void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_ os_tsk.run->p_lnk = NULL; os_tsk.run->p_rlnk = (P_TCB)pmcb; // Task is waiting to allocate a message - pmcb->state = 3; + pmcb->state = 3U; } rt_block(rt_ms2tick(millisec), WAIT_MBX); } - return mem; + return mem; } /// Free a memory block from a mail osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) { - P_MCB pmcb; - P_TCB ptcb; - void *pool; - void *mem; - int32_t res; + P_MCB pmcb; + P_TCB ptcb; + void *pool; + void *mem; + uint32_t res; - if (queue_id == NULL) return osErrorParameter; + if (queue_id == NULL) { + return osErrorParameter; + } pmcb = *(((void **)queue_id) + 0); pool = *(((void **)queue_id) + 1); - if ((pmcb == NULL) || (pool == NULL)) return osErrorParameter; + if ((pmcb == NULL) || (pool == NULL)) { + return osErrorParameter; + } res = rt_free_box(pool, mail); - if (res != 0) return osErrorValue; + if (res != 0U) { + return osErrorValue; + } - if (pmcb->state == 3) { + if ((pmcb->p_lnk != NULL) && (pmcb->state == 3U)) { // Task is waiting to allocate a message - if (isr) { + if (isr != 0U) { rt_psq_enq (pmcb, (U32)pool); rt_psh_req (); } else { mem = rt_alloc_box(pool); if (mem != NULL) { ptcb = rt_get_first((P_XCB)pmcb); - if (pmcb->p_lnk == NULL) { - pmcb->state = 0; - } rt_ret_val(ptcb, (U32)mem); rt_rmv_dly(ptcb); rt_dispatch(ptcb); @@ -1820,9 +2095,11 @@ osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) { // Mail Queue Management Public API /// Create and Initialize mail queue -osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) { - if (__get_IPSR() != 0) return NULL; // Not allowed in ISR - if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) { +osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) { + if (__get_IPSR() != 0U) { + return NULL; // Not allowed in ISR + } + if (((__get_CONTROL() & 1U) == 0U) && (os_running == 0U)) { // Privileged and not running return svcMailCreate(queue_def, thread_id); } else { @@ -1832,42 +2109,51 @@ osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) { /// Allocate a memory block from a mail void *osMailAlloc (osMailQId queue_id, uint32_t millisec) { - if (__get_IPSR() != 0) { // in ISR - return sysMailAlloc(queue_id, millisec, 1, 0); + if (__get_IPSR() != 0U) { // in ISR + return sysMailAlloc(queue_id, millisec, 1U); } else { // in Thread - return __sysMailAlloc(queue_id, millisec, 0, 0); + return __sysMailAlloc(queue_id, millisec, 0U); } } /// Allocate a memory block from a mail and set memory block to zero void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) { - if (__get_IPSR() != 0) { // in ISR - return sysMailAlloc(queue_id, millisec, 1, 1); + void *pool; + void *mem; + + if (__get_IPSR() != 0U) { // in ISR + mem = sysMailAlloc(queue_id, millisec, 1U); } else { // in Thread - return __sysMailAlloc(queue_id, millisec, 0, 1); + mem = __sysMailAlloc(queue_id, millisec, 0U); } + + pool = *(((void **)queue_id) + 1); + + rt_clr_box(pool, mem); + + return mem; } /// Free a memory block from a mail osStatus osMailFree (osMailQId queue_id, void *mail) { - if (__get_IPSR() != 0) { // in ISR - return sysMailFree(queue_id, mail, 1); + if (__get_IPSR() != 0U) { // in ISR + return sysMailFree(queue_id, mail, 1U); } else { // in Thread - return __sysMailFree(queue_id, mail, 0); + return __sysMailFree(queue_id, mail, 0U); } } /// Put a mail to a queue osStatus osMailPut (osMailQId queue_id, void *mail) { - if (queue_id == NULL) return osErrorParameter; - if (mail == NULL) return osErrorValue; - return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0); + if (queue_id == NULL) { + return osErrorParameter; + } + if (mail == NULL) { + return osErrorValue; + } + return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0U); } -#ifdef __CC_ARM -#pragma push -#pragma Ospace -#endif // __arm__ /// Get a mail from a queue os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { osEvent ret; @@ -1882,6 +2168,23 @@ os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) { return ret; } -#ifdef __CC_ARM -#pragma pop -#endif // __arm__ + + +// ==== RTX Extensions ==== + +// Service Calls declarations +SVC_0_1(rt_suspend, uint32_t, RET_uint32_t) +SVC_1_0(rt_resume, void, uint32_t) + + +// Public API + +/// Suspends the OS task scheduler +uint32_t os_suspend (void) { + return __rt_suspend(); +} + +/// Resumes the OS task scheduler +void os_resume (uint32_t sleep_time) { + __rt_resume(sleep_time); +} diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Event.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Event.c index acd8ccc205..8e9178b955 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Event.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Event.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_EVENT.C * Purpose: Implements waits and wake-ups for event flags - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_System.h" #include "rt_Event.h" #include "rt_List.h" @@ -86,7 +86,7 @@ void rt_evt_set (U16 event_flags, OS_TID task_id) { /* Set one or more event flags of a selectable task. */ P_TCB p_tcb; - p_tcb = os_active_TCB[task_id-1]; + p_tcb = os_active_TCB[task_id-1U]; if (p_tcb == NULL) { return; } @@ -108,7 +108,7 @@ wkup: p_tcb->events &= ~event_flags; rt_rmv_dly (p_tcb); p_tcb->state = READY; #ifdef __CMSIS_RTOS - rt_ret_val2(p_tcb, 0x08/*osEventSignal*/, p_tcb->waits); + rt_ret_val2(p_tcb, 0x08U/*osEventSignal*/, p_tcb->waits); #else rt_ret_val (p_tcb, OS_R_EVT); #endif @@ -123,7 +123,7 @@ wkup: p_tcb->events &= ~event_flags; void rt_evt_clr (U16 clear_flags, OS_TID task_id) { /* Clear one or more event flags (identified by "clear_flags") of a */ /* selectable task (identified by "task"). */ - P_TCB task = os_active_TCB[task_id-1]; + P_TCB task = os_active_TCB[task_id-1U]; if (task == NULL) { return; @@ -136,7 +136,7 @@ void rt_evt_clr (U16 clear_flags, OS_TID task_id) { void isr_evt_set (U16 event_flags, OS_TID task_id) { /* Same function as "os_evt_set", but to be called by ISRs. */ - P_TCB p_tcb = os_active_TCB[task_id-1]; + P_TCB p_tcb = os_active_TCB[task_id-1U]; if (p_tcb == NULL) { return; @@ -176,7 +176,7 @@ rdy: p_CB->events &= ~event_flags; rt_rmv_dly (p_CB); p_CB->state = READY; #ifdef __CMSIS_RTOS - rt_ret_val2(p_CB, 0x08/*osEventSignal*/, p_CB->waits); + rt_ret_val2(p_CB, 0x08U/*osEventSignal*/, p_CB->waits); #else rt_ret_val (p_CB, OS_R_EVT); #endif diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Event.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Event.h index 8b92f3c4c4..cffe7cbee3 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Event.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Event.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_EVENT.H * Purpose: Implements waits and wake-ups for event flags - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -15,19 +15,19 @@ * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * - Neither the name of ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without * specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *---------------------------------------------------------------------------*/ diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h index 2ab4b36cc7..d6bac9a0db 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_HAL_CM.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_HAL_CM.H * Purpose: Hardware Abstraction Layer for Cortex-M definitions - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,33 +33,38 @@ *---------------------------------------------------------------------------*/ /* Definitions */ -#define INITIAL_xPSR 0x01000000 -#define DEMCR_TRCENA 0x01000000 -#define ITM_ITMENA 0x00000001 -#define MAGIC_WORD 0xE25A2EA5 +#define INITIAL_xPSR 0x01000000U +#define DEMCR_TRCENA 0x01000000U +#define ITM_ITMENA 0x00000001U +#define MAGIC_WORD 0xE25A2EA5U +#define MAGIC_PATTERN 0xCCCCCCCCU #if defined (__CC_ARM) /* ARM Compiler */ -#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !NO_EXCLUSIVE_ACCESS) +#if ((defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) && !defined(NO_EXCLUSIVE_ACCESS)) #define __USE_EXCLUSIVE_ACCESS #else #undef __USE_EXCLUSIVE_ACCESS #endif +#ifndef __CMSIS_GENERIC +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0) +#endif + #elif defined (__GNUC__) /* GNU Compiler */ #undef __USE_EXCLUSIVE_ACCESS #if defined (__CORTEX_M0) || defined (__CORTEX_M0PLUS) -#define __TARGET_ARCH_6S_M 1 -#else -#define __TARGET_ARCH_6S_M 0 +#define __TARGET_ARCH_6S_M #endif #if defined (__VFP_FP__) && !defined(__SOFTFP__) -#define __TARGET_FPU_VFP 1 -#else -#define __TARGET_FPU_VFP 0 +#define __TARGET_FPU_VFP #endif #define __inline inline @@ -81,12 +86,17 @@ __attribute__((always_inline)) static inline U32 __disable_irq(void) return(result & 1); } +__attribute__((always_inline)) static inline void __DMB(void) +{ + __asm volatile ("dmb 0xF":::"memory"); +} + #endif __attribute__(( always_inline)) static inline U8 __clz(U32 value) { U8 result; - + __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); return(result); } @@ -97,14 +107,10 @@ __attribute__(( always_inline)) static inline U8 __clz(U32 value) #if (__CORE__ == __ARM6M__) #define __TARGET_ARCH_6S_M 1 -#else -#define __TARGET_ARCH_6S_M 0 #endif #if defined __ARMVFP__ #define __TARGET_FPU_VFP 1 -#else -#define __TARGET_FPU_VFP 0 #endif #define __inline inline @@ -119,7 +125,7 @@ static inline void __enable_irq(void) static inline U32 __disable_irq(void) { U32 result; - + __asm volatile ("mrs %0, primask" : "=r" (result)); __asm volatile ("cpsid i"); return(result & 1); @@ -130,7 +136,7 @@ static inline U32 __disable_irq(void) static inline U8 __clz(U32 value) { U8 result; - + __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); return(result); } @@ -138,59 +144,59 @@ static inline U8 __clz(U32 value) #endif /* NVIC registers */ -#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010)) -#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014)) -#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018)) -#define NVIC_ISER ((volatile U32 *)0xE000E100) -#define NVIC_ICER ((volatile U32 *)0xE000E180) -#if (__TARGET_ARCH_6S_M) -#define NVIC_IP ((volatile U32 *)0xE000E400) +#define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010U)) +#define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014U)) +#define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018U)) +#define NVIC_ISER ((volatile U32 *)0xE000E100U) +#define NVIC_ICER ((volatile U32 *)0xE000E180U) +#if defined(__TARGET_ARCH_6S_M) +#define NVIC_IP ((volatile U32 *)0xE000E400U) #else -#define NVIC_IP ((volatile U8 *)0xE000E400) +#define NVIC_IP ((volatile U8 *)0xE000E400U) #endif -#define NVIC_INT_CTRL (*((volatile U32 *)0xE000ED04)) -#define NVIC_AIR_CTRL (*((volatile U32 *)0xE000ED0C)) -#define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1C)) -#define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20)) +#define NVIC_INT_CTRL (*((volatile U32 *)0xE000ED04U)) +#define NVIC_AIR_CTRL (*((volatile U32 *)0xE000ED0CU)) +#define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1CU)) +#define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20U)) -#define OS_PEND_IRQ() NVIC_INT_CTRL = (1<<28) -#define OS_PENDING ((NVIC_INT_CTRL >> 26) & (1<<2 | 1)) -#define OS_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_PENDING) << 25 -#define OS_PEND(fl,p) NVIC_INT_CTRL = (fl | p<<2) << 26 -#define OS_LOCK() NVIC_ST_CTRL = 0x0005 -#define OS_UNLOCK() NVIC_ST_CTRL = 0x0007 +#define OS_PEND_IRQ() NVIC_INT_CTRL = (1UL<<28) +#define OS_PENDING ((NVIC_INT_CTRL >> 26) & 5U) +#define OS_UNPEND(fl) NVIC_INT_CTRL = (U32)(fl = (U8)OS_PENDING) << 25 +#define OS_PEND(fl,p) NVIC_INT_CTRL = (U32)(fl | (U8)(p<<2)) << 26 +#define OS_LOCK() NVIC_ST_CTRL = 0x0005U +#define OS_UNLOCK() NVIC_ST_CTRL = 0x0007U -#define OS_X_PENDING ((NVIC_INT_CTRL >> 28) & 1) -#define OS_X_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_X_PENDING) << 27 -#define OS_X_PEND(fl,p) NVIC_INT_CTRL = (fl | p) << 28 -#if (__TARGET_ARCH_6S_M) -#define OS_X_INIT(n) NVIC_IP[n>>2] |= 0xFF << (8*(n & 0x03)); \ - NVIC_ISER[n>>5] = 1 << (n & 0x1F) +#define OS_X_PENDING ((NVIC_INT_CTRL >> 28) & 1U) +#define OS_X_UNPEND(fl) NVIC_INT_CTRL = (U32)(fl = (U8)OS_X_PENDING) << 27 +#define OS_X_PEND(fl,p) NVIC_INT_CTRL = (U32)(fl | p) << 28 +#if defined(__TARGET_ARCH_6S_M) +#define OS_X_INIT(n) NVIC_IP[n>>2] |= (U32)0xFFU << ((n & 0x03U) << 3); \ + NVIC_ISER[n>>5] = (U32)1U << (n & 0x1FU) #else -#define OS_X_INIT(n) NVIC_IP[n] = 0xFF; \ - NVIC_ISER[n>>5] = 1 << (n & 0x1F) +#define OS_X_INIT(n) NVIC_IP[n] = 0xFFU; \ + NVIC_ISER[n>>5] = (U32)1U << (n & 0x1FU) #endif -#define OS_X_LOCK(n) NVIC_ICER[n>>5] = 1 << (n & 0x1F) -#define OS_X_UNLOCK(n) NVIC_ISER[n>>5] = 1 << (n & 0x1F) +#define OS_X_LOCK(n) NVIC_ICER[n>>5] = (U32)1U << (n & 0x1FU) +#define OS_X_UNLOCK(n) NVIC_ISER[n>>5] = (U32)1U << (n & 0x1FU) /* Core Debug registers */ -#define DEMCR (*((volatile U32 *)0xE000EDFC)) +#define DEMCR (*((volatile U32 *)0xE000EDFCU)) /* ITM registers */ -#define ITM_CONTROL (*((volatile U32 *)0xE0000E80)) -#define ITM_ENABLE (*((volatile U32 *)0xE0000E00)) -#define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078)) -#define ITM_PORT31_U32 (*((volatile U32 *)0xE000007C)) -#define ITM_PORT31_U16 (*((volatile U16 *)0xE000007C)) -#define ITM_PORT31_U8 (*((volatile U8 *)0xE000007C)) +#define ITM_CONTROL (*((volatile U32 *)0xE0000E80U)) +#define ITM_ENABLE (*((volatile U32 *)0xE0000E00U)) +#define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078U)) +#define ITM_PORT31_U32 (*((volatile U32 *)0xE000007CU)) +#define ITM_PORT31_U16 (*((volatile U16 *)0xE000007CU)) +#define ITM_PORT31_U8 (*((volatile U8 *)0xE000007CU)) /* Variables */ extern BIT dbg_msg; /* Functions */ #ifdef __USE_EXCLUSIVE_ACCESS - #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) - #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) + #define rt_inc(p) while(__strex((__ldrex(p)+1U),p)) + #define rt_dec(p) while(__strex((__ldrex(p)-1U),p)) #else #define rt_inc(p) __disable_irq();(*p)++;__enable_irq(); #define rt_dec(p) __disable_irq();(*p)--;__enable_irq(); @@ -203,18 +209,18 @@ __inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { if ((cnt = __ldrex(count)) == size) { __clrex(); return (cnt); } - } while (__strex(cnt+1, count)); + } while (__strex(cnt+1U, count)); do { - c2 = (cnt = __ldrex(first)) + 1; - if (c2 == size) c2 = 0; + c2 = (cnt = __ldrex(first)) + 1U; + if (c2 == size) { c2 = 0U; } } while (__strex(c2, first)); #else __disable_irq(); if ((cnt = *count) < size) { - *count = cnt+1; - c2 = (cnt = *first) + 1; - if (c2 == size) c2 = 0; - *first = c2; + *count = (U8)(cnt+1U); + c2 = (cnt = *first) + 1U; + if (c2 == size) { c2 = 0U; } + *first = (U8)c2; } __enable_irq (); #endif @@ -223,25 +229,33 @@ __inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { __inline static void rt_systick_init (void) { NVIC_ST_RELOAD = os_trv; - NVIC_ST_CURRENT = 0; - NVIC_ST_CTRL = 0x0007; - NVIC_SYS_PRI3 |= 0xFF000000; + NVIC_ST_CURRENT = 0U; + NVIC_ST_CTRL = 0x0007U; + NVIC_SYS_PRI3 |= 0xFF000000U; +} + +__inline static U32 rt_systick_val (void) { + return (os_trv - NVIC_ST_CURRENT); +} + +__inline static U32 rt_systick_ovf (void) { + return ((NVIC_INT_CTRL >> 26) & 1U); } __inline static void rt_svc_init (void) { -#if !(__TARGET_ARCH_6S_M) - int sh,prigroup; +#if !defined(__TARGET_ARCH_6S_M) + U32 sh,prigroup; #endif - NVIC_SYS_PRI3 |= 0x00FF0000; -#if (__TARGET_ARCH_6S_M) - NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000; + NVIC_SYS_PRI3 |= 0x00FF0000U; +#if defined(__TARGET_ARCH_6S_M) + NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000U; #else - sh = 8 - __clz (~((NVIC_SYS_PRI3 << 8) & 0xFF000000)); - prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07); + sh = 8U - __clz(~((NVIC_SYS_PRI3 << 8) & 0xFF000000U)); + prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07U); if (prigroup >= sh) { - sh = prigroup + 1; + sh = prigroup + 1U; } - NVIC_SYS_PRI2 = ((0xFEFFFFFF << sh) & 0xFF000000) | (NVIC_SYS_PRI2 & 0x00FFFFFF); + NVIC_SYS_PRI2 = ((0xFEFFFFFFU << sh) & 0xFF000000U) | (NVIC_SYS_PRI2 & 0x00FFFFFFU); #endif } @@ -249,7 +263,7 @@ extern void rt_set_PSP (U32 stack); extern U32 rt_get_PSP (void); extern void os_set_env (void); extern void *_alloc_box (void *box_mem); -extern int _free_box (void *box_mem, void *box); +extern U32 _free_box (void *box_mem, void *box); extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); extern void rt_ret_val (P_TCB p_TCB, U32 v0); @@ -262,8 +276,8 @@ extern void dbg_task_switch (U32 task_id); #ifdef DBG_MSG #define DBG_INIT() dbg_init() #define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create) -#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new_tsk != os_tsk.run)) \ - dbg_task_switch(task_id) +#define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new_tsk!=os_tsk.run)) \ + dbg_task_switch(task_id) #else #define DBG_INIT() #define DBG_TASK_NOTIFY(p_tcb,create) @@ -273,4 +287,3 @@ extern void dbg_task_switch (U32 task_id); /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/ - diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_List.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_List.c index 2134d14b38..fbf4a35aef 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_List.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_List.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_LIST.C * Purpose: Functions for the management of different lists - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_System.h" #include "rt_List.h" #include "rt_Task.h" @@ -65,13 +65,13 @@ void rt_put_prio (P_XCB p_CB, P_TCB p_task) { U32 prio; BOOL sem_mbx = __FALSE; - if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + if ((p_CB->cb_type == SCB) || (p_CB->cb_type == MCB) || (p_CB->cb_type == MUCB)) { sem_mbx = __TRUE; } prio = p_task->prio; p_CB2 = p_CB->p_lnk; /* Search for an entry in the list */ - while (p_CB2 != NULL && prio <= p_CB2->prio) { + while ((p_CB2 != NULL) && (prio <= p_CB2->prio)) { p_CB = (P_XCB)p_CB2; p_CB2 = p_CB2->p_lnk; } @@ -99,7 +99,7 @@ P_TCB rt_get_first (P_XCB p_CB) { p_first = p_CB->p_lnk; p_CB->p_lnk = p_first->p_lnk; - if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { + if ((p_CB->cb_type == SCB) || (p_CB->cb_type == MCB) || (p_CB->cb_type == MUCB)) { if (p_first->p_lnk != NULL) { p_first->p_lnk->p_rlnk = (P_TCB)p_CB; p_first->p_lnk = NULL; @@ -176,7 +176,7 @@ void rt_put_dly (P_TCB p_task, U16 delay) { p = (P_TCB)&os_dly; if (p->p_dlnk == NULL) { /* Delay list empty */ - delta = 0; + delta = 0U; goto last; } delta = os_dly.delta_time; @@ -187,7 +187,7 @@ last: p_task->p_dlnk = NULL; p->p_dlnk = p_task; p_task->p_blnk = p; p->delta_time = (U16)(idelay - delta); - p_task->delta_time = 0; + p_task->delta_time = 0U; return; } p = p->p_dlnk; @@ -215,7 +215,7 @@ void rt_dec_dly (void) { return; } os_dly.delta_time--; - while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) { + while ((os_dly.delta_time == 0U) && (os_dly.p_dlnk != NULL)) { p_rdy = os_dly.p_dlnk; if (p_rdy->p_rlnk != NULL) { /* Task is really enqueued, remove task from semaphore/mailbox */ @@ -236,7 +236,7 @@ void rt_dec_dly (void) { p_rdy->state = READY; os_dly.p_dlnk = p_rdy->p_dlnk; if (p_rdy->p_dlnk != NULL) { - p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; + p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; p_rdy->p_dlnk = NULL; } p_rdy->p_blnk = NULL; @@ -290,7 +290,7 @@ void rt_rmv_dly (P_TCB p_task) { } else { /* 'p_task' is at the end of list */ - p_b->delta_time = 0; + p_b->delta_time = 0U; } p_task->p_blnk = NULL; } @@ -313,8 +313,6 @@ void rt_psq_enq (OS_ID entry, U32 arg) { } } - /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/ - diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_List.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_List.h index cb3008e713..7d5385f5fc 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_List.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_List.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_LIST.H * Purpose: Functions for the management of different lists - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,11 +35,11 @@ /* Definitions */ /* Values for 'cb_type' */ -#define TCB 0 -#define MCB 1 -#define SCB 2 -#define MUCB 3 -#define HCB 4 +#define TCB 0U +#define MCB 1U +#define SCB 2U +#define MUCB 3U +#define HCB 4U /* Variables */ extern struct OS_XCB os_rdy; diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c index ef28b7639c..456b0ac6e2 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_MAILBOX.C * Purpose: Implements waits and wake-ups for mailbox messages - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_System.h" #include "rt_List.h" #include "rt_Mailbox.h" @@ -54,14 +54,14 @@ void rt_mbx_init (OS_ID mailbox, U16 mbx_size) { P_MCB p_MCB = mailbox; p_MCB->cb_type = MCB; - p_MCB->state = 0; - p_MCB->isr_st = 0; + p_MCB->state = 0U; + p_MCB->isr_st = 0U; p_MCB->p_lnk = NULL; - p_MCB->first = 0; - p_MCB->last = 0; - p_MCB->count = 0; - p_MCB->size = (mbx_size + sizeof(void *) - sizeof(struct OS_MCB)) / - (U32)sizeof (void *); + p_MCB->first = 0U; + p_MCB->last = 0U; + p_MCB->count = 0U; + p_MCB->size = (U16)((mbx_size - (sizeof(struct OS_MCB) - (sizeof(void *)))) + / sizeof(void *)); } @@ -72,11 +72,11 @@ OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { P_MCB p_MCB = mailbox; P_TCB p_TCB; - if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 1)) { + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 1U)) { /* A task is waiting for message */ p_TCB = rt_get_first ((P_XCB)p_MCB); #ifdef __CMSIS_RTOS - rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); + rt_ret_val2(p_TCB, 0x10U/*osEventMessage*/, (U32)p_msg); #else *p_TCB->msg = p_msg; rt_ret_val (p_TCB, OS_R_MBX); @@ -90,7 +90,7 @@ OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { /* No free message entry, wait for one. If message queue is full, */ /* then no task is waiting for message. The 'p_MCB->p_lnk' list */ /* pointer can now be reused for send message waits task list. */ - if (timeout == 0) { + if (timeout == 0U) { return (OS_R_TMO); } if (p_MCB->p_lnk != NULL) { @@ -100,8 +100,8 @@ OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { p_MCB->p_lnk = os_tsk.run; os_tsk.run->p_lnk = NULL; os_tsk.run->p_rlnk = (P_TCB)p_MCB; - /* Task is waiting to send a message */ - p_MCB->state = 2; + /* Task is waiting to send a message */ + p_MCB->state = 2U; } os_tsk.run->msg = p_msg; rt_block (timeout, WAIT_MBX); @@ -111,7 +111,7 @@ OS_RESULT rt_mbx_send (OS_ID mailbox, void *p_msg, U16 timeout) { p_MCB->msg[p_MCB->first] = p_msg; rt_inc (&p_MCB->count); if (++p_MCB->first == p_MCB->size) { - p_MCB->first = 0; + p_MCB->first = 0U; } } return (OS_R_OK); @@ -130,19 +130,19 @@ OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { if (p_MCB->count) { *message = p_MCB->msg[p_MCB->last]; if (++p_MCB->last == p_MCB->size) { - p_MCB->last = 0; + p_MCB->last = 0U; } - if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2)) { + if ((p_MCB->p_lnk != NULL) && (p_MCB->state == 2U)) { /* A task is waiting to send message */ p_TCB = rt_get_first ((P_XCB)p_MCB); #ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0/*osOK*/); + rt_ret_val(p_TCB, 0U/*osOK*/); #else rt_ret_val(p_TCB, OS_R_OK); #endif p_MCB->msg[p_MCB->first] = p_TCB->msg; if (++p_MCB->first == p_MCB->size) { - p_MCB->first = 0; + p_MCB->first = 0U; } rt_rmv_dly (p_TCB); rt_dispatch (p_TCB); @@ -153,7 +153,7 @@ OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { return (OS_R_OK); } /* No message available: wait for one */ - if (timeout == 0) { + if (timeout == 0U) { return (OS_R_TMO); } if (p_MCB->p_lnk != NULL) { @@ -163,8 +163,8 @@ OS_RESULT rt_mbx_wait (OS_ID mailbox, void **message, U16 timeout) { p_MCB->p_lnk = os_tsk.run; os_tsk.run->p_lnk = NULL; os_tsk.run->p_rlnk = (P_TCB)p_MCB; - /* Task is waiting to receive a message */ - p_MCB->state = 1; + /* Task is waiting to receive a message */ + p_MCB->state = 1U; } rt_block(timeout, WAIT_MBX); #ifndef __CMSIS_RTOS @@ -181,7 +181,7 @@ OS_RESULT rt_mbx_check (OS_ID mailbox) { /* that can be stored to a mailbox. It returns 0 when mailbox is full. */ P_MCB p_MCB = mailbox; - return (p_MCB->size - p_MCB->count); + return ((U32)(p_MCB->size - p_MCB->count)); } @@ -206,14 +206,14 @@ OS_RESULT isr_mbx_receive (OS_ID mailbox, void **message) { if (p_MCB->count) { /* A message is available in the fifo buffer. */ *message = p_MCB->msg[p_MCB->last]; - if (p_MCB->state == 2) { + if (p_MCB->state == 2U) { /* A task is locked waiting to send message */ - rt_psq_enq (p_MCB, 0); + rt_psq_enq (p_MCB, 0U); rt_psh_req (); } rt_dec (&p_MCB->count); if (++p_MCB->last == p_MCB->size) { - p_MCB->last = 0; + p_MCB->last = 0U; } return (OS_R_MBX); } @@ -233,7 +233,7 @@ void rt_mbx_psh (P_MCB p_CB, void *p_msg) { case 3: /* Task is waiting to allocate memory, remove it from the waiting list */ mem = rt_alloc_box(p_msg); - if (mem == NULL) break; + if (mem == NULL) { break; } p_TCB = rt_get_first ((P_XCB)p_CB); rt_ret_val(p_TCB, (U32)mem); p_TCB->state = READY; @@ -245,14 +245,14 @@ void rt_mbx_psh (P_MCB p_CB, void *p_msg) { /* Task is waiting to send a message, remove it from the waiting list */ p_TCB = rt_get_first ((P_XCB)p_CB); #ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0/*osOK*/); + rt_ret_val(p_TCB, 0U/*osOK*/); #else rt_ret_val(p_TCB, OS_R_OK); #endif p_CB->msg[p_CB->first] = p_TCB->msg; rt_inc (&p_CB->count); if (++p_CB->first == p_CB->size) { - p_CB->first = 0; + p_CB->first = 0U; } p_TCB->state = READY; rt_rmv_dly (p_TCB); @@ -262,7 +262,7 @@ void rt_mbx_psh (P_MCB p_CB, void *p_msg) { /* Task is waiting for a message, pass the message to the task directly */ p_TCB = rt_get_first ((P_XCB)p_CB); #ifdef __CMSIS_RTOS - rt_ret_val2(p_TCB, 0x10/*osEventMessage*/, (U32)p_msg); + rt_ret_val2(p_TCB, 0x10U/*osEventMessage*/, (U32)p_msg); #else *p_TCB->msg = p_msg; rt_ret_val (p_TCB, OS_R_MBX); @@ -271,22 +271,23 @@ void rt_mbx_psh (P_MCB p_CB, void *p_msg) { rt_rmv_dly (p_TCB); rt_put_prio (&os_rdy, p_TCB); break; + default: + break; } else { - /* No task is waiting for a message, store it to the mailbox queue */ - if (p_CB->count < p_CB->size) { - p_CB->msg[p_CB->first] = p_msg; - rt_inc (&p_CB->count); - if (++p_CB->first == p_CB->size) { - p_CB->first = 0; - } - } - else { - os_error (OS_ERR_MBX_OVF); + /* No task is waiting for a message, store it to the mailbox queue */ + if (p_CB->count < p_CB->size) { + p_CB->msg[p_CB->first] = p_msg; + rt_inc (&p_CB->count); + if (++p_CB->first == p_CB->size) { + p_CB->first = 0U; } + } + else { + os_error (OS_ERR_MBX_OVF); + } } } /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/ - diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h index 0c8e2f39b2..5110541a91 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mailbox.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_MAILBOX.H * Purpose: Implements waits and wake-ups for mailbox messages - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c index 5b96ae0e65..8df30441f1 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_MEMBOX.C * Purpose: Interface functions for fixed memory block management system - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_System.h" #include "rt_MemBox.h" #include "rt_HAL_CM.h" @@ -45,7 +45,7 @@ /*--------------------------- _init_box -------------------------------------*/ -int _init_box (void *box_mem, U32 box_size, U32 blk_size) { +U32 _init_box (void *box_mem, U32 box_size, U32 blk_size) { /* Initialize memory block system, returns 0 if OK, 1 if fails. */ void *end; void *blk; @@ -54,20 +54,20 @@ int _init_box (void *box_mem, U32 box_size, U32 blk_size) { /* Create memory structure. */ if (blk_size & BOX_ALIGN_8) { - /* Memory blocks 8-byte aligned. */ - blk_size = ((blk_size & ~BOX_ALIGN_8) + 7) & ~7; - sizeof_bm = (sizeof (struct OS_BM) + 7) & ~7; + /* Memory blocks 8-byte aligned. */ + blk_size = ((blk_size & ~BOX_ALIGN_8) + 7U) & ~(U32)7U; + sizeof_bm = (sizeof (struct OS_BM) + 7U) & ~(U32)7U; } else { /* Memory blocks 4-byte aligned. */ - blk_size = (blk_size + 3) & ~3; + blk_size = (blk_size + 3U) & ~(U32)3U; sizeof_bm = sizeof (struct OS_BM); } - if (blk_size == 0) { - return (1); + if (blk_size == 0U) { + return (1U); } if ((blk_size + sizeof_bm) > box_size) { - return (1); + return (1U); } /* Create a Memory structure. */ blk = ((U8 *) box_mem) + sizeof_bm; @@ -80,13 +80,13 @@ int _init_box (void *box_mem, U32 box_size, U32 blk_size) { end = ((U8 *) end) - blk_size; while (1) { next = ((U8 *) blk) + blk_size; - if (next > end) break; + if (next > end) { break; } *((void **)blk) = next; blk = next; } /* end marker */ - *((void **)blk) = 0; - return (0); + *((void **)blk) = 0U; + return (0U); } /*--------------------------- rt_alloc_box ----------------------------------*/ @@ -95,17 +95,17 @@ void *rt_alloc_box (void *box_mem) { /* Allocate a memory block and return start address. */ void **free; #ifndef __USE_EXCLUSIVE_ACCESS - int irq_dis; + U32 irq_mask; - irq_dis = __disable_irq (); + irq_mask = (U32)__disable_irq (); free = ((P_BM) box_mem)->free; if (free) { ((P_BM) box_mem)->free = *free; } - if (!irq_dis) __enable_irq (); + if (irq_mask == 0U) { __enable_irq (); } #else do { - if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0) { + if ((free = (void **)__ldrex(&((P_BM) box_mem)->free)) == 0U) { __clrex(); break; } @@ -126,8 +126,8 @@ void *_calloc_box (void *box_mem) { free = _alloc_box (box_mem); if (free) { p = free; - for (i = ((P_BM) box_mem)->blk_size; i; i -= 4) { - *p = 0; + for (i = ((P_BM) box_mem)->blk_size; i; i -= 4U) { + *p = 0U; p++; } } @@ -137,30 +137,32 @@ void *_calloc_box (void *box_mem) { /*--------------------------- rt_free_box -----------------------------------*/ -int rt_free_box (void *box_mem, void *box) { +U32 rt_free_box (void *box_mem, void *box) { /* Free a memory block, returns 0 if OK, 1 if box does not belong to box_mem */ #ifndef __USE_EXCLUSIVE_ACCESS - int irq_dis; + U32 irq_mask; #endif - if (box < box_mem || box >= ((P_BM) box_mem)->end) { - return (1); + if ((box < box_mem) || (box >= ((P_BM) box_mem)->end)) { + return (1U); } #ifndef __USE_EXCLUSIVE_ACCESS - irq_dis = __disable_irq (); + irq_mask = (U32)__disable_irq (); *((void **)box) = ((P_BM) box_mem)->free; ((P_BM) box_mem)->free = box; - if (!irq_dis) __enable_irq (); + if (irq_mask == 0U) { __enable_irq (); } #else do { - *((void **)box) = (void *)__ldrex(&((P_BM) box_mem)->free); + do { + *((void **)box) = ((P_BM) box_mem)->free; + __DMB(); + } while (*(void**)box != (void *)__ldrex(&((P_BM) box_mem)->free)); } while (__strex ((U32)box, &((P_BM) box_mem)->free)); #endif - return (0); + return (0U); } /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/ - diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h index c10a1cbe70..ed8e06fca5 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_MemBox.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_MEMBOX.H * Purpose: Interface functions for fixed memory block management system - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,12 +35,11 @@ /* Functions */ #define rt_init_box _init_box #define rt_calloc_box _calloc_box -extern int _init_box (void *box_mem, U32 box_size, U32 blk_size); +extern U32 _init_box (void *box_mem, U32 box_size, U32 blk_size); extern void *rt_alloc_box (void *box_mem); extern void * _calloc_box (void *box_mem); -extern int rt_free_box (void *box_mem, void *box); +extern U32 rt_free_box (void *box_mem, void *box); /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/ - diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Memory.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Memory.c new file mode 100644 index 0000000000..7ade9e1c0e --- /dev/null +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Memory.c @@ -0,0 +1,140 @@ +/*---------------------------------------------------------------------------- + * CMSIS-RTOS - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMORY.C + * Purpose: Interface functions for Dynamic Memory Management System + * Rev.: V4.79 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "rt_Memory.h" + + +/* Functions */ + +// Initialize Dynamic Memory pool +// Parameters: +// pool: Pointer to memory pool +// size: Size of memory pool in bytes +// Return: 0 - OK, 1 - Error + +U32 rt_init_mem (void *pool, U32 size) { + MEMP *ptr; + + if ((pool == NULL) || (size < sizeof(MEMP))) { return (1U); } + + ptr = (MEMP *)pool; + ptr->next = (MEMP *)((U32)pool + size - sizeof(MEMP *)); + ptr->next->next = NULL; + ptr->len = 0U; + + return (0U); +} + +// Allocate Memory from Memory pool +// Parameters: +// pool: Pointer to memory pool +// size: Size of memory in bytes to allocate +// Return: Pointer to allocated memory + +void *rt_alloc_mem (void *pool, U32 size) { + MEMP *p, *p_search, *p_new; + U32 hole_size; + + if ((pool == NULL) || (size == 0U)) { return NULL; } + + /* Add header offset to 'size' */ + size += sizeof(MEMP); + /* Make sure that block is 4-byte aligned */ + size = (size + 3U) & ~(U32)3U; + + p_search = (MEMP *)pool; + while (1) { + hole_size = (U32)p_search->next - (U32)p_search; + hole_size -= p_search->len; + /* Check if hole size is big enough */ + if (hole_size >= size) { break; } + p_search = p_search->next; + if (p_search->next == NULL) { + /* Failed, we are at the end of the list */ + return NULL; + } + } + + if (p_search->len == 0U) { + /* No block is allocated, set the Length of the first element */ + p_search->len = size; + p = (MEMP *)(((U32)p_search) + sizeof(MEMP)); + } else { + /* Insert new list element into the memory list */ + p_new = (MEMP *)((U32)p_search + p_search->len); + p_new->next = p_search->next; + p_new->len = size; + p_search->next = p_new; + p = (MEMP *)(((U32)p_new) + sizeof(MEMP)); + } + + return (p); +} + +// Free Memory and return it to Memory pool +// Parameters: +// pool: Pointer to memory pool +// mem: Pointer to memory to free +// Return: 0 - OK, 1 - Error + +U32 rt_free_mem (void *pool, void *mem) { + MEMP *p_search, *p_prev, *p_return; + + if ((pool == NULL) || (mem == NULL)) { return (1U); } + + p_return = (MEMP *)((U32)mem - sizeof(MEMP)); + + /* Set list header */ + p_prev = NULL; + p_search = (MEMP *)pool; + while (p_search != p_return) { + p_prev = p_search; + p_search = p_search->next; + if (p_search == NULL) { + /* Valid Memory block not found */ + return (1U); + } + } + + if (p_prev == NULL) { + /* First block to be released, only set length to 0 */ + p_search->len = 0U; + } else { + /* Discard block from chain list */ + p_prev->next = p_search->next; + } + + return (0U); +} diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Memory.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Memory.h new file mode 100644 index 0000000000..26780a4ad3 --- /dev/null +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Memory.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------- + * CMSIS-RTOS - RTX + *---------------------------------------------------------------------------- + * Name: RT_MEMORY.H + * Purpose: Interface functions for Dynamic Memory Management System + * Rev.: V4.79 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Types */ +typedef struct mem { /* << Memory Pool management struct >> */ + struct mem *next; /* Next Memory Block in the list */ + U32 len; /* Length of data block */ +} MEMP; + +/* Functions */ +extern U32 rt_init_mem (void *pool, U32 size); +extern void *rt_alloc_mem (void *pool, U32 size); +extern U32 rt_free_mem (void *pool, void *mem); diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c index c7a996bb50..64afdd7049 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_MUTEX.C * Purpose: Implements mutex synchronization objects - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_List.h" #include "rt_Task.h" #include "rt_Mutex.h" @@ -52,10 +52,10 @@ void rt_mut_init (OS_ID mutex) { P_MUCB p_MCB = mutex; p_MCB->cb_type = MUCB; - p_MCB->prio = 0; - p_MCB->level = 0; + p_MCB->level = 0U; p_MCB->p_lnk = NULL; p_MCB->owner = NULL; + p_MCB->p_mlnk = NULL; } @@ -66,32 +66,64 @@ OS_RESULT rt_mut_delete (OS_ID mutex) { /* Delete a mutex object */ P_MUCB p_MCB = mutex; P_TCB p_TCB; + P_MUCB p_mlnk; + U8 prio; - /* Restore owner task's priority. */ - if (p_MCB->level != 0) { - p_MCB->owner->prio = p_MCB->prio; - if (p_MCB->owner != os_tsk.run) { - rt_resort_prio (p_MCB->owner); + if (p_MCB->level != 0U) { + + p_TCB = p_MCB->owner; + + /* Remove mutex from task mutex owner list. */ + p_mlnk = p_TCB->p_mlnk; + if (p_mlnk == p_MCB) { + p_TCB->p_mlnk = p_MCB->p_mlnk; } + else { + while (p_mlnk) { + if (p_mlnk->p_mlnk == p_MCB) { + p_mlnk->p_mlnk = p_MCB->p_mlnk; + break; + } + p_mlnk = p_mlnk->p_mlnk; + } + } + + /* Restore owner task's priority. */ + prio = p_TCB->prio_base; + p_mlnk = p_TCB->p_mlnk; + while (p_mlnk) { + if ((p_mlnk->p_lnk != NULL) && (p_mlnk->p_lnk->prio > prio)) { + /* A task with higher priority is waiting for mutex. */ + prio = p_mlnk->p_lnk->prio; + } + p_mlnk = p_mlnk->p_mlnk; + } + if (p_TCB->prio != prio) { + p_TCB->prio = prio; + if (p_TCB != os_tsk.run) { + rt_resort_prio (p_TCB); + } + } + } while (p_MCB->p_lnk != NULL) { /* A task is waiting for mutex. */ p_TCB = rt_get_first ((P_XCB)p_MCB); - rt_ret_val(p_TCB, 0/*osOK*/); + rt_ret_val(p_TCB, 0U/*osOK*/); rt_rmv_dly(p_TCB); p_TCB->state = READY; rt_put_prio (&os_rdy, p_TCB); } - if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + if ((os_rdy.p_lnk != NULL) && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { /* preempt running task */ rt_put_prio (&os_rdy, os_tsk.run); os_tsk.run->state = READY; rt_dispatch (NULL); } - p_MCB->cb_type = 0; + p_MCB->cb_type = 0U; return (OS_R_OK); } @@ -104,29 +136,58 @@ OS_RESULT rt_mut_release (OS_ID mutex) { /* Release a mutex object */ P_MUCB p_MCB = mutex; P_TCB p_TCB; + P_MUCB p_mlnk; + U8 prio; - if (p_MCB->level == 0 || p_MCB->owner != os_tsk.run) { + if ((p_MCB->level == 0U) || (p_MCB->owner != os_tsk.run)) { /* Unbalanced mutex release or task is not the owner */ return (OS_R_NOK); } - if (--p_MCB->level != 0) { + if (--p_MCB->level != 0U) { return (OS_R_OK); } + + /* Remove mutex from task mutex owner list. */ + p_mlnk = os_tsk.run->p_mlnk; + if (p_mlnk == p_MCB) { + os_tsk.run->p_mlnk = p_MCB->p_mlnk; + } + else { + while (p_mlnk) { + if (p_mlnk->p_mlnk == p_MCB) { + p_mlnk->p_mlnk = p_MCB->p_mlnk; + break; + } + p_mlnk = p_mlnk->p_mlnk; + } + } + /* Restore owner task's priority. */ - os_tsk.run->prio = p_MCB->prio; + prio = os_tsk.run->prio_base; + p_mlnk = os_tsk.run->p_mlnk; + while (p_mlnk) { + if ((p_mlnk->p_lnk != NULL) && (p_mlnk->p_lnk->prio > prio)) { + /* A task with higher priority is waiting for mutex. */ + prio = p_mlnk->p_lnk->prio; + } + p_mlnk = p_mlnk->p_mlnk; + } + os_tsk.run->prio = prio; + if (p_MCB->p_lnk != NULL) { /* A task is waiting for mutex. */ p_TCB = rt_get_first ((P_XCB)p_MCB); #ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 0/*osOK*/); + rt_ret_val(p_TCB, 0U/*osOK*/); #else - rt_ret_val(p_TCB, OS_R_MUT); + rt_ret_val(p_TCB, OS_R_MUT); #endif rt_rmv_dly (p_TCB); /* A waiting task becomes the owner of this mutex. */ - p_MCB->level = 1; - p_MCB->owner = p_TCB; - p_MCB->prio = p_TCB->prio; + p_MCB->level = 1U; + p_MCB->owner = p_TCB; + p_MCB->p_mlnk = p_TCB->p_mlnk; + p_TCB->p_mlnk = p_MCB; /* Priority inversion, check which task continues. */ if (os_tsk.run->prio >= rt_rdy_prio()) { rt_dispatch (p_TCB); @@ -141,7 +202,7 @@ OS_RESULT rt_mut_release (OS_ID mutex) { } } else { - /* Check if own priority raised by priority inversion. */ + /* Check if own priority lowered by priority inversion. */ if (rt_rdy_prio() > os_tsk.run->prio) { rt_put_prio (&os_rdy, os_tsk.run); os_tsk.run->state = READY; @@ -158,9 +219,10 @@ OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) { /* Wait for a mutex, continue when mutex is free. */ P_MUCB p_MCB = mutex; - if (p_MCB->level == 0) { - p_MCB->owner = os_tsk.run; - p_MCB->prio = os_tsk.run->prio; + if (p_MCB->level == 0U) { + p_MCB->owner = os_tsk.run; + p_MCB->p_mlnk = os_tsk.run->p_mlnk; + os_tsk.run->p_mlnk = p_MCB; goto inc; } if (p_MCB->owner == os_tsk.run) { @@ -169,12 +231,12 @@ inc:p_MCB->level++; return (OS_R_OK); } /* Mutex owned by another task, wait until released. */ - if (timeout == 0) { + if (timeout == 0U) { return (OS_R_TMO); } /* Raise the owner task priority if lower than current priority. */ /* This priority inversion is called priority inheritance. */ - if (p_MCB->prio < os_tsk.run->prio) { + if (p_MCB->owner->prio < os_tsk.run->prio) { p_MCB->owner->prio = os_tsk.run->prio; rt_resort_prio (p_MCB->owner); } diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h index bf15c4d56c..f7db67d52b 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Mutex.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_MUTEX.H * Purpose: Implements mutex synchronization objects - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Robin.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Robin.c index d693dc6524..dd2ca8adec 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Robin.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Robin.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_ROBIN.C * Purpose: Round Robin Task switching - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_List.h" #include "rt_Task.h" #include "rt_Time.h" @@ -68,7 +68,7 @@ __weak void rt_chk_robin (void) { if (os_robin.task != os_rdy.p_lnk) { /* New task was suspended, reset Round Robin timeout. */ os_robin.task = os_rdy.p_lnk; - os_robin.time = (U16)os_time + os_robin.tout - 1; + os_robin.time = (U16)os_time + os_robin.tout - 1U; } if (os_robin.time == (U16)os_time) { /* Round Robin timeout has expired, swap Robin tasks. */ @@ -81,4 +81,3 @@ __weak void rt_chk_robin (void) { /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/ - diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Robin.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Robin.h index 3ccbffcffd..31d8367d43 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Robin.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Robin.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_ROBIN.H * Purpose: Round Robin Task switching definitions - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c index 93ff2bf083..db8d352e32 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_SEMAPHORE.C * Purpose: Implements binary and counting semaphores - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_System.h" #include "rt_List.h" #include "rt_Task.h" @@ -69,20 +69,20 @@ OS_RESULT rt_sem_delete (OS_ID semaphore) { while (p_SCB->p_lnk != NULL) { /* A task is waiting for token */ p_TCB = rt_get_first ((P_XCB)p_SCB); - rt_ret_val(p_TCB, 0); + rt_ret_val(p_TCB, 0U); rt_rmv_dly(p_TCB); p_TCB->state = READY; rt_put_prio (&os_rdy, p_TCB); } - if (os_rdy.p_lnk && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { + if ((os_rdy.p_lnk != NULL) && (os_rdy.p_lnk->prio > os_tsk.run->prio)) { /* preempt running task */ rt_put_prio (&os_rdy, os_tsk.run); os_tsk.run->state = READY; rt_dispatch (NULL); } - p_SCB->cb_type = 0; + p_SCB->cb_type = 0U; return (OS_R_OK); } @@ -100,7 +100,7 @@ OS_RESULT rt_sem_send (OS_ID semaphore) { /* A task is waiting for token */ p_TCB = rt_get_first ((P_XCB)p_SCB); #ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 1); + rt_ret_val(p_TCB, 1U); #else rt_ret_val(p_TCB, OS_R_SEM); #endif @@ -126,7 +126,7 @@ OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) { return (OS_R_OK); } /* No token available: wait for one */ - if (timeout == 0) { + if (timeout == 0U) { return (OS_R_TMO); } if (p_SCB->p_lnk != NULL) { @@ -145,10 +145,10 @@ OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) { /*--------------------------- isr_sem_send ----------------------------------*/ void isr_sem_send (OS_ID semaphore) { - /* Same function as "os_sem"send", but to be called by ISRs */ + /* Same function as "os_sem_send", but to be called by ISRs */ P_SCB p_SCB = semaphore; - rt_psq_enq (p_SCB, 0); + rt_psq_enq (p_SCB, 0U); rt_psh_req (); } @@ -165,7 +165,7 @@ void rt_sem_psh (P_SCB p_CB) { rt_rmv_dly (p_TCB); p_TCB->state = READY; #ifdef __CMSIS_RTOS - rt_ret_val(p_TCB, 1); + rt_ret_val(p_TCB, 1U); #else rt_ret_val(p_TCB, OS_R_SEM); #endif @@ -180,4 +180,3 @@ void rt_sem_psh (P_SCB p_CB) { /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/ - diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h index ec4548000b..e239dc91f9 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Semaphore.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_SEMAPHORE.H * Purpose: Implements binary and counting semaphores - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_System.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_System.c index f48b67bc2b..653ba9bd5c 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_System.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_System.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_SYSTEM.C * Purpose: System Task Manager - * Rev.: V4.60 + * Rev.: V4.80 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_Task.h" #include "rt_System.h" #include "rt_Event.h" @@ -41,6 +41,7 @@ #include "rt_Mailbox.h" #include "rt_Semaphore.h" #include "rt_Time.h" +#include "rt_Timer.h" #include "rt_Robin.h" #include "rt_HAL_CM.h" @@ -48,7 +49,7 @@ * Global Variables *---------------------------------------------------------------------------*/ -int os_tick_irqn; +S32 os_tick_irqn; /*---------------------------------------------------------------------------- * Local Variables @@ -62,28 +63,39 @@ static U8 pend_flags; * Global Functions *---------------------------------------------------------------------------*/ +#define RL_RTX_VER 0x480 + #if defined (__CC_ARM) __asm void $$RTX$$version (void) { /* Export a version number symbol for a version control. */ EXPORT __RL_RTX_VER -__RL_RTX_VER EQU 0x450 +__RL_RTX_VER EQU RL_RTX_VER } #endif /*--------------------------- rt_suspend ------------------------------------*/ + +extern U32 sysUserTimerWakeupTime(void); + U32 rt_suspend (void) { /* Suspend OS scheduler */ - U32 delta = 0xFFFF; + U32 delta = 0xFFFFU; +#ifdef __CMSIS_RTOS + U32 sleep; +#endif rt_tsk_lock(); - + if (os_dly.p_dlnk) { delta = os_dly.delta_time; } -#ifndef __CMSIS_RTOS +#ifdef __CMSIS_RTOS + sleep = sysUserTimerWakeupTime(); + if (sleep < delta) { delta = sleep; } +#else if (os_tmr.next) { if (os_tmr.tcnt < delta) delta = os_tmr.tcnt; } @@ -94,6 +106,9 @@ U32 rt_suspend (void) { /*--------------------------- rt_resume -------------------------------------*/ + +extern void sysUserTimerUpdate (U32 sleep_time); + void rt_resume (U32 sleep_time) { /* Resume OS scheduler after suspend */ P_TCB next; @@ -110,31 +125,33 @@ void rt_resume (U32 sleep_time) { if (delta >= os_dly.delta_time) { delta -= os_dly.delta_time; os_time += os_dly.delta_time; - os_dly.delta_time = 1; + os_dly.delta_time = 1U; while (os_dly.p_dlnk) { rt_dec_dly(); - if (delta == 0) break; + if (delta == 0U) { break; } delta--; os_time++; } } else { - os_time += delta; - os_dly.delta_time -= delta; + os_time += delta; + os_dly.delta_time -= (U16)delta; } } else { os_time += sleep_time; } -#ifndef __CMSIS_RTOS /* Check the user timers. */ +#ifdef __CMSIS_RTOS + sysUserTimerUpdate(sleep_time); +#else if (os_tmr.next) { delta = sleep_time; if (delta >= os_tmr.tcnt) { delta -= os_tmr.tcnt; - os_tmr.tcnt = 1; + os_tmr.tcnt = 1U; while (os_tmr.next) { rt_tmr_tick(); - if (delta == 0) break; + if (delta == 0U) { break; } delta--; } } else { @@ -158,11 +175,11 @@ void rt_tsk_lock (void) { if (os_tick_irqn < 0) { OS_LOCK(); os_lock = __TRUE; - OS_UNPEND (&pend_flags); + OS_UNPEND(pend_flags); } else { - OS_X_LOCK(os_tick_irqn); + OS_X_LOCK((U32)os_tick_irqn); os_lock = __TRUE; - OS_X_UNPEND (&pend_flags); + OS_X_UNPEND(pend_flags); } } @@ -174,12 +191,12 @@ void rt_tsk_unlock (void) { if (os_tick_irqn < 0) { OS_UNLOCK(); os_lock = __FALSE; - OS_PEND (pend_flags, os_psh_flag); + OS_PEND(pend_flags, os_psh_flag); os_psh_flag = __FALSE; } else { - OS_X_UNLOCK(os_tick_irqn); + OS_X_UNLOCK((U32)os_tick_irqn); os_lock = __FALSE; - OS_X_PEND (pend_flags, os_psh_flag); + OS_X_PEND(pend_flags, os_psh_flag); os_psh_flag = __FALSE; } } @@ -190,7 +207,7 @@ void rt_tsk_unlock (void) { void rt_psh_req (void) { /* Initiate a post service handling request if required. */ if (os_lock == __FALSE) { - OS_PEND_IRQ (); + OS_PEND_IRQ(); } else { os_psh_flag = __TRUE; @@ -224,10 +241,10 @@ void rt_pop_req (void) { /* Must be of SCB type */ rt_sem_psh ((P_SCB)p_CB); } - if (++idx == os_psq->size) idx = 0; + if (++idx == os_psq->size) { idx = 0U; } rt_dec (&os_psq->count); } - os_psq->last = idx; + os_psq->last = (U8)idx; next = rt_get_first (&os_rdy); rt_switch_req (next); @@ -236,12 +253,25 @@ void rt_pop_req (void) { /*--------------------------- os_tick_init ----------------------------------*/ -__weak int os_tick_init (void) { +__weak S32 os_tick_init (void) { /* Initialize SysTick timer as system tick timer. */ - rt_systick_init (); + rt_systick_init(); return (-1); /* Return IRQ number of SysTick timer */ } +/*--------------------------- os_tick_val -----------------------------------*/ + +__weak U32 os_tick_val (void) { + /* Get SysTick timer current value (0 .. OS_TRV). */ + return rt_systick_val(); +} + +/*--------------------------- os_tick_ovf -----------------------------------*/ + +__weak U32 os_tick_ovf (void) { + /* Get SysTick timer overflow flag */ + return rt_systick_ovf(); +} /*--------------------------- os_tick_irqack --------------------------------*/ @@ -281,9 +311,11 @@ void rt_systick (void) { } /*--------------------------- rt_stk_check ----------------------------------*/ + __weak void rt_stk_check (void) { +#ifdef __MBED_CMSIS_RTOS_CM /* Check for stack overflow. */ - if (os_tsk.run->task_id == 0x01) { + if (os_tsk.run->task_id == 0x02) { // TODO: For the main thread the check should be done against the main heap pointer } else { if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || @@ -291,6 +323,12 @@ __weak void rt_stk_check (void) { os_error (OS_ERR_STK_OVF); } } +#else + if ((os_tsk.run->tsk_stack < (U32)os_tsk.run->stack) || + (os_tsk.run->stack[0] != MAGIC_WORD)) { + os_error (OS_ERR_STK_OVF); + } +#endif } /*---------------------------------------------------------------------------- diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_System.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_System.h index 91db6487e0..aa30077daf 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_System.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_System.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_SYSTEM.H * Purpose: System Task Manager definitions - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -34,7 +34,7 @@ /* Variables */ #define os_psq ((P_PSQ)&os_fifo) -extern int os_tick_irqn; +extern S32 os_tick_irqn; /* Functions */ extern U32 rt_suspend (void); diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Task.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Task.c index 518f78fefb..7904855d29 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Task.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Task.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_TASK.C * Purpose: Task functions and system start up. - * Rev.: V4.60 + * Rev.: V4.80 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_System.h" #include "rt_Task.h" #include "rt_List.h" @@ -56,48 +56,41 @@ struct OS_TCB os_idle_TCB; * Local Functions *---------------------------------------------------------------------------*/ -OS_TID rt_get_TID (void) { +static OS_TID rt_get_TID (void) { U32 tid; - for (tid = 1; tid <= os_maxtaskrun; tid++) { - if (os_active_TCB[tid-1] == NULL) { + for (tid = 1U; tid <= os_maxtaskrun; tid++) { + if (os_active_TCB[tid-1U] == NULL) { return ((OS_TID)tid); } } - return (0); + return (0U); } -#if defined (__CC_ARM) && !defined (__MICROLIB) -/*--------------------------- __user_perthread_libspace ---------------------*/ -extern void *__libspace_start; - -void *__user_perthread_libspace (void) { - /* Provide a separate libspace for each task. */ - if (os_tsk.run == NULL) { - /* RTX not running yet. */ - return (&__libspace_start); - } - return (void *)(os_tsk.run->std_libspace); -} -#endif /*--------------------------- rt_init_context -------------------------------*/ -void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) { +static void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) { /* Initialize general part of the Task Control Block. */ - p_TCB->cb_type = TCB; - p_TCB->state = READY; - p_TCB->prio = priority; - p_TCB->p_lnk = NULL; - p_TCB->p_rlnk = NULL; - p_TCB->p_dlnk = NULL; - p_TCB->p_blnk = NULL; - p_TCB->delta_time = 0; - p_TCB->interval_time = 0; - p_TCB->events = 0; - p_TCB->waits = 0; - p_TCB->stack_frame = 0; + p_TCB->cb_type = TCB; + p_TCB->state = READY; + p_TCB->prio = priority; + p_TCB->prio_base = priority; + p_TCB->p_lnk = NULL; + p_TCB->p_rlnk = NULL; + p_TCB->p_dlnk = NULL; + p_TCB->p_blnk = NULL; + p_TCB->p_mlnk = NULL; + p_TCB->delta_time = 0U; + p_TCB->interval_time = 0U; + p_TCB->events = 0U; + p_TCB->waits = 0U; + p_TCB->stack_frame = 0U; + if (p_TCB->priv_stack == 0U) { + /* Allocate the memory space for the stack. */ + p_TCB->stack = rt_alloc_box (mp_stk); + } rt_init_stack (p_TCB, task_body); } @@ -148,7 +141,7 @@ void rt_block (U16 timeout, U8 block_state) { P_TCB next_TCB; if (timeout) { - if (timeout < 0xffff) { + if (timeout < 0xFFFFU) { rt_put_dly (os_tsk.run, timeout); } os_tsk.run->state = block_state; @@ -178,9 +171,9 @@ void rt_tsk_pass (void) { OS_TID rt_tsk_self (void) { /* Return own task identifier value. */ if (os_tsk.run == NULL) { - return (0); + return (0U); } - return (os_tsk.run->task_id); + return ((OS_TID)os_tsk.run->task_id); } @@ -190,9 +183,10 @@ OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) { /* Change execution priority of a task to "new_prio". */ P_TCB p_task; - if (task_id == 0) { + if (task_id == 0U) { /* Change execution priority of calling task. */ - os_tsk.run->prio = new_prio; + os_tsk.run->prio = new_prio; + os_tsk.run->prio_base = new_prio; run:if (rt_rdy_prio() > new_prio) { rt_put_prio (&os_rdy, os_tsk.run); os_tsk.run->state = READY; @@ -202,12 +196,13 @@ run:if (rt_rdy_prio() > new_prio) { } /* Find the task in the "os_active_TCB" array. */ - if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + if ((task_id > os_maxtaskrun) || (os_active_TCB[task_id-1U] == NULL)) { /* Task with "task_id" not found or not started. */ return (OS_R_NOK); } - p_task = os_active_TCB[task_id-1]; - p_task->prio = new_prio; + p_task = os_active_TCB[task_id-1U]; + p_task->prio = new_prio; + p_task->prio_base = new_prio; if (p_task == os_tsk.run) { goto run; } @@ -220,38 +215,146 @@ run:if (rt_rdy_prio() > new_prio) { return (OS_R_OK); } + +/*--------------------------- rt_tsk_create ---------------------------------*/ + +OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv) { + /* Start a new task declared with "task". */ + P_TCB task_context; + U32 i; + + /* Priority 0 is reserved for idle task! */ + if ((prio_stksz & 0xFFU) == 0U) { + prio_stksz += 1U; + } + task_context = rt_alloc_box (mp_tcb); + if (task_context == NULL) { + return (0U); + } + /* If "size != 0" use a private user provided stack. */ + task_context->stack = stk; + task_context->priv_stack = prio_stksz >> 8; + + /* Find a free entry in 'os_active_TCB' table. */ + i = rt_get_TID (); + if (i == 0U) { + return (0U); + } + task_context->task_id = (U8)i; + /* Pass parameter 'argv' to 'rt_init_context' */ + task_context->msg = argv; + /* For 'size == 0' system allocates the user stack from the memory pool. */ + rt_init_context (task_context, (U8)(prio_stksz & 0xFFU), task); + + os_active_TCB[i-1U] = task_context; + DBG_TASK_NOTIFY(task_context, __TRUE); + rt_dispatch (task_context); + return ((OS_TID)i); +} + + /*--------------------------- rt_tsk_delete ---------------------------------*/ OS_RESULT rt_tsk_delete (OS_TID task_id) { /* Terminate the task identified with "task_id". */ - P_TCB task_context; + P_TCB task_context; + P_TCB p_TCB; + P_MUCB p_MCB, p_MCB0; - if (task_id == 0 || task_id == os_tsk.run->task_id) { + if ((task_id == 0U) || (task_id == os_tsk.run->task_id)) { /* Terminate itself. */ os_tsk.run->state = INACTIVE; os_tsk.run->tsk_stack = rt_get_PSP (); rt_stk_check (); - os_active_TCB[os_tsk.run->task_id-1] = NULL; - + p_MCB = os_tsk.run->p_mlnk; + while (p_MCB) { + /* Release mutexes owned by this task */ + if (p_MCB->p_lnk) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val (p_TCB, 0U/*osOK*/); +#else + rt_ret_val (p_TCB, OS_R_MUT); +#endif + rt_rmv_dly (p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + /* A waiting task becomes the owner of this mutex. */ + p_MCB0 = p_MCB->p_mlnk; + p_MCB->level = 1U; + p_MCB->owner = p_TCB; + p_MCB->p_mlnk = p_TCB->p_mlnk; + p_TCB->p_mlnk = p_MCB; + p_MCB = p_MCB0; + } + else { + p_MCB0 = p_MCB->p_mlnk; + p_MCB->level = 0U; + p_MCB->owner = NULL; + p_MCB->p_mlnk = NULL; + p_MCB = p_MCB0; + } + } + os_active_TCB[os_tsk.run->task_id-1U] = NULL; + rt_free_box (mp_stk, os_tsk.run->stack); os_tsk.run->stack = NULL; DBG_TASK_NOTIFY(os_tsk.run, __FALSE); + rt_free_box (mp_tcb, os_tsk.run); os_tsk.run = NULL; rt_dispatch (NULL); /* The program should never come to this point. */ } else { /* Find the task in the "os_active_TCB" array. */ - if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) { + if ((task_id > os_maxtaskrun) || (os_active_TCB[task_id-1U] == NULL)) { /* Task with "task_id" not found or not started. */ return (OS_R_NOK); } - task_context = os_active_TCB[task_id-1]; + task_context = os_active_TCB[task_id-1U]; rt_rmv_list (task_context); rt_rmv_dly (task_context); - os_active_TCB[task_id-1] = NULL; - + p_MCB = task_context->p_mlnk; + while (p_MCB) { + /* Release mutexes owned by this task */ + if (p_MCB->p_lnk) { + /* A task is waiting for mutex. */ + p_TCB = rt_get_first ((P_XCB)p_MCB); +#ifdef __CMSIS_RTOS + rt_ret_val (p_TCB, 0U/*osOK*/); +#else + rt_ret_val (p_TCB, OS_R_MUT); +#endif + rt_rmv_dly (p_TCB); + p_TCB->state = READY; + rt_put_prio (&os_rdy, p_TCB); + /* A waiting task becomes the owner of this mutex. */ + p_MCB0 = p_MCB->p_mlnk; + p_MCB->level = 1U; + p_MCB->owner = p_TCB; + p_MCB->p_mlnk = p_TCB->p_mlnk; + p_TCB->p_mlnk = p_MCB; + p_MCB = p_MCB0; + } + else { + p_MCB0 = p_MCB->p_mlnk; + p_MCB->level = 0U; + p_MCB->owner = NULL; + p_MCB->p_mlnk = NULL; + p_MCB = p_MCB0; + } + } + os_active_TCB[task_id-1U] = NULL; + rt_free_box (mp_stk, task_context->stack); task_context->stack = NULL; DBG_TASK_NOTIFY(task_context, __FALSE); + rt_free_box (mp_tcb, task_context); + if (rt_rdy_prio() > os_tsk.run->prio) { + /* Ready task has higher priority than running task. */ + os_tsk.run->state = READY; + rt_put_prio (&os_rdy, os_tsk.run); + rt_dispatch (NULL); + } } return (OS_R_OK); } @@ -270,15 +373,17 @@ void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) { DBG_INIT(); /* Initialize dynamic memory and task TCB pointers to NULL. */ - for (i = 0; i < os_maxtaskrun; i++) { + for (i = 0U; i < os_maxtaskrun; i++) { os_active_TCB[i] = NULL; } + rt_init_box (mp_tcb, (U32)mp_tcb_size, sizeof(struct OS_TCB)); + rt_init_box (mp_stk, mp_stk_size, BOX_ALIGN_8 | (U16)(os_stackinfo)); + rt_init_box ((U32 *)m_tmr, (U32)mp_tmr_size, sizeof(struct OS_TMR)); /* Set up TCB of idle demon */ - os_idle_TCB.task_id = 255; - os_idle_TCB.priv_stack = idle_task_stack_size; - os_idle_TCB.stack = idle_task_stack; - rt_init_context (&os_idle_TCB, 0, os_idle_demon); + os_idle_TCB.task_id = 255U; + os_idle_TCB.priv_stack = 0U; + rt_init_context (&os_idle_TCB, 0U, os_idle_demon); /* Set up ready list: initially empty */ os_rdy.cb_type = HCB; @@ -287,31 +392,31 @@ void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) { os_dly.cb_type = HCB; os_dly.p_dlnk = NULL; os_dly.p_blnk = NULL; - os_dly.delta_time = 0; + os_dly.delta_time = 0U; - /* Fix SP and systemvariables to assume idle task is running */ + /* Fix SP and system variables to assume idle task is running */ /* Transform main program into idle task by assuming idle TCB */ #ifndef __CMSIS_RTOS - rt_set_PSP (os_idle_TCB.tsk_stack+32); + rt_set_PSP (os_idle_TCB.tsk_stack+32U); #endif os_tsk.run = &os_idle_TCB; os_tsk.run->state = RUNNING; /* Initialize ps queue */ - os_psq->first = 0; - os_psq->last = 0; + os_psq->first = 0U; + os_psq->last = 0U; os_psq->size = os_fifo_size; rt_init_robin (); - /* Intitialize SVC and PendSV */ +#ifndef __CMSIS_RTOS + /* Initialize SVC and PendSV */ rt_svc_init (); -#ifndef __CMSIS_RTOS - /* Intitialize and start system clock timer */ + /* Initialize and start system clock timer */ os_tick_irqn = os_tick_init (); if (os_tick_irqn >= 0) { - OS_X_INIT(os_tick_irqn); + OS_X_INIT((U32)os_tick_irqn); } /* Start up first user task before entering the endless loop */ @@ -326,10 +431,13 @@ void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) { void rt_sys_start (void) { /* Start system */ - /* Intitialize and start system clock timer */ + /* Initialize SVC and PendSV */ + rt_svc_init (); + + /* Initialize and start system clock timer */ os_tick_irqn = os_tick_init (); if (os_tick_irqn >= 0) { - OS_X_INIT(os_tick_irqn); + OS_X_INIT((U32)os_tick_irqn); } } #endif diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Task.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Task.h index 9d3727b5a6..2fe14dccf9 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Task.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Task.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_TASK.H * Purpose: Task functions and system start up. - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,29 +33,28 @@ *---------------------------------------------------------------------------*/ /* Definitions */ -#define __CMSIS_RTOS 1 /* Values for 'state' */ -#define INACTIVE 0 -#define READY 1 -#define RUNNING 2 -#define WAIT_DLY 3 -#define WAIT_ITV 4 -#define WAIT_OR 5 -#define WAIT_AND 6 -#define WAIT_SEM 7 -#define WAIT_MBX 8 -#define WAIT_MUT 9 +#define INACTIVE 0U +#define READY 1U +#define RUNNING 2U +#define WAIT_DLY 3U +#define WAIT_ITV 4U +#define WAIT_OR 5U +#define WAIT_AND 6U +#define WAIT_SEM 7U +#define WAIT_MBX 8U +#define WAIT_MUT 9U /* Return codes */ -#define OS_R_TMO 0x01 -#define OS_R_EVT 0x02 -#define OS_R_SEM 0x03 -#define OS_R_MBX 0x04 -#define OS_R_MUT 0x05 +#define OS_R_TMO 0x01U +#define OS_R_EVT 0x02U +#define OS_R_SEM 0x03U +#define OS_R_MBX 0x04U +#define OS_R_MUT 0x05U -#define OS_R_OK 0x00 -#define OS_R_NOK 0xff +#define OS_R_OK 0x00U +#define OS_R_NOK 0xFFU /* Variables */ extern struct OS_TSK os_tsk; @@ -68,6 +67,15 @@ extern void rt_block (U16 timeout, U8 block_state); extern void rt_tsk_pass (void); extern OS_TID rt_tsk_self (void); extern OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio); +extern OS_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv); extern OS_RESULT rt_tsk_delete (OS_TID task_id); +#ifdef __CMSIS_RTOS extern void rt_sys_init (void); extern void rt_sys_start (void); +#else +extern void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk); +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Time.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Time.c index b02ccebbad..abbd4acf58 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Time.c +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Time.c @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_TIME.C * Purpose: Delay and interval wait functions - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,7 @@ *---------------------------------------------------------------------------*/ #include "rt_TypeDef.h" -#include "RTX_Conf.h" +#include "RTX_Config.h" #include "rt_Task.h" #include "rt_Time.h" @@ -83,7 +83,7 @@ void rt_itv_wait (void) { delta = os_tsk.run->delta_time - (U16)os_time; os_tsk.run->delta_time += os_tsk.run->interval_time; - if ((delta & 0x8000) == 0) { + if ((delta & 0x8000U) == 0U) { rt_block (delta, WAIT_ITV); } } @@ -91,4 +91,3 @@ void rt_itv_wait (void) { /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/ - diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Time.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Time.h index 27706373d5..8e952480eb 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Time.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Time.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_TIME.H * Purpose: Delay and interval wait functions definitions - * Rev.: V4.60 + * Rev.: V4.70 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Timer.c b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Timer.c new file mode 100644 index 0000000000..29b398bdf9 --- /dev/null +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Timer.c @@ -0,0 +1,134 @@ +/*---------------------------------------------------------------------------- + * CMSIS-RTOS - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIMER.C + * Purpose: User timer functions + * Rev.: V4.70 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +#include "rt_TypeDef.h" +#include "RTX_Config.h" +#include "rt_Timer.h" +#include "rt_MemBox.h" + +#ifndef __CMSIS_RTOS + + +/*---------------------------------------------------------------------------- + * Global Variables + *---------------------------------------------------------------------------*/ + +/* User Timer list pointer */ +struct OS_XTMR os_tmr; + +/*---------------------------------------------------------------------------- + * Functions + *---------------------------------------------------------------------------*/ + +/*--------------------------- rt_tmr_tick -----------------------------------*/ + +void rt_tmr_tick (void) { + /* Decrement delta count of timer list head. Timers having the value of */ + /* zero are removed from the list and the callback function is called. */ + P_TMR p; + + if (os_tmr.next == NULL) { + return; + } + os_tmr.tcnt--; + while ((os_tmr.tcnt == 0U) && ((p = os_tmr.next) != NULL)) { + /* Call a user provided function to handle an elapsed timer */ + os_tmr_call (p->info); + os_tmr.tcnt = p->tcnt; + os_tmr.next = p->next; + rt_free_box ((U32 *)m_tmr, p); + } +} + +/*--------------------------- rt_tmr_create ---------------------------------*/ + +OS_ID rt_tmr_create (U16 tcnt, U16 info) { + /* Create an user timer and put it into the chained timer list using */ + /* a timeout count value of "tcnt". User parameter "info" is used as a */ + /* parameter for the user provided callback function "os_tmr_call ()". */ + P_TMR p_tmr, p; + U32 delta,itcnt = tcnt; + + if ((tcnt == 0U) || (m_tmr == NULL)) { + return (NULL); + } + p_tmr = rt_alloc_box ((U32 *)m_tmr); + if (!p_tmr) { + return (NULL); + } + p_tmr->info = info; + p = (P_TMR)&os_tmr; + delta = p->tcnt; + while ((delta < itcnt) && (p->next != NULL)) { + p = p->next; + delta += p->tcnt; + } + /* Right place found, insert timer into the list */ + p_tmr->next = p->next; + p_tmr->tcnt = (U16)(delta - itcnt); + p->next = p_tmr; + p->tcnt -= p_tmr->tcnt; + return (p_tmr); +} + +/*--------------------------- rt_tmr_kill -----------------------------------*/ + +OS_ID rt_tmr_kill (OS_ID timer) { + /* Remove user timer from the chained timer list. */ + P_TMR p, p_tmr; + + p_tmr = (P_TMR)timer; + p = (P_TMR)&os_tmr; + /* Search timer list for requested timer */ + while (p->next != p_tmr) { + if (p->next == NULL) { + /* Failed, "timer" is not in the timer list */ + return (p_tmr); + } + p = p->next; + } + /* Timer was found, remove it from the list */ + p->next = p_tmr->next; + p->tcnt += p_tmr->tcnt; + rt_free_box ((U32 *)m_tmr, p_tmr); + /* Timer killed */ + return (NULL); +} + + +#endif + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Timer.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Timer.h new file mode 100644 index 0000000000..3db3e0a67f --- /dev/null +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_Timer.h @@ -0,0 +1,45 @@ +/*---------------------------------------------------------------------------- + * CMSIS-RTOS - RTX + *---------------------------------------------------------------------------- + * Name: RT_TIMER.H + * Purpose: User timer functions + * Rev.: V4.70 + *---------------------------------------------------------------------------- + * + * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH + * All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *---------------------------------------------------------------------------*/ + +/* Variables */ +extern struct OS_XTMR os_tmr; + +/* Functions */ +extern void rt_tmr_tick (void); +extern OS_ID rt_tmr_create (U16 tcnt, U16 info); +extern OS_ID rt_tmr_kill (OS_ID timer); + +/*---------------------------------------------------------------------------- + * end of file + *---------------------------------------------------------------------------*/ diff --git a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h index 27416c502c..86a84d2750 100644 --- a/libraries/rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h +++ b/libraries/rtos/rtx/TARGET_CORTEX_M/rt_TypeDef.h @@ -1,12 +1,12 @@ /*---------------------------------------------------------------------------- - * RL-ARM - RTX + * CMSIS-RTOS - RTX *---------------------------------------------------------------------------- * Name: RT_TYPEDEF.H * Purpose: Type Definitions - * Rev.: V4.60 + * Rev.: V4.79 *---------------------------------------------------------------------------- * - * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH + * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -34,14 +34,54 @@ #ifndef RT_TYPE_DEF_H #define RT_TYPE_DEF_H -#include "os_tcb.h" +/* Types */ +typedef char S8; +typedef unsigned char U8; +typedef short S16; +typedef unsigned short U16; +typedef int S32; +typedef unsigned int U32; +typedef long long S64; +typedef unsigned long long U64; +typedef unsigned char BIT; +typedef unsigned int BOOL; +typedef void (*FUNCP)(void); typedef U32 OS_TID; typedef void *OS_ID; typedef U32 OS_RESULT; -#define TCB_STACKF 32 /* 'stack_frame' offset */ -#define TCB_TSTACK 40 /* 'tsk_stack' offset */ +typedef struct OS_TCB { + /* General part: identical for all implementations. */ + U8 cb_type; /* Control Block Type */ + U8 state; /* Task state */ + U8 prio; /* Execution priority */ + U8 task_id; /* Task ID value for optimized TCB access */ + struct OS_TCB *p_lnk; /* Link pointer for ready/sem. wait list */ + struct OS_TCB *p_rlnk; /* Link pointer for sem./mbx lst backwards */ + struct OS_TCB *p_dlnk; /* Link pointer for delay list */ + struct OS_TCB *p_blnk; /* Link pointer for delay list backwards */ + U16 delta_time; /* Time until time out */ + U16 interval_time; /* Time interval for periodic waits */ + U16 events; /* Event flags */ + U16 waits; /* Wait flags */ + void **msg; /* Direct message passing when task waits */ + struct OS_MUCB *p_mlnk; /* Link pointer for mutex owner list */ + U8 prio_base; /* Base priority */ + + /* Hardware dependant part: specific for CM processor */ + U8 stack_frame; /* Stack frame: 0=Basic, 1=Extended, */ + U16 reserved; /* Two reserved bytes for alignment */ + /* (2=VFP/D16 stacked, 4=NEON/D32 stacked) */ + U32 priv_stack; /* Private stack size, 0= system assigned */ + U32 tsk_stack; /* Current task Stack pointer (R13) */ + U32 *stack; /* Pointer to Task Stack memory block */ + + /* Task entry point used for uVision debugger */ + FUNCP ptask; /* Task entry address */ +} *P_TCB; +#define TCB_STACKF 37 /* 'stack_frame' offset */ +#define TCB_TSTACK 44 /* 'tsk_stack' offset */ typedef struct OS_PSFE { /* Post Service Fifo Entry */ void *id; /* Object Identification */ @@ -58,7 +98,7 @@ typedef struct OS_PSQ { /* Post Service Queue */ typedef struct OS_TSK { P_TCB run; /* Current running task */ - P_TCB new_tsk; /* Scheduled task to run */ + P_TCB new_tsk; /* Scheduled task to run */ } *P_TSK; typedef struct OS_ROBIN { /* Round Robin Control */ @@ -97,10 +137,10 @@ typedef struct OS_SCB { typedef struct OS_MUCB { U8 cb_type; /* Control Block Type */ - U8 prio; /* Owner task default priority */ U16 level; /* Call nesting level */ struct OS_TCB *p_lnk; /* Chain of tasks waiting for mutex */ struct OS_TCB *owner; /* Mutex owner task */ + struct OS_MUCB *p_mlnk; /* Chain of mutexes by owner task */ } *P_MUCB; typedef struct OS_XTMR { @@ -121,8 +161,8 @@ typedef struct OS_BM { } *P_BM; /* Definitions */ -#define __TRUE 1 -#define __FALSE 0 +#define __TRUE 1U +#define __FALSE 0U #define NULL ((void *) 0) #endif diff --git a/workspace_tools/toolchains/__init__.py b/workspace_tools/toolchains/__init__.py index d122fb72d1..a7c405e133 100644 --- a/workspace_tools/toolchains/__init__.py +++ b/workspace_tools/toolchains/__init__.py @@ -166,14 +166,14 @@ class mbedToolchain: VERBOSE = True CORTEX_SYMBOLS = { - "Cortex-M0" : ["__CORTEX_M0", "ARM_MATH_CM0"], - "Cortex-M0+": ["__CORTEX_M0PLUS", "ARM_MATH_CM0PLUS"], - "Cortex-M1" : ["__CORTEX_M3", "ARM_MATH_CM1"], - "Cortex-M3" : ["__CORTEX_M3", "ARM_MATH_CM3"], - "Cortex-M4" : ["__CORTEX_M4", "ARM_MATH_CM4"], - "Cortex-M4F" : ["__CORTEX_M4", "ARM_MATH_CM4", "__FPU_PRESENT=1"], - "Cortex-M7" : ["__CORTEX_M7", "ARM_MATH_CM7"], - "Cortex-M7F" : ["__CORTEX_M7", "ARM_MATH_CM7", "__FPU_PRESENT=1"], + "Cortex-M0" : ["__CORTEX_M0", "ARM_MATH_CM0", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], + "Cortex-M0+": ["__CORTEX_M0PLUS", "ARM_MATH_CM0PLUS", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], + "Cortex-M1" : ["__CORTEX_M3", "ARM_MATH_CM1", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], + "Cortex-M3" : ["__CORTEX_M3", "ARM_MATH_CM3", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], + "Cortex-M4" : ["__CORTEX_M4", "ARM_MATH_CM4", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], + "Cortex-M4F" : ["__CORTEX_M4", "ARM_MATH_CM4", "__FPU_PRESENT=1", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], + "Cortex-M7" : ["__CORTEX_M7", "ARM_MATH_CM7", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], + "Cortex-M7F" : ["__CORTEX_M7", "ARM_MATH_CM7", "__FPU_PRESENT=1", "__CMSIS_RTOS", "__MBED_CMSIS_RTOS_CM"], "Cortex-A9" : ["__CORTEX_A9", "ARM_MATH_CA9", "__FPU_PRESENT", "__CMSIS_RTOS", "__EVAL", "__MBED_CMSIS_RTOS_CA9"], }