Official mbed Real Time Operating System based on the RTX implementation of the CMSIS-RTOS API open standard.

Dependents:   Assignment_3__Embedded_Software

Fork of mbed-rtos by mbed official

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 {