Fork of the mbed-rtos library by mbed.
Dependents: internet_clock 4180_Final_Project 4180_Final_Project_WaveProblems 4180_Final_Project ... more
Fork of mbed-rtos by
Revision 92:bc9729798a19, committed 2015-09-25
- Comitter:
- mbed_official
- Date:
- Fri Sep 25 13:30:34 2015 +0100
- Parent:
- 91:9d001ed5feec
- 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
diff -r 9d001ed5feec -r bc9729798a19 rtos/Mutex.h --- 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 }; }
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/HAL_CA.c --- 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) {
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/RTX_CM_lib.h --- 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
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/RTX_Config.h --- 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);
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/HAL_CA9.c --- 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
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/TOOLCHAIN_ARM/SVC_Table.S --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/HAL_CA9.S --- 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 /*----------------------------------------------------------------------------
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/TOOLCHAIN_GCC/SVC_Table.S --- 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
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/cmsis_os.h --- 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
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_CMSIS.c --- 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); +}
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Event.c --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Event.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_HAL_CA.h --- 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;
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_HAL_CM.h --- 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()
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_List.c --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_List.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Mailbox.c --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Mailbox.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_MemBox.c --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_MemBox.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Memory.c --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Memory.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Mutex.c --- 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); }
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Mutex.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Robin.c --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Robin.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Semaphore.c --- 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);
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Semaphore.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_System.c --- 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 --------------------------------*/
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_System.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Task.c --- 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); }
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Task.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Time.c --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Time.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_Timer.h --- 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:
diff -r 9d001ed5feec -r bc9729798a19 rtx/TARGET_CORTEX_A/rt_TypeDef.h --- 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 {