Official mbed Real Time Operating System based on the RTX implementation of the CMSIS-RTOS API open standard.
Dependents: denki-yohou_b TestY201 Network-RTOS NTPClient_HelloWorld ... more
Deprecated
This is the mbed 2 rtos library. mbed OS 5 integrates the mbed library with mbed-rtos. With this, we have provided thread safety for all mbed APIs. If you'd like to learn about using mbed OS 5, please see the docs.
Diff: rtx/TARGET_CORTEX_M/rt_CMSIS.c
- Revision:
- 112:53ace74b190c
- Parent:
- 101:3d9d2b8b8f17
- Child:
- 114:031a41d65add
--- a/rtx/TARGET_CORTEX_M/rt_CMSIS.c Tue May 03 00:15:52 2016 +0100 +++ b/rtx/TARGET_CORTEX_M/rt_CMSIS.c Thu May 05 20:45:13 2016 +0100 @@ -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 @@ 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 @@ 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 @@ #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 @@ #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 @@ ); #else #define SVC_Call(f) \ - __asm volatile \ + __asm volatile \ ( \ "ldr r12,="#f"\n\t" \ "svc 0" \ @@ -227,6 +237,13 @@ 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 @@ 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 @@ :: "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 @@ 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$$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 @@ /// 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 @@ 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; + + if (os_initialized == 0U) { - rt_sys_init(); // RTX System Initialization - os_tsk.run->prio = 255; // Highest priority + // 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 @@ /// 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 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ /// 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 @@ /// 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 @@ 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 @@ /// 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 @@ 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 @@ // ==== 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 @@ 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 @@ } // 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 @@ // 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 @@ return NULL; } + pt->next = NULL; pt->state = osTimerStopped; pt->type = (uint8_t)type; pt->arg = argument; @@ -875,10 +1038,13 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } } +/// 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 @@ /// 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 @@ // 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 sig; ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + if (ptcb == NULL) { + return (int32_t)0x80000000U; + } - sig = ptcb->events; // Previous signal flags + if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) { + return (int32_t)0x80000000U; + } - rt_evt_set(signals, ptcb->task_id); // Set event flags + sig = (int32_t)ptcb->events; // Previous signal flags + + rt_evt_set((uint16_t)signals, ptcb->task_id); // Set event flags return sig; } @@ -1069,48 +1278,42 @@ int32_t sig; ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer - if (ptcb == NULL) return 0x80000000; - - if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + if (ptcb == NULL) { + return (int32_t)0x80000000U; + } - sig = ptcb->events; // Previous signal flags + if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) { + return (int32_t)0x80000000U; + } - rt_evt_clr(signals, ptcb->task_id); // Clear event flags + sig = (int32_t)ptcb->events; // Previous signal 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 @@ // 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 (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000; + if (ptcb == NULL) { + return (int32_t)0x80000000U; + } - sig = ptcb->events; // Previous signal flags + if ((uint32_t)signals & (0xFFFFFFFFU << osFeature_Signals)) { + return (int32_t)0x80000000U; + } - isr_evt_set(signals, ptcb->task_id); // Set event flags + sig = (int32_t)ptcb->events; // Previous signal flags + + isr_evt_set((uint16_t)signals, ptcb->task_id);// Set event flags return sig; } @@ -1142,8 +1349,8 @@ /// 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 @@ /// 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 @@ // ==== 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 @@ return NULL; } - if (((P_MUCB)mut)->cb_type != 0) { + if (((P_MUCB)mut)->cb_type != 0U) { sysThreadError(osErrorParameter); return NULL; } @@ -1214,14 +1417,18 @@ 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 @@ 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 @@ 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 @@ // 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 @@ /// 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 @@ // 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 @@ return NULL; } - if (((P_SCB)sem)->cb_type != 0) { + if (((P_SCB)sem)->cb_type != 0U) { sysThreadError(osErrorParameter); return NULL; } @@ -1326,8 +1551,8 @@ return NULL; } - rt_sem_init(sem, count); // Initialize Semaphore - + rt_sem_init(sem, (uint16_t)count); // Initialize Semaphore + return sem; } @@ -1337,15 +1562,19 @@ 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 @@ 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; + } + rt_sem_send(sem); // Release Semaphore return osOK; @@ -1369,9 +1604,13 @@ 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 @@ // 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 @@ // 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 @@ /// 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 @@ /// 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 @@ 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 @@ 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 @@ // 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 @@ /// 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 @@ // ==== 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 @@ 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 @@ } 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 @@ // 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 @@ } /// 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 @@ } 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 @@ // 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 @@ /// 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 @@ /// 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 @@ // ==== 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 @@ 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); + _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)); - + 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 ((pool == NULL) || (pmcb == NULL)) { + return NULL; + } - if (isr && (millisec != 0)) return NULL; + if ((isr != 0U) && (millisec != 0U)) { + return NULL; + } mem = rt_alloc_box(pool); - if (clr) { - rt_clr_box(pool, mem); - } - if ((mem == NULL) && (millisec != 0)) { + 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 @@ 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 @@ // 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 @@ /// 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 @@ 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); +}