mirror of https://github.com/ARMmbed/mbed-os.git
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
parent
b65fbdc3e4
commit
d8a3c68e2c
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
/*----------------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 --------------------------------*/
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue