Rtos code cntains bug possible incompatability with I2C
Fork of mbed-rtos by
Diff: rtx/TARGET_CORTEX_A/rt_CMSIS.c
- Revision:
- 92:bc9729798a19
- Parent:
- 85:ef0a22cdf839
- Child:
- 115:8a283ff636b9
- Child:
- 118:4c105b8d7cae
--- a/rtx/TARGET_CORTEX_A/rt_CMSIS.c Wed Sep 16 11:15:38 2015 +0100 +++ b/rtx/TARGET_CORTEX_A/rt_CMSIS.c Fri Sep 25 13:30:34 2015 +0100 @@ -3,10 +3,10 @@ *---------------------------------------------------------------------------- * Name: rt_CMSIS.c * Purpose: CMSIS RTOS API - * Rev.: V4.60 + * Rev.: V4.74 *---------------------------------------------------------------------------- * - * 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: @@ -100,6 +100,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); \ @@ -280,6 +288,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) { \ @@ -353,6 +368,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); \ @@ -539,6 +562,7 @@ 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) static void sysThreadError (osStatus status); osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument); @@ -577,6 +601,7 @@ sysThreadError(osOK); os_initialized = 1; + os_running = 0; return osOK; } @@ -586,8 +611,10 @@ if (os_running) return osOK; - rt_tsk_prio(0, 0); // Lowest priority - __set_PSP(os_tsk.run->tsk_stack + 8*4); // New context + rt_tsk_prio(0, os_tsk.run->prio_base); // Restore priority + if (os_tsk.run->task_id == 0xFF) { // Idle Thread + __set_PSP(os_tsk.run->tsk_stack + 8*4); // Setup PSP + } os_tsk.run = NULL; // Force context switch rt_sys_start(); @@ -602,6 +629,22 @@ return 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 + 1) * (os_time + 1); + } else { + tick += (os_trv + 1) * os_time; + } + + return tick; +} + // Kernel Control Public API /// Initialize the RTOS Kernel for creating objects @@ -642,6 +685,12 @@ } } +/// Get the RTOS kernel system timer counter +uint32_t osKernelSysTick (void) { + if (__exceptional_mode()) return 0; // Not allowed in ISR + return __svcKernelSysTick(); +} + // ==== Thread Management ==== @@ -1047,6 +1096,7 @@ return NULL; } + pt->next = NULL; pt->state = osTimerStopped; pt->type = (uint8_t)type; pt->arg = argument; @@ -1176,6 +1226,30 @@ } } +/// Get user timers wake-up time +uint32_t sysUserTimerWakeupTime (void) { + + if (os_timer_head) { + return os_timer_head->tcnt; + } + return 0xFFFF; +} + +/// Update user timers on resume +void sysUserTimerUpdate (uint32_t sleep_time) { + + while (os_timer_head && sleep_time) { + if (sleep_time >= os_timer_head->tcnt) { + sleep_time -= os_timer_head->tcnt; + os_timer_head->tcnt = 1; + sysTimerTick(); + } else { + os_timer_head->tcnt -= sleep_time; + break; + } + } +} + // Timer Management Public API @@ -1237,7 +1311,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 @@ -1276,16 +1349,6 @@ 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; @@ -1361,12 +1424,6 @@ return __svcSignalClear(thread_id, signals); } -/// Get Signal Flags status of an active thread -int32_t osSignalGet (osThreadId thread_id) { - if (__exceptional_mode()) 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; @@ -1960,7 +2017,6 @@ rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4)); - return queue_def->pool; } @@ -2020,7 +2076,7 @@ if (res != 0) return osErrorValue; - if (pmcb->state == 3) { + if ((pmcb->p_lnk != NULL) && (pmcb->state == 3)) { // Task is waiting to allocate a message if (isr) { rt_psq_enq (pmcb, (U32)pool); @@ -2029,9 +2085,6 @@ 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); @@ -2111,3 +2164,23 @@ #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); +}