📄 tct.s
字号:
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* S. Nguyen 03/28/2005 Released version 1.15.1
;*
;************************************************************************
;VOID TCT_Unprotect_Specific(TC_PROTECT *protect)
.def _TCT_Unprotect_Specific
_TCT_Unprotect_Specific
; Determine if the caller is in a task or HISR thread.
LDR r1,TCT_Current_Thread1 ; Pickup current thread ptr address
LDR r3,[r1] ; Pickup current thread pointer
CMP r3,#0 ; Check to see if it is non-NULL
BEQ TCT_Skip_Unprot_Spec ; If NULL, skip unprotect specific
; Lockout interrupts.
MRS r3,CPSR ; Pickup current CPSR
ORR r2,r3,#LOCKOUT ; Place lockout value in
MSR CPSR,r2 ; Lockout interrupts
; Clear the protection pointer.
MOV r2,#0 ; Build NU_NULL value
STR r2,[r0, #TC_TCB_PTR] ; Clear protection ownership
; Determine if a thread is waiting.
LDR r2,[r0, #TC_THREAD_WAIT] ; Pickup the waiting field
CMP r2,#0 ; Is there another thread waiting?
BEQ TCT_Not_Waiting_Unspec ; No, restore interrupts and return
; Save a minimal context of the thread on the current stack.
STMDB sp!,{r4-r12,lr}
; Check to see if caller was in THUMB mode
; and update saved CPSR accordingly
TST lr,#1 ; Check bit 0 (set if THUMB mode)
ORRNE r3,r3,#THUMB_BIT ; Set THUMB bit if caller in THUMB mode
; Save CPSR on stack (with caller's lock-out bits / mode set correctly)
STR r3,[sp, #-4]!
; Place the solicited stack type value on the top of the stack
MOV r2,#0 ; Build solicited stack type value
STR r2,[sp, #-4]! ; Place it on the top of the stack
; Setup a pointer to the thread control block and clear the current
; thread control block pointer.
LDR r1,TCT_Current_Thread1 ; Pickup current thread ptr address
LDR r0,[r1] ; Pickup current thread pointer
STR r2,[r1] ; Set current thread pointer to NU_NULL
; Check to see if a time slice is active.
LDR r3,TCT_Slice_State ; Pickup time slice state address
LDR r1,[r3] ; Pickup time slice state flag
CMP r1,#0 ; Compare with active value
BNE TCT_No_Stop_TS_3 ; If non-active, don't disable
; Insure that the next time the task runs it gets a fresh time slice
LDR r1,[r0, #TC_TIME_SLICE] ; Pickup original time slice
STR r1,[r0, #TC_CUR_TIME_SLICE] ; Reset current time slice
; Set the time-slice state to NOT_ACTIVE.
MOV r2,#1 ; Build disable value
STR r2,[r3] ; Disable time slice
TCT_No_Stop_TS_3
; Save off the current stack pointer in the control block.
STR sp,[r0, #TC_STACK_POINTER]
; Switch to the system stack.
LDR r1,TCT_System_Stack ; Pickup address of stack pointer
LDR r2,TCT_System_Limit1 ; Pickup address of stack limit ptr
LDR sp,[r1] ; Switch to system stack
LDR r10,[r2] ; Setup system stack limit
; Finished, return to the scheduling loop
B _TCT_Schedule
TCT_Not_Waiting_Unspec
; Restore interrupts to original level
MSR CPSR,r3
TCT_Skip_Unprot_Spec
; Return to caller.
BX lr
;************************************************************************
;*
;* FUNCTION
;*
;* TCT_Set_Current_Protect
;*
;* DESCRIPTION
;*
;* This function sets the current protection field of the current
;* thread's control block to the specified protection pointer.
;*
;* CALLED BY
;*
;* TCC_Resume_Task Resume task function
;*
;* CALLS
;*
;* None
;*
;* INPUTS
;*
;* r0 - Pointer to protection block
;*
;* OUTPUTS
;*
;* None
;*
;* REGISTERS MODIFIED
;*
;* r1
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* S. Nguyen 03/28/2005 Released version 1.15.1
;*
;************************************************************************
;VOID TCT_Set_Current_Protect(TC_PROTECT *protect)
.def _TCT_Set_Current_Protect
_TCT_Set_Current_Protect
; Determine if the caller is in a task or HISR thread.
LDR r1,TCT_Current_Thread1 ; Pickup current thread ptr address
LDR r1,[r1] ; Pickup current thread pointer
CMP r1,#0 ; Check to see if a thread is active
; If the caller is in a task or HISR, modify the current protection.
STRNE r0,[r1, #TC_CURRENT_PROTECT]
; Return to caller.
BX lr
;************************************************************************
;*
;* FUNCTION
;*
;* TCT_Protect_Switch
;*
;* DESCRIPTION
;*
;* This function waits until a specific task no longer has any
;* protection associated with it. This is necessary since task's
;* cannot be suspended or terminated unless they have released all
;* of their protection.
;*
;* CALLED BY
;*
;* System Components
;*
;* CALLS
;*
;* None
;*
;* INPUTS
;*
;* r0 - Pointer to protection block
;*
;* OUTPUTS
;*
;* None
;*
;* REGISTERS MODIFIED
;*
;* r0, r1
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* S. Nguyen 03/28/2005 Released version 1.15.1
;*
;************************************************************************
;VOID TCT_Protect_Switch(TC_TCB *task)
.def _TCT_Protect_Switch
_TCT_Protect_Switch
; Lockout interrupts.
MRS r1,CPSR ; Pickup current CPSR
STMDB sp!,{r1} ; Save CPSR on stack
TCT_Swtich_Loop
ORR r1,r1,#LOCKOUT ; Place lockout value in
MSR CPSR,r1 ; Lockout interrupts
; Wait until the specified task has no protection associated with it.
LDR r1,[r0, #TC_CURRENT_PROTECT] ; Pickup protection of specified thread
CMP r1,#0 ; Does the specified thread have
; an active protection?
BEQ TCT_Switch_Done ; If not, protect switch is done
; Indicate that a higher priority thread is waiting.
MOV r2,#1 ; Build waiting flag value
STR r2,[r1, #TC_THREAD_WAIT] ; Set waiting flag
; Save r0 and lr on stack
STMDB sp!,{r0,lr}
; Get address of thread holding protection
LDR r0,[r1, #TC_TCB_PTR]
; Schedule the protected thread
BL _TCT_Schedule_Protected
; Restore registers
LDMIA sp!,{r0,lr}
; Pickup current CPSR
MRS r1,CPSR
; Keep looping until switch complete (protection free)
B TCT_Swtich_Loop
TCT_Switch_Done
; Restore interrupts.
LDMIA sp!,{r1} ; Get saved CPSR off stack
MSR CPSR,r1 ; Restore CPSR
; Return to caller
BX lr
;************************************************************************
;*
;* FUNCTION
;*
;* TCT_Schedule_Protected
;*
;* DESCRIPTION
;*
;* This function saves the minimal context of the thread and then
;* directly schedules the thread that has protection over the
;* the thread that called this routine.
;*
;* CALLED BY
;*
;* TCT_Protect
;* TCT_Protect_Switch
;*
;* CALLS
;*
;* TCT_Control_To_Thread Transfer control to protected
;* thread
;*
;* INPUTS
;*
;* None
;*
;* OUTPUTS
;*
;* None
;*
;* REGISTERS MODIFIED
;*
;* EAX, EDX, ESP
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* S. Nguyen 03/28/2005 Released version 1.15.1
;*
;************************************************************************
;VOID TCT_Schedule_Protected(TC_TCB *task)
.def _TCT_Schedule_Protected
_TCT_Schedule_Protected
; Interrupts are already locked out by the caller.
; Save minimal context required by the system.
STMDB sp!,{r4-r12,lr} ; Save minimal context
; Pickup current CPSR
MRS r1,CPSR
; Check to see if caller was in THUMB mode
; and update saved CPSR accordingly
TST lr,#1 ; Check bit 0 (set if THUMB mode)
ORRNE r1,r1,#THUMB_BIT ; Set THUMB bit if caller in THUMB mode
; Save CPSR on stack (with caller's lock-out bits / mode set correctly)
STR r1,[sp, #-4]!
; Put solicited stack type on top of the stack
MOV r2,#0 ; Build solicited stack type value
; and NU_NULL value
STR r2,[sp, #-4]! ; Place it on the top of the stack
; Setup a pointer to the thread control block and clear it.
LDR r3,TCT_Current_Thread1 ; Pickup current thread ptr address
LDR r1,[r3] ; Get current thread pointer address
STR r2,[r3] ; Set current thread pointer to NU_NULL
; Check to see if a time slice is active.
LDR r3,TCT_Slice_State ; Pickup time slice state address
LDR r2,[r3] ; Pickup time slice state flag
CMP r2,#0 ; Compare with active value
BNE TCT_No_Stop_TS_4 ; If non-active, don't disable
; Insure that the next time the task runs it gets a fresh time slice
LDR r2,[r1, #TC_TIME_SLICE] ; Pickup original time slice
STR r2,[r1, #TC_CUR_TIME_SLICE] ; Reset current time slice
; Set time-slice state to NOT_ACTIVE.
MOV r2,#1 ; Build disable value
STR r2,[r3] ; Disable time slice
TCT_No_Stop_TS_4
; Save off the current stack pointer in the control block.
STR sp,[r1, #TC_STACK_POINTER]
; Switch to the system stack and system stack limit
LDR r1,TCT_System_Stack ; Pickup address of stack pointer
LDR r2,TCT_System_Limit1 ; Pickup address of stack limit ptr
LDR sp,[r1] ; Switch to system stack
LDR r10,[r2] ; Setup system stack limit
; Transfer control to the specified thread directly.
B _TCT_Control_To_Thread
;************************************************************************
;*
;* FUNCTION
;*
;* TCT_Interrupt_Context_Save
;*
;* DESCRIPTION
;*
;* This function saves the interrupted thread's context. Nested
;* interrupts are also supported. If a task or HISR thread was
;* interrupted, the stack pointer is switched to the system stack
;* after the context is saved.
;*
;* CALLED BY
;*
;* Application ISRs Assembly language ISRs
;* INT_IRQ_Shell IRQ Interrupt handler shell
;* INT_FIQ_Shell FIQ Interrupt handler shell
;*
;* CALLS
;*
;* None
;*
;* INPUTS
;*
;* r0 - Interrupt's vector number
;*
;* OUTPUTS
;*
;* None
;*
;* REGISTERS MODIFIED
;*
;* r1, r2, r3, r4, r5, sp, CPSR
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* S. Nguyen 03/28/2005 Released version 1.15.1
;*
;************************************************************************
;VOID TCT_Interrupt_Context_Save(vector)
.def _TCT_Interrupt_Context_Save
_TCT_Interrupt_Context_Save
.if NU_TEST3_SUPPORT
STMDB sp!,{r0,r12,lr}
BL _Set_Context_Save_Start
LDMIA sp!,{r0,r12,lr}
.endif
; Determine if this is a nested interrupt.
LDR r1,TCT_Int_Count ; Pickup address of interrupt count
LDR r2,[r1] ; Pickup interrupt counter
ADD r2,r2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -