Official mbed Real Time Operating System based on the RTX implementation of the CMSIS-RTOS API open standard.
Fork of mbed-rtos by
Diff: rtx/TARGET_CORTEX_A/rt_CMSIS.c
- Revision:
- 92:bc9729798a19
- Parent:
- 85:ef0a22cdf839
--- 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);
+}
