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.

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Fri Sep 25 13:30:34 2015 +0100
Parent:
91:9d001ed5feec
Child:
93:795765880f57
Commit message:
Synchronized with git revision e8c24ba90dd5507bdb7c1b46dd3aba8cfabb762b

Full URL: https://github.com/mbedmicro/mbed/commit/e8c24ba90dd5507bdb7c1b46dd3aba8cfabb762b/

RZ_A1H - Modify to support NEON for RTOS.

Changed in this revision

rtos/Mutex.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/HAL_CA.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/RTX_CM_lib.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/RTX_Config.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/HAL_CA9.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/SVC_Table.S Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/HAL_CA9.S Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/SVC_Table.S Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/cmsis_os.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_CMSIS.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Event.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Event.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_HAL_CA.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_HAL_CM.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_List.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_List.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Mailbox.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Mailbox.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_MemBox.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_MemBox.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Memory.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Memory.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Mutex.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Mutex.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Robin.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Robin.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Semaphore.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Semaphore.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_System.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_System.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Task.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Task.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Time.c Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Time.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_Timer.h Show annotated file Show diff for this revision Revisions of this file
rtx/TARGET_CORTEX_A/rt_TypeDef.h Show annotated file Show diff for this revision Revisions of this file
--- a/rtos/Mutex.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtos/Mutex.h	Fri Sep 25 13:30:34 2015 +0100
@@ -57,8 +57,12 @@
     osMutexId _osMutexId;
     osMutexDef_t _osMutexDef;
 #ifdef CMSIS_OS_RTX
+#ifdef __MBED_CMSIS_RTOS_CA9
+    int32_t _mutex_data[4];
+#else
     int32_t _mutex_data[3];
 #endif
+#endif
 };
 
 }
--- a/rtx/TARGET_CORTEX_A/HAL_CA.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/HAL_CA.c	Fri Sep 25 13:30:34 2015 +0100
@@ -91,18 +91,16 @@
 
 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 (p_TCB->stack_frame & 0x2) {
-    /* Extended Stack Frame: S0-31,FPSCR,Reserved,R4-R11,R0-R3,R12,LR,PC,xPSR */
-    return (U32 *)(p_TCB->tsk_stack + 8*4 + 34*4);
+  if (p_TCB->stack_frame & 0x4) {
+    /* NEON/D32 Stack Frame: D0-31,FPSCR,Reserved,R4-R11,R0-R3,R12,LR,PC,xPSR */
+    return (U32 *)(p_TCB->tsk_stack + 8*4 + 2*4 + 32*8);
+  } else if (p_TCB->stack_frame & 0x2) {
+    /* VFP/D16 Stack Frame: D0-D15/S0-31,FPSCR,Reserved,R4-R11,R0-R3,R12,LR,PC,xPSR */
+    return (U32 *)(p_TCB->tsk_stack + 8*4 + 2*4 + 32*4);
   } else {
     /* Basic Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */
     return (U32 *)(p_TCB->tsk_stack + 8*4);
   }
-#else
-  /* Stack Frame: R4-R11,R0-R3,R12,LR,PC,xPSR */
-  return (U32 *)(p_TCB->tsk_stack + 8*4);
-#endif
 }
 
 void rt_ret_val (P_TCB p_TCB, U32 v0) {
--- a/rtx/TARGET_CORTEX_A/RTX_CM_lib.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/RTX_CM_lib.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RTX_CM_LIB.H
  *      Purpose: RTX Kernel System Configuration
- *      Rev.:    V4.60
+ *      Rev.:    V4.73
  *----------------------------------------------------------------------------
  *
- * 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:
@@ -50,14 +50,14 @@
 #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()
@@ -104,10 +104,15 @@
 uint32_t const os_stackinfo  = (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;
 
@@ -258,7 +263,6 @@
 osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE };
 #endif
 
-
 #if defined (__CC_ARM)
 
 #ifdef __MICROLIB
--- a/rtx/TARGET_CORTEX_A/RTX_Config.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/RTX_Config.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RTX_CONFIG.H
  *      Purpose: Exported functions of RTX_Config.c
- *      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:
@@ -67,6 +67,8 @@
 /* Functions */
 extern void os_idle_demon   (void);
 extern int  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);
--- a/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/HAL_CA9.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/HAL_CA9.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    HAL_CA9.c
  *      Purpose: Hardware Abstraction Layer for Cortex-A9
- *      Rev.:    3 Sept 2013
+ *      Rev.:    8 April 2015
  *----------------------------------------------------------------------------
  *
- * Copyright (c) 2012 - 2013 ARM Limited
+ * Copyright (c) 2012 - 2015 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:
@@ -114,6 +114,7 @@
         IMPORT  SVC_Table
         IMPORT  rt_stk_check
         IMPORT  FPUEnable
+        IMPORT  scheduler_suspended    ; flag set by rt_suspend, cleared by rt_resume, read by SVC_Handler
 
 Mode_SVC        EQU     0x13
 
@@ -159,7 +160,7 @@
         /* Here we will be in SVC mode (even if coming in from PendSV_Handler or OS_Tick_Handler) */
 Sys_Switch
         LDR     LR,=__cpp(&os_tsk)
-        LDM     LR,{R4,LR}              ; os_tsk.run, os_tsk.new
+        LDM     LR,{R4,LR}              ; os_tsk.run, os_tsk.new_tsk
         CMP     R4,LR
         BNE     switching
 
@@ -170,7 +171,13 @@
         PUSH    {R12, LR}               ; Store stack adjustment and dummy LR to SVC stack
 
         CPSID   i
