Modify to support NEON for RTOS. (CMSIS-RTOS RTX for Cortex-A9)

We modified to support NEON of CMSIS-RTOS RTX for Cortex-A9 and fixed some bugs of it.
pull/1326/head
tomoyuki yamanaka 2015-09-08 16:37:18 +09:00
parent b65fbdc3e4
commit d8a3c68e2c
35 changed files with 537 additions and 230 deletions

View File

@ -91,18 +91,16 @@ void rt_init_stack (P_TCB p_TCB, FUNCP task_body) {
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) {

View File

@ -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_IDLESTKSIZE*4);
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_
osThreadDef_t os_thread_def_main = {(os_pthread)main, osPriorityNormal, 1, 4*OS_MAINSTKSIZE };
#endif
#if defined (__CC_ARM)
#ifdef __MICROLIB

View File

@ -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 @@ extern U8 const os_fifo_size;
/* 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);

View File

@ -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 @@ __asm void SVC_Handler (void) {
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 @@ Mode_SVC EQU 0x13
/* 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 @@ Sys_Switch
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 @@ switching
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 @@ switching
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 @@ no_outgoing_vfp
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 @@ SVC_Next //R4 == os_tsk.run, LR == os_tsk.new, R0-R3, R5-R12 corruptible
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 @@ __asm void PendSV_Handler (U32 IRQn) {
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 @@ __asm void PendSV_Handler (U32 IRQn) {
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 @@ __asm void OS_Tick_Handler (U32 IRQn) {
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 @@ __asm void OS_Tick_Handler (U32 IRQn) {
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

View File

@ -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:

View File

@ -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 @@ rt_set_PSP:
@ 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 @@ rt_get_PSP:
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 @@ _alloc_box:
@ __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 @@ _free_box:
@ #pragma push
@ #pragma arm
@ __asm void SVC_Handler (void) {
.type SVC_Handler, %function
.global SVC_Handler
SVC_Handler:
@ PRESERVE8
.arm
.eabi_attribute Tag_ABI_align8_preserved,1
.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 @@ SVC_Handler:
/* 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 @@ Sys_Switch:
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 @@ switching:
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 @@ switching:
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 @@ no_outgoing_vfp:
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 @@ SVC_Next: @ R4 == os_tsk.run, LR == os_tsk.new, R0-R3, R5-R12 corruptible
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 @@ SVC_Done:
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 @@ PendSV_Handler:
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 @@ PendSV_Handler:
@ }
@ #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 @@ OS_Tick_Handler:
@ }
@ #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
/*----------------------------------------------------------------------------

View File

@ -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

View File

@ -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 @@ used throughout the whole project.
#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 @@ used throughout the whole project.
#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 @@ osStatus osKernelStart (void);
/// \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 @@ int32_t osSignalSet (osThreadId thread_id, int32_t signals);
/// \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 @@ os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec);
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 @@ osStatus osMutexDelete (osMutexId mutex_id);
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 @@ osStatus osPoolFree (osPoolId pool_id, void *block);
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 @@ os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec);
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 @@ osStatus osMailFree (osMailQId queue_id, void *mail);
#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

View File

@ -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 @@ static __inline t __##f (void) { \
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 @@ static inline t __##f (void) { \
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 @@ static inline t __##f (void) { \
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 @@ uint8_t os_running; // Kernel Running flag
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 @@ osStatus svcKernelInitialize (void) {
sysThreadError(osOK);
os_initialized = 1;
os_running = 0;
return osOK;
}
@ -586,8 +611,10 @@ osStatus svcKernelStart (void) {
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 @@ int32_t svcKernelRunning(void) {
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 @@ int32_t osKernelRunning(void) {
}
}
/// 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 @@ osTimerId svcTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, voi
return NULL;
}
pt->next = NULL;
pt->state = osTimerStopped;
pt->type = (uint8_t)type;
pt->arg = argument;
@ -1176,6 +1226,30 @@ void sysTimerTick (void) {
}
}
/// 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 @@ __NO_RETURN void osTimerThread (void const *argument) {
// 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 @@ int32_t svcSignalClear (osThreadId thread_id, int32_t signals) {
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 @@ int32_t osSignalClear (osThreadId thread_id, int32_t signals) {
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 @@ osMailQId svcMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) {
rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4));
return queue_def->pool;
}
@ -2020,7 +2076,7 @@ osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) {
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 @@ osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) {
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 @@ os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) {
#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);
}

View File

@ -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:

View File

@ -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:

View File

@ -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 @@ __inline static void rt_systick_init (void) {
/* 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;

View File

@ -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 @@ __inline static void rt_systick_init (void) {
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 @@ extern void dbg_task_switch (U32 task_id);
#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()

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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 @@ void rt_mut_init (OS_ID mutex) {
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 @@ OS_RESULT rt_mut_delete (OS_ID mutex) {
/* 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 @@ OS_RESULT rt_mut_release (OS_ID mutex) {
/* 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 @@ OS_RESULT rt_mut_release (OS_ID mutex) {
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 @@ OS_RESULT rt_mut_release (OS_ID mutex) {
/* 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 @@ OS_RESULT rt_mut_release (OS_ID mutex) {
}
}
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 @@ OS_RESULT rt_mut_wait (OS_ID mutex, U16 timeout) {
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 @@ inc:p_MCB->level++;
}
/* 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);
}

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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 @@ OS_RESULT rt_sem_wait (OS_ID semaphore, U16 timeout) {
/*--------------------------- 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);

View File

@ -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:

View File

@ -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 @@ static U8 pend_flags;
* 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 @@ U32 rt_suspend (void) {
/*--------------------------- 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 @@ void rt_resume (U32 sleep_time) {
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 @@ void rt_resume (U32 sleep_time) {
next = rt_get_first (&os_rdy);
rt_switch_req (next);
scheduler_suspended = 0;
rt_tsk_unlock();
}
@ -163,6 +180,9 @@ void rt_resume (U32 sleep_time) {
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 @@ __weak int os_tick_init (void) {
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 --------------------------------*/

View File

@ -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:

View File

@ -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 @@ static void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) {
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 @@ static void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) {
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 @@ OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) {
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 @@ run:if (rt_rdy_prio() > new_prio) {
}
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_TID rt_tsk_create (FUNCP task, U32 prio_stksz, void *stk, void *argv) {
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 @@ OS_RESULT rt_tsk_delete (OS_TID task_id) {
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);
}

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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 @@ typedef struct OS_TCB {
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 @@ typedef struct OS_TCB {
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_PSQ { /* Post Service Queue */
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_SCB {
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 {