+        ; Do not unlock scheduler if it has just been suspended by rt_suspend()
+        LDR     R1,=scheduler_suspended
+        LDRB    R0, [R1]
+        CMP     R0, #1
+        BEQ     dont_unlock
         BLX     rt_tsk_unlock
+dont_unlock
 
         POP     {R12, LR}               ; Get stack adjustment & discard dummy LR
         ADD     SP, SP, R12             ; Unadjust stack
@@ -188,7 +195,7 @@
 
         PUSH    {R8-R11} //R4 and LR already stacked
         MOV     R10,R4                  ; Preserve os_tsk.run
-        MOV     R11,LR                  ; Preserve os_tsk.new
+        MOV     R11,LR                  ; Preserve os_tsk.new_tsk
 
         ADD     R8,SP,#16               ; Unstack R4,LR
         LDMIA   R8,{R4,LR}
@@ -204,21 +211,22 @@
         SUB     R8,R8,#4                ; No writeback for store of User LR
         STMDB   R8!,{R0-R3,R12}         ; User R0-R3,R12
         MOV     R3,R10                  ; os_tsk.run
-        MOV     LR,R11                  ; os_tsk.new
+        MOV     LR,R11                  ; os_tsk.new_tsk
         POP     {R9-R12}
         ADD     SP,SP,#12               ; Fix up SP for unstack of R4, LR & SPSR
         STMDB   R8!,{R4-R7,R9-R12}      ; User R4-R11
 
-        //If applicable, stack VFP state
+        //If applicable, stack VFP/NEON state
         MRC     p15,0,R1,c1,c0,2        ; VFP/NEON access enabled? (CPACR)
         AND     R2,R1,#0x00F00000
         CMP     R2,#0x00F00000
         BNE     no_outgoing_vfp
         VMRS    R2,FPSCR
         STMDB   R8!,{R2,R4}             ; Push FPSCR, maintain 8-byte alignment
-        VSTMDB  R8!,{S0-S31}
-        LDRB    R2,[R3,#TCB_STACKF]     ; Record in TCB that VFP state is stacked
-        ORR     R2,#2
+        VSTMDB  R8!,{D0-D15}
+        VSTMDB  R8!,{D16-D31}
+        LDRB    R2,[R3,#TCB_STACKF]     ; Record in TCB that NEON/D32 state is stacked
+        ORR     R2,#4
         STRB    R2,[R3,#TCB_STACKF]
 
 no_outgoing_vfp
@@ -238,8 +246,8 @@
 
         MOV     LR,R4
 
-SVC_Next  //R4 == os_tsk.run, LR == os_tsk.new, R0-R3, R5-R12 corruptible
-        LDR     R1,=__cpp(&os_tsk)      ; os_tsk.run = os_tsk.new
+SVC_Next  //R4 == os_tsk.run, LR == os_tsk.new_tsk, R0-R3, R5-R12 corruptible
+        LDR     R1,=__cpp(&os_tsk)      ; os_tsk.run = os_tsk.new_tsk
         STR     LR,[R1]
         LDRB    R1,[LR,#TCB_TID]        ; os_tsk.run->task_id
         LSL     R1,#8                   ; Store PROCID
@@ -247,16 +255,17 @@
 
         LDR     R0,[LR,#TCB_TSTACK]     ; os_tsk.run->tsk_stack
 
-        //Does incoming task have VFP state in stack?
+        //Does incoming task have VFP/NEON state in stack?
         LDRB    R3,[LR,#TCB_STACKF]
-        TST     R3,#0x2
+        ANDS    R3, R3, #0x6
         MRC     p15,0,R1,c1,c0,2        ; Read CPACR
-        ANDEQ   R1,R1,#0xFF0FFFFF       ; Disable VFP access if incoming task does not have stacked VFP state
-        ORRNE   R1,R1,#0x00F00000       ; Enable VFP access if incoming task does have stacked VFP state
+        ANDEQ   R1,R1,#0xFF0FFFFF       ; Disable VFP/NEON access if incoming task does not have stacked VFP/NEON state
+        ORRNE   R1,R1,#0x00F00000       ; Enable VFP/NEON access if incoming task does have stacked VFP/NEON state
         MCR     p15,0,R1,c1,c0,2        ; Write CPACR
         BEQ     no_incoming_vfp
-        ISB                             ; We only need the sync if we enabled, otherwise we will context switch before next VFP instruction anyway
-        VLDMIA  R0!,{S0-S31}
+        ISB                             ; We only need the sync if we enabled, otherwise we will context switch before next VFP/NEON instruction anyway
+        VLDMIA  R0!,{D16-D31}
+        VLDMIA  R0!,{D0-D15}
         LDR     R2,[R0]
         VMSR    FPSCR,R2
         ADD     R0,R0,#8
@@ -343,7 +352,8 @@
     ARM
 
     IMPORT  rt_tsk_lock
-    IMPORT  IRQNestLevel
+    IMPORT  IRQNestLevel                ; Flag indicates whether inside an ISR, and the depth of nesting.  0 = not in ISR.
+    IMPORT  seen_id0_active             ; Flag used to workaround GIC 390 errata 733075 - set in startup_Renesas_RZ_A1.s
 
     ADD     SP,SP,#8 //fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment)
 
@@ -355,6 +365,11 @@
     LDR     R1, [R1, #0]
     STR     R0, [R1, #0x10]
 
+    ; If it was interrupt ID0, clear the seen flag, otherwise return as normal
+    CMP     R0, #0
+    LDREQ   R1, =seen_id0_active
+    STRBEQ  R0, [R1]                    ; Clear the seen flag, using R0 (which is 0), to save loading another register
+
     LDR     R0, =IRQNestLevel           ; Get address of nesting counter
     LDR     R1, [R0]
     SUB     R1, R1, #1                  ; Decrement nesting counter
@@ -380,7 +395,8 @@
     ARM
 
     IMPORT  rt_tsk_lock
-    IMPORT  IRQNestLevel
+    IMPORT  IRQNestLevel                ; Flag indicates whether inside an ISR, and the depth of nesting.  0 = not in ISR.
+    IMPORT  seen_id0_active             ; Flag used to workaround GIC 390 errata 733075 - set in startup_Renesas_RZ_A1.s
 
     ADD     SP,SP,#8 //fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment)
 
@@ -391,6 +407,11 @@
     LDR     R1, [R1, #0]
     STR     R0, [R1, #0x10]
 
+    ; If it was interrupt ID0, clear the seen flag, otherwise return as normal
+    CMP     R0, #0
+    LDREQ   R1, =seen_id0_active
+    STRBEQ  R0, [R1]                    ; Clear the seen flag, using R0 (which is 0), to save loading another register
+
     LDR     R0, =IRQNestLevel           ; Get address of nesting counter
     LDR     R1, [R0]
     SUB     R1, R1, #1                  ; Decrement nesting counter
--- a/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/SVC_Table.S	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/SVC_Table.S	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
 ; *----------------------------------------------------------------------------
 ; *      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:
--- a/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/HAL_CA9.S	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/HAL_CA9.S	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    HAL_CA9.c
  *      Purpose: Hardware Abstraction Layer for Cortex-A9
- *      Rev.:    3 Sept 2013
+ *      Rev.:    8 April 2015
  *----------------------------------------------------------------------------
  *
- * Copyright (c) 2012 - 2013 ARM Limited
+ * Copyright (c) 2012 - 2015 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:
@@ -36,9 +36,11 @@
     .global rt_get_PSP
     .global _alloc_box
     .global _free_box
+    .global SVC_Handler
     .global PendSV_Handler
     .global OS_Tick_Handler
 
+/* macro defines form rt_HAL_CA.h */
     .EQU CPSR_T_BIT,    0x20
     .EQU CPSR_I_BIT,    0x80
     .EQU CPSR_F_BIT,    0x40
@@ -51,9 +53,11 @@
     .EQU MODE_UND,      0x1B
     .EQU MODE_SYS,      0x1F
 
+/* macro defines form rt_TypeDef.h */
     .EQU TCB_TID,        3        /* 'task id' offset                        */
-    .EQU TCB_STACKF,    32        /* 'stack_frame' offset                    */
-    .EQU TCB_TSTACK,    36        /* 'tsk_stack' offset                      */
+    .EQU TCB_STACKF,    37        /* 'stack_frame' offset                    */
+    .EQU TCB_TSTACK,    44        /* 'tsk_stack' offset for LARGE_STACK      */
+
 
     .extern rt_alloc_box
     .extern os_tsk
@@ -62,14 +66,16 @@
     .extern os_tick_irqack
     .extern rt_systick
 
+    .text
+
 /*----------------------------------------------------------------------------
  *      Functions
  *---------------------------------------------------------------------------*/
-    .text
+
 @ For A-class, set USR/SYS stack
 @ __asm void rt_set_PSP (U32 stack) {
 rt_set_PSP:
-        .arm
+        .ARM
 
         MRS     R1, CPSR
         CPS     #MODE_SYS   @no effect in USR mode
@@ -84,7 +90,7 @@
 @ For A-class, get USR/SYS stack
 @ __asm U32 rt_get_PSP (void) {
 rt_get_PSP:
-        .arm
+        .ARM
 
         MRS     R1, CPSR
         CPS     #MODE_SYS   @no effect in USR mode
@@ -93,16 +99,15 @@
         MSR     CPSR_c, R1  @no effect in USR mode
         ISB
         BX      LR
-
 @ }
 
 /*--------------------------- _alloc_box ------------------------------------*/
 @ __asm void *_alloc_box (void *box_mem) {
 _alloc_box:
     /* Function wrapper for Unprivileged/Privileged mode. */
-        .arm
+        .ARM
 
-        LDR     R12,=rt_alloc_box       @ __cpp(rt_alloc_box)
+        LDR     R12,=rt_alloc_box
         MRS     R2, CPSR
         LSLS    R2, #28
         BXNE    R12
@@ -115,9 +120,9 @@
 @ __asm int _free_box (void *box_mem, void *box) {
 _free_box:
    /* Function wrapper for Unprivileged/Privileged mode. */
-        .arm
+        .ARM
 
-        LDR     R12,=rt_free_box        @ __cpp(rt_free_box)
+        LDR     R12,=rt_free_box
         MRS     R2, CPSR
         LSLS    R2, #28
         BXNE    R12
@@ -131,25 +136,23 @@
 @ #pragma push
 @ #pragma arm
 @ __asm void SVC_Handler (void) {
+SVC_Handler:
+        .eabi_attribute Tag_ABI_align8_preserved,1
+        .ARM
 
-        .type   SVC_Handler, %function
-        .global SVC_Handler
-SVC_Handler:
-@         PRESERVE8
-        .arm
         .extern  rt_tsk_lock
         .extern  rt_tsk_unlock
         .extern  SVC_Count
         .extern  SVC_Table
         .extern  rt_stk_check
         .extern  FPUEnable
+        .extern  scheduler_suspended   @ flag set by rt_suspend, cleared by rt_resume, read by SVC_Handler
 
         .EQU    Mode_SVC, 0x13
 
-        SRSDB   SP!, #Mode_SVC         @ Push LR_SVC and SPRS_SVC onto SVC mode stack
+        SRSDB   SP!, #Mode_SVC         @ Push LR_SVC and SPRS_SVC onto SVC mode stack  @ Use SRSDB because SRSFD isn't supported by GCC-ARM.
         PUSH    {R4}                   @ Push R4 so we can use it as a temp
 
-
         MRS     R4,SPSR                @ Get SPSR
         TST     R4,#CPSR_T_BIT         @ Check Thumb Bit
         LDRNEH  R4,[LR,#-2]            @ Thumb: Load Halfword
@@ -188,8 +191,8 @@
 
         /* Here we will be in SVC mode (even if coming in from PendSV_Handler or OS_Tick_Handler) */
 Sys_Switch:
-        LDR     LR,=os_tsk              @ __cpp(&os_tsk)
-        LDM     LR,{R4,LR}              @ os_tsk.run, os_tsk.new
+        LDR     LR,=os_tsk
+        LDM     LR,{R4,LR}              @ os_tsk.run, os_tsk.new_tsk
         CMP     R4,LR
         BNE     switching
 
@@ -200,7 +203,13 @@
         PUSH    {R12, LR}               @ Store stack adjustment and dummy LR to SVC stack
 
         CPSID   i
+        @ Do not unlock scheduler if it has just been suspended by rt_suspend()
+        LDR     R1,=scheduler_suspended
+        LDRB    R0, [R1]
+        CMP     R0, #1
+        BEQ     dont_unlock
         BLX     rt_tsk_unlock
+dont_unlock:
 
         POP     {R12, LR}               @ Get stack adjustment & discard dummy LR
         ADD     SP, SP, R12             @ Unadjust stack
@@ -218,7 +227,7 @@
 
         PUSH    {R8-R11} @ R4 and LR already stacked
         MOV     R10,R4                  @ Preserve os_tsk.run
-        MOV     R11,LR                  @ Preserve os_tsk.new
+        MOV     R11,LR                  @ Preserve os_tsk.new_tsk
 
         ADD     R8,SP,#16               @ Unstack R4,LR
         LDMIA   R8,{R4,LR}
@@ -234,21 +243,22 @@
         SUB     R8,R8,#4                @ No writeback for store of User LR
         STMDB   R8!,{R0-R3,R12}         @ User R0-R3,R12
         MOV     R3,R10                  @ os_tsk.run
-        MOV     LR,R11                  @ os_tsk.new
+        MOV     LR,R11                  @ os_tsk.new_tsk
         POP     {R9-R12}
         ADD     SP,SP,#12               @ Fix up SP for unstack of R4, LR & SPSR
         STMDB   R8!,{R4-R7,R9-R12}      @ User R4-R11
 
-        @ If applicable, stack VFP state
+        @ If applicable, stack VFP/NEON state
         MRC     p15,0,R1,c1,c0,2        @ VFP/NEON access enabled? (CPACR)
         AND     R2,R1,#0x00F00000
         CMP     R2,#0x00F00000
         BNE     no_outgoing_vfp
         VMRS    R2,FPSCR
         STMDB   R8!,{R2,R4}             @ Push FPSCR, maintain 8-byte alignment
-        VSTMDB  R8!,{S0-S31}
-        LDRB    R2,[R3,#TCB_STACKF]     @ Record in TCB that VFP state is stacked
-        ORR     R2,#2
+        VSTMDB  R8!,{D0-D15}
+        VSTMDB  R8!,{D16-D31}
+        LDRB    R2,[R3,#TCB_STACKF]     @ Record in TCB that NEON/D32 state is stacked
+        ORR     R2,#4
         STRB    R2,[R3,#TCB_STACKF]
 
 no_outgoing_vfp:
@@ -268,8 +278,8 @@
 
         MOV     LR,R4
 
-SVC_Next:  @ R4 == os_tsk.run, LR == os_tsk.new, R0-R3, R5-R12 corruptible
-        LDR     R1,=os_tsk              @ __cpp(&os_tsk), os_tsk.run = os_tsk.new
+SVC_Next:  @ R4 == os_tsk.run, LR == os_tsk.new_tsk, R0-R3, R5-R12 corruptible
+        LDR     R1,=os_tsk              @ os_tsk.run = os_tsk.new_tsk
         STR     LR,[R1]
         LDRB    R1,[LR,#TCB_TID]        @ os_tsk.run->task_id
         LSL     R1,#8                   @ Store PROCID
@@ -277,16 +287,17 @@
 
         LDR     R0,[LR,#TCB_TSTACK]     @ os_tsk.run->tsk_stack
 
-        @ Does incoming task have VFP state in stack?
+        @ Does incoming task have VFP/NEON state in stack?
         LDRB    R3,[LR,#TCB_STACKF]
-        TST     R3,#0x2
+        ANDS    R3, R3, #0x6
         MRC     p15,0,R1,c1,c0,2        @ Read CPACR
-        ANDEQ   R1,R1,#0xFF0FFFFF       @ Disable VFP access if incoming task does not have stacked VFP state
-        ORRNE   R1,R1,#0x00F00000       @ Enable VFP access if incoming task does have stacked VFP state
+        ANDEQ   R1,R1,#0xFF0FFFFF       @ Disable VFP/NEON access if incoming task does not have stacked VFP/NEON state
+        ORRNE   R1,R1,#0x00F00000       @ Enable VFP/NEON access if incoming task does have stacked VFP/NEON state
         MCR     p15,0,R1,c1,c0,2        @ Write CPACR
         BEQ     no_incoming_vfp
-        ISB                             @ We only need the sync if we enabled, otherwise we will context switch before next VFP instruction anyway
-        VLDMIA  R0!,{S0-S31}
+        ISB                             @ We only need the sync if we enabled, otherwise we will context switch before next VFP/NEON instruction anyway
+        VLDMIA  R0!,{D16-D31}
+        VLDMIA  R0!,{D0-D15}
         LDR     R2,[R0]
         VMSR    FPSCR,R2
         ADD     R0,R0,#8
@@ -364,20 +375,18 @@
         POP     {R0-R3,R12,LR}
         POP     {R4}
         RFEFD   SP!                     @ Return from exception
-
 @ }
-
 @ #pragma pop
 
-
 @ #pragma push
 @ #pragma arm
 @ __asm void PendSV_Handler (U32 IRQn) {
 PendSV_Handler:
-    .arm
+    .ARM
 
     .extern  rt_tsk_lock
-    .extern  IRQNestLevel
+    .extern  IRQNestLevel                @ Flag indicates whether inside an ISR, and the depth of nesting.  0 = not in ISR.
+    .extern  seen_id0_active             @ Flag used to workaround GIC 390 errata 733075 - set in startup_Renesas_RZ_A1.s
 
     ADD     SP,SP,#8 @ fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment)
 
@@ -385,16 +394,21 @@
     PUSH    {R0, R1}
     BLX     rt_tsk_lock
     POP     {R0, R1}
-    LDR     R1, =GICInterface_BASE      @ __cpp(&GICInterface_BASE)
+    LDR     R1, =GICInterface_BASE
     LDR     R1, [R1, #0]
     STR     R0, [R1, #0x10]
 
+    @ If it was interrupt ID0, clear the seen flag, otherwise return as normal
+    CMP     R0, #0
+    LDREQ   R1, =seen_id0_active
+    STREQB  R0, [R1]                    @ Clear the seen flag, using R0 (which is 0), to save loading another register
+
     LDR     R0, =IRQNestLevel           @ Get address of nesting counter
     LDR     R1, [R0]
     SUB     R1, R1, #1                  @ Decrement nesting counter
     STR     R1, [R0]
 
-    BLX     rt_pop_req                  @ __cpp(rt_pop_req)
+    BLX     rt_pop_req
 
     POP     {R1, LR}                @ Get stack adjustment & discard dummy LR
     ADD     SP, SP, R1              @ Unadjust stack
@@ -407,28 +421,38 @@
 @ }
 @ #pragma pop
 
+
 @ #pragma push
 @ #pragma arm
 @ __asm void OS_Tick_Handler (U32 IRQn) {
 OS_Tick_Handler:
-    .arm
+    .ARM
+
+    .extern  rt_tsk_lock
+    .extern  IRQNestLevel                @ Flag indicates whether inside an ISR, and the depth of nesting.  0 = not in ISR.
+    .extern  seen_id0_active             @ Flag used to workaround GIC 390 errata 733075 - set in startup_Renesas_RZ_A1.s
 
     ADD     SP,SP,#8 @ fix up stack pointer (R0 has been pushed and will never be popped, R1 was pushed for stack alignment)
 
     PUSH    {R0, R1}
     BLX     rt_tsk_lock
     POP     {R0, R1}
-    LDR     R1, =GICInterface_BASE      @ __cpp(&GICInterface_BASE)
+    LDR     R1, =GICInterface_BASE
     LDR     R1, [R1, #0]
     STR     R0, [R1, #0x10]
 
+    @ If it was interrupt ID0, clear the seen flag, otherwise return as normal
+    CMP     R0, #0
+    LDREQ   R1, =seen_id0_active
+    STREQB  R0, [R1]                    @ Clear the seen flag, using R0 (which is 0), to save loading another register
+
     LDR     R0, =IRQNestLevel           @ Get address of nesting counter
     LDR     R1, [R0]
     SUB     R1, R1, #1                  @ Decrement nesting counter
     STR     R1, [R0]
 
-    BLX      os_tick_irqack             @ __cpp(os_tick_irqack)
-    BLX      rt_systick                 @ __cpp(rt_systick)
+    BLX      os_tick_irqack
+    BLX      rt_systick
 
     POP     {R1, LR}                @ Get stack adjustment & discard dummy LR
     ADD     SP, SP, R1              @ Unadjust stack
@@ -441,32 +465,6 @@
 @ }
 @ #pragma pop
 
-    .global __set_PSP
-@ __STATIC_ASM void __set_PSP(uint32_t topOfProcStack)
-@ {
-__set_PSP:
-@     PRESERVE8
-    .arm
-
-    BIC     R0, R0, #7  @ensure stack is 8-byte aligned
-    MRS     R1, CPSR
-    CPS     #MODE_SYS   @no effect in USR mode
-    MOV     SP, R0
-    MSR     CPSR_c, R1  @no effect in USR mode
-    ISB
-    BX      LR
-
-@ }
-
-    .global __set_CPS_USR
-@ __STATIC_ASM void __set_CPS_USR(void)
-@ {
-__set_CPS_USR:
-    .arm
-
-    CPS  #MODE_USR
-    BX   LR
-@ }
 
     .END
 /*----------------------------------------------------------------------------
--- a/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/SVC_Table.S	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/SVC_Table.S	Fri Sep 25 13:30:34 2015 +0100
@@ -34,23 +34,20 @@
 
 
                 .section    SVC_TABLE @, CODE, READONLY
-                .align  5
 
                 .global  SVC_Count
 
 .EQU    SVC_Cnt,        (SVC_End-SVC_Table)/4
-
-SVC_Count:
-                .word   SVC_Cnt
+SVC_Count:      .word   SVC_Cnt
 
 @ Import user SVC functions here.
 @                .extern __SVC_1
+
                 .global SVC_Table
 SVC_Table:
 @ Insert user SVC functions here. SVC 0 used by RTL Kernel.
 @                .word   __SVC_1                 @ InitMemorySubsystem
 
-@SVC_End
 SVC_End:
 
                 .END
--- a/rtx/TARGET_CORTEX_A/cmsis_os.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/cmsis_os.h	Fri Sep 25 13:30:34 2015 +0100
@@ -1,6 +1,6 @@
 /* ----------------------------------------------------------------------
- * $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
@@ -18,9 +18,13 @@
  *     - 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) 2012 ARM LIMITED
+ * 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:
@@ -127,13 +131,13 @@
 #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])
+#define osCMSIS           0x10002      ///< 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])
+#define osCMSIS_RTX     ((4<<16)|74)   ///< 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 osKernelSystemId "RTX V4.74"   ///< RTOS identification string
 
 #define CMSIS_OS_RTX
 #define CMSIS_OS_RTX_CA          /* new define for Coretex-A */
@@ -155,6 +159,7 @@
 #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 osFeature_SysTick      1       ///< osKernelSysTick functions: 1=available, 0=not available
 
 #if defined (__CC_ARM)
 #define os_InRegs __value_in_regs      // Compiler specific: force struct in registers
@@ -345,6 +350,30 @@
 /// \return 0 RTOS is not started, 1 RTOS is started.
 int32_t osKernelRunning(void);
 
+#if (defined (osFeature_SysTick)  &&  (osFeature_SysTick != 0))     // System Timer available
+
+extern uint32_t const os_tickfreq;
+extern uint16_t const os_tickus_i;
+extern uint16_t const os_tickus_f;
+
+/// Get the RTOS kernel system timer counter.
+/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
+/// \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 ====
 
@@ -504,12 +533,6 @@
 /// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
 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.
@@ -529,7 +552,7 @@
 extern const osMutexDef_t os_mutex_def_##name
 #else                            // define the object
 #define osMutexDef(name)  \
-uint32_t os_mutex_cb_##name[3]; \
+uint32_t os_mutex_cb_##name[4] = { 0 }; \
 const osMutexDef_t os_mutex_def_##name = { (os_mutex_cb_##name) }
 #endif
 
@@ -579,7 +602,7 @@
 extern const osSemaphoreDef_t os_semaphore_def_##name
 #else                            // define the object
 #define osSemaphoreDef(name)  \
-uint32_t os_semaphore_cb_##name[2]; \
+uint32_t os_semaphore_cb_##name[2] = { 0 }; \
 const osSemaphoreDef_t os_semaphore_def_##name = { (os_semaphore_cb_##name) }
 #endif
 
@@ -689,7 +712,7 @@
 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)]; \
+uint32_t os_messageQ_q_##name[4+(queue_sz)] = { 0 }; \
 const osMessageQDef_t os_messageQ_def_##name = \
 { (queue_sz), (os_messageQ_q_##name) }
 #endif
@@ -741,7 +764,7 @@
 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 }; \
 const osMailQDef_t os_mailQ_def_##name =  \
@@ -800,6 +823,15 @@
 #endif  // Mail Queues available
 
 
+//  ==== RTX Extensions ====
+
+/// os_suspend: http://www.keil.com/support/man/docs/rlarm/rlarm_os_suspend.htm
+uint32_t os_suspend (void);
+
+/// os_resume: http://www.keil.com/support/man/docs/rlarm/rlarm_os_resume.htm
+void os_resume (uint32_t sleep_time);
+
+
 #ifdef  __cplusplus
 }
 #endif
--- 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);
+}
--- a/rtx/TARGET_CORTEX_A/rt_Event.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Event.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_EVENT.C
  *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Event.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Event.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      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:
--- a/rtx/TARGET_CORTEX_A/rt_HAL_CA.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_HAL_CA.h	Fri Sep 25 13:30:34 2015 +0100
@@ -1,9 +1,9 @@
 /*----------------------------------------------------------------------------
  *      RL-ARM - RTX
  *----------------------------------------------------------------------------
- *      Name:    RT_HAL_CM.H
+ *      Name:    RT_HAL_CA.H
  *      Purpose: Hardware Abstraction Layer for Cortex-A definitions
- *      Rev.:    21 Aug 2013
+ *      Rev.:    14th Jan 2014
  *----------------------------------------------------------------------------
  *
  * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
@@ -169,6 +169,18 @@
   /* HW initialization needs to be done in os_tick_init (void) -RTX_Conf_CM.c- */
 }
 
+__inline static U32 rt_systick_val (void) {
+  /* Cortex-A doesn't have a Systick. User needs to provide an alternative timer using RTX_Conf_CM configuration */
+  /* HW initialization needs to be done in os_tick_init (void) -RTX_Conf_CM.c- */
+  return 0;
+}
+
+__inline static U32 rt_systick_ovf (void) {
+  /* Cortex-A doesn't have a Systick. User needs to provide an alternative timer using RTX_Conf_CM configuration */
+  /* HW initialization needs to be done in os_tick_init (void) -RTX_Conf_CM.c- */
+  return 0;
+}
+
 __inline static void rt_svc_init (void) {
   /* Register pendSV - through SGI */
   volatile char *reg;
--- a/rtx/TARGET_CORTEX_A/rt_HAL_CM.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_HAL_CM.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_HAL_CM.H
  *      Purpose: Hardware Abstraction Layer for Cortex-M 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:
@@ -40,7 +40,7 @@
 
 #if defined (__CC_ARM)          /* ARM Compiler */
 
-#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !NO_EXCLUSIVE_ACCESS)
+#if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !defined(NO_EXCLUSIVE_ACCESS))
  #define __USE_EXCLUSIVE_ACCESS
 #else
  #undef  __USE_EXCLUSIVE_ACCESS
@@ -228,6 +228,14 @@
   NVIC_SYS_PRI3  |= 0xFF000000;
 }
 
+__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) & 1);
+}
+
 __inline static void rt_svc_init (void) {
 #if !(__TARGET_ARCH_6S_M)
   int sh,prigroup;
@@ -262,7 +270,7 @@
 #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!=os_tsk.run)) \
+#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()
--- a/rtx/TARGET_CORTEX_A/rt_List.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_List.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_LIST.C
  *      Purpose: Functions for the management of different lists
- *      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:
--- a/rtx/TARGET_CORTEX_A/rt_List.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_List.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_LIST.H
  *      Purpose: Functions for the management of different lists
- *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Mailbox.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Mailbox.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_MAILBOX.C
  *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Mailbox.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Mailbox.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      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:
--- a/rtx/TARGET_CORTEX_A/rt_MemBox.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_MemBox.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_MEMBOX.C
  *      Purpose: Interface functions for fixed memory block management system
- *      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:
--- a/rtx/TARGET_CORTEX_A/rt_MemBox.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_MemBox.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_MEMBOX.H
  *      Purpose: Interface functions for fixed memory block management system
- *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Memory.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Memory.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_MEMORY.C
  *      Purpose: Interface functions for Dynamic Memory Management System
- *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Memory.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Memory.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_MEMORY.H
  *      Purpose: Interface functions for Dynamic Memory Management System
- *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Mutex.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Mutex.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_MUTEX.C
  *      Purpose: Implements mutex synchronization objects
- *      Rev.:    V4.60
+ *      Rev.:    V4.73
  *----------------------------------------------------------------------------
  *
- * 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:
@@ -56,10 +56,10 @@
   P_MUCB p_MCB = mutex;
 
   p_MCB->cb_type = MUCB;
-  p_MCB->prio    = 0;
   p_MCB->level   = 0;
   p_MCB->p_lnk   = NULL;
   p_MCB->owner   = NULL;
+  p_MCB->p_mlnk  = NULL;
 }
 
 
@@ -70,14 +70,47 @@
   /* Delete a mutex object */
   P_MUCB p_MCB = mutex;
   P_TCB  p_TCB;
+  P_MUCB p_mlnk;
+  U8     prio;
 
   __DMB();
   /* 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);
+
+    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 && (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) {
@@ -109,6 +142,8 @@
   /* 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) {
     /* Unbalanced mutex release or task is not the owner */
@@ -118,8 +153,34 @@
   if (--p_MCB->level != 0) {
     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 && (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);
@@ -132,7 +193,8 @@
     /* 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->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);
@@ -147,7 +209,7 @@
     }
   }
   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;
@@ -166,7 +228,8 @@
 
   if (p_MCB->level == 0) {
     p_MCB->owner = os_tsk.run;
-    p_MCB->prio  = os_tsk.run->prio;
+    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) {
@@ -181,7 +244,7 @@
   }
   /* 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);
   }
--- a/rtx/TARGET_CORTEX_A/rt_Mutex.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Mutex.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Robin.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Robin.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_ROBIN.C
  *      Purpose: Round Robin Task switching
- *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Robin.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Robin.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Semaphore.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Semaphore.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_SEMAPHORE.C
  *      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:
@@ -152,7 +152,7 @@
 /*--------------------------- 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);
--- a/rtx/TARGET_CORTEX_A/rt_Semaphore.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Semaphore.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      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:
--- a/rtx/TARGET_CORTEX_A/rt_System.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_System.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_SYSTEM.C
  *      Purpose: System Task Manager
- *      Rev.:    V4.60
+ *      Rev.:    8 April 2015
  *----------------------------------------------------------------------------
  *
- * 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:
@@ -54,6 +54,7 @@
  *---------------------------------------------------------------------------*/
 
 int os_tick_irqn;
+U8  scheduler_suspended = 0;    // flag set by rt_suspend, cleared by rt_resume, read by SVC_Handler
 
 /*----------------------------------------------------------------------------
  *      Local Variables
@@ -68,29 +69,40 @@
  *      Global Functions
  *---------------------------------------------------------------------------*/
 
+#define RL_RTX_VER      0x473
+
 #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;
+#ifdef __CMSIS_RTOS
+  U32 sleep;
+#endif
 
   rt_tsk_lock();
+  scheduler_suspended = 1;
 
   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;
   }
@@ -102,6 +114,8 @@
 
 /*--------------------------- rt_resume -------------------------------------*/
 
+extern void sysUserTimerUpdate (U32 sleep_time);
+
 void rt_resume (U32 sleep_time) {
   /* Resume OS scheduler after suspend */
   P_TCB next;
@@ -133,8 +147,10 @@
     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) {
@@ -155,6 +171,7 @@
   next = rt_get_first (&os_rdy);
   rt_switch_req (next);
 
+  scheduler_suspended = 0;
   rt_tsk_unlock();
 }
 
@@ -163,6 +180,9 @@
 
 void rt_tsk_lock (void) {
   /* Prevent task switching by locking out scheduler */
+  if (os_lock == __TRUE) // don't lock again if already locked
+    return;
+
   if (os_tick_irqn < 0) {
     OS_LOCK();
     os_lock = __TRUE;
@@ -250,6 +270,19 @@
   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 --------------------------------*/
 
--- a/rtx/TARGET_CORTEX_A/rt_System.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_System.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_SYSTEM.H
  *      Purpose: System Task Manager 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:
--- a/rtx/TARGET_CORTEX_A/rt_Task.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Task.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_TASK.C
  *      Purpose: Task functions and system start up.
- *      Rev.:    V4.60
+ *      Rev.:    V4.73
  *----------------------------------------------------------------------------
  *
- * 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:
@@ -79,10 +79,12 @@
   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    = 0;
   p_TCB->interval_time = 0;
   p_TCB->events  = 0;
@@ -101,7 +103,7 @@
 
 void rt_switch_req (P_TCB p_new) {
   /* Switch to next task (identified by "p_new"). */
-  os_tsk.new   = p_new;
+  os_tsk.new_tsk   = p_new;
   p_new->state = RUNNING;
   DBG_TASK_SWITCH(p_new->task_id);
 }
@@ -188,6 +190,7 @@
   if (task_id == 0) {
     /* Change execution priority of calling task. */
     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;
@@ -203,6 +206,7 @@
   }
   p_task = os_active_TCB[task_id-1];
   p_task->prio = new_prio;
+  p_task->prio_base = new_prio;
   if (p_task == os_tsk.run) {
     goto run;
   }
@@ -254,12 +258,40 @@
 OS_RESULT rt_tsk_delete (OS_TID task_id) {
   /* Terminate the task identified with "task_id". */
   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) {
     /* Terminate itself. */
     os_tsk.run->state     = INACTIVE;
     os_tsk.run->tsk_stack = rt_get_PSP ();
     rt_stk_check ();
+    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, 0/*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_MCB->level  = 1;
+        p_MCB->owner  = p_TCB;
+        p_MCB->p_mlnk = p_TCB->p_mlnk;
+        p_TCB->p_mlnk = p_MCB; 
+        p_MCB = p_MCB0->p_mlnk;
+      }
+      else {
+        p_MCB = p_MCB->p_mlnk;
+      }
+    }
     os_active_TCB[os_tsk.run->task_id-1] = NULL;
     rt_free_box (mp_stk, os_tsk.run->stack);
     os_tsk.run->stack = NULL;
@@ -278,11 +310,43 @@
     task_context = os_active_TCB[task_id-1];
     rt_rmv_list (task_context);
     rt_rmv_dly (task_context);
+    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, 0/*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_MCB->level  = 1;
+        p_MCB->owner  = p_TCB;
+        p_MCB->p_mlnk = p_TCB->p_mlnk;
+        p_TCB->p_mlnk = p_MCB; 
+        p_MCB = p_MCB0->p_mlnk;
+      }
+      else {
+        p_MCB = p_MCB->p_mlnk;
+      }
+    }
     os_active_TCB[task_id-1] = 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);
 }
--- a/rtx/TARGET_CORTEX_A/rt_Task.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Task.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_TASK.H
  *      Purpose: Task functions and system start up.
- *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Time.c	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Time.c	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_TIME.C
  *      Purpose: Delay and interval wait functions
- *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Time.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Time.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      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:
--- a/rtx/TARGET_CORTEX_A/rt_Timer.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Timer.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_TIMER.H
  *      Purpose: User timer functions
- *      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:
--- a/rtx/TARGET_CORTEX_A/rt_TypeDef.h	Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_TypeDef.h	Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
  *----------------------------------------------------------------------------
  *      Name:    RT_TYPEDEF.H
  *      Purpose: Type Definitions
- *      Rev.:    V4.60
+ *      Rev.:    V4.73 (plus large stack)
  *----------------------------------------------------------------------------
  *
- * 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:
@@ -64,11 +64,13 @@
   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 Cortex processor                  */
-  U8     stack_frame;             /* Stack frame: 0x1 Basic/Extended, 0x2 FP stacked/not stacked */
-  U8     reserved;
-  U16    priv_stack;              /* Private stack size, 0= system assigned  */
+  U8     stack_frame;             /* Stack frame: 0x0 Basic, 0x1 Extended, 0x2 VFP/D16 stacked, 0x4 NEON/D32 stacked */
+  U16    reserved;                /* Reserved (padding)                      */
+  U32    priv_stack;              /* Private stack size for LARGE_STACK, 0= system assigned  */
   U32    tsk_stack;               /* Current task Stack pointer (R13)        */
   U32    *stack;                  /* Pointer to Task Stack memory block      */
 
@@ -76,8 +78,8 @@
   FUNCP  ptask;                   /* Task entry address                      */
 } *P_TCB;
 #define TCB_TID          3        /* 'task id' offset                        */
-#define TCB_STACKF      32        /* 'stack_frame' offset                    */
-#define TCB_TSTACK      36        /* 'tsk_stack' offset                      */
+#define TCB_STACKF      37        /* 'stack_frame' offset                    */
+#define TCB_TSTACK      44        /* 'tsk_stack' offset for LARGE_STACK      */
 
 typedef struct OS_PSFE {          /* Post Service Fifo Entry                 */
   void  *id;                      /* Object Identification                   */
@@ -94,7 +96,7 @@
 
 typedef struct OS_TSK {
   P_TCB  run;                     /* Current running task                    */
-  P_TCB  new;                     /* Scheduled task to run                   */
+  P_TCB  new_tsk;                 /* Scheduled task to run                   */
 } *P_TSK;
 
 typedef struct OS_ROBIN {         /* Round Robin Control                     */
@@ -133,10 +135,10 @@
 
 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 {