📄 tct.s
字号:
ENDIF
;************************************************************************
;*
;* FUNCTION
;*
;* TCT_Control_To_System
;*
;* DESCRIPTION
;*
;* This function returns control from a thread to the system. Note
;* that this service is called in a solicited manner, i.e. it is
;* not called from an interrupt thread. Registers required by the
;* compiler to be preserved across function boundaries are saved by
;* this routine. Note that this is usually a sub-set of the total
;* number of available registers.
;*
;* CALLED BY
;*
;* Other Components
;*
;* CALLS
;*
;* TCT_Schedule Schedule the next thread
;*
;* INPUTS
;*
;* None
;*
;* OUTPUTS
;*
;* None
;*
;* REGISTERS MODIFIED
;*
;* r0, r1, r2, r3, r10, sp, CPSR
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* Driscoll, D 01/24/2003 Released Version 1.14.1
;************************************************************************
;VOID TCT_Control_To_System(VOID)
EXPORT TCT_Control_To_System
TCT_Control_To_System
; Lockout interrupts.
MRS r0,CPSR ; Pickup current CPSR
ORR r1,r0,#LOCKOUT ; Build interrupt lockout value
MSR CPSR_cxsf,r1 ; Lockout interrupts
; 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 r0,r0,#THUMB_BIT ; Set THUMB bit if caller in THUMB mode
; Save CPSR on stack (with caller's lock-out bits / mode set correctly)
STR r0,[sp, #-4]!
; Push solicited stack type on the top of the stack.
MOV r2,#0
STR r2,[sp, #-4]!
; Setup a pointer to the thread control block and set the current
; thread pointer to NU_NULL.
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_1 ; 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
; Clear any active time slice by setting the state to NOT_ACTIVE.
MOV r2,#1 ; Build disable value
STR r2,[r3] ; Disable time slice
TCT_No_Stop_TS_1
; Save off the current stack pointer in the control block.
STR sp,[r0, #TC_STACK_POINTER] ; Save the thread's stack pointer
; Clear the task's current protection.
LDR r1,[r0, #TC_CURRENT_PROTECT] ; Pickup current thread pointer
MOV r2,#0 ; Build NU_NULL value
STR r2,[r0, #TC_CURRENT_PROTECT] ; Clear the protect pointer field
STR r2,[r1] ; Release the actual protection
; Switch to the system stack / 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
; Finished, return to the scheduling loop.
B TCT_Schedule ; Return to scheduling loop
;************************************************************************
;*
;* FUNCTION
;*
;* TCT_Signal_Exit
;*
;* DESCRIPTION
;*
;* This function exits from a signal handler. The primary purpose
;* of this function is to clear the scheduler protection and switch
;* the stack pointer back to the normal task's stack pointer.
;*
;* CALLED BY
;*
;* TCC_Signal_Shell Signal handling shell function
;*
;* CALLS
;*
;* TCT_Schedule Scheduler
;*
;* INPUTS
;*
;* None
;*
;* OUTPUTS
;*
;* None
;*
;* REGISTERS MODIFIED
;*
;* r0, r1, r2, r3, r10, sp, CPSR
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* Driscoll, D 01/24/2003 Released Version 1.14.1
;************************************************************************
;VOID TCT_Signal_Exit(VOID)
EXPORT TCT_Signal_Exit
TCT_Signal_Exit
; Lockout interrupts.
MRS r3,CPSR ; Pickup current CPSR
ORR r3,r3,#LOCKOUT ; Build lockout value
MSR CPSR_cxsf,r3 ; Lockout interrupts
; Setup a pointer to the thread control block.
LDR r1,TCT_Current_Thread1 ; Pickup address of thread pointer
LDR r0,[r1] ; Pickup current thread pointer
; Clear the current thread control block.
MOV r2,#0 ; Build NU_NULL value
STR r2,[r1] ; Clear current thread pointer
; 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_2 ; 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
; Clear any active time slice by setting the state to NOT_ACTIVE.
MOV r2,#1 ; Build disable value
STR r2,[r3] ; Disable time slice
TCT_No_Stop_TS_2
; Switch back to the saved stack. The saved stack pointer was saved
; before the signal frame was built.
LDR r1,[r0, #TC_SAVED_STACK_PTR] ; Pickup saved stack pointer
STR r1,[r0, #TC_STACK_POINTER] ; Place in current stack pointer
; Clear the task's current protection.
LDR r1,[r0, #TC_CURRENT_PROTECT] ; Pickup current thread pointer
MOV r2,#0 ; Build NU_NULL value
STR r2,[r0, #TC_CURRENT_PROTECT] ; Clear the protect pointer field
STR r2,[r1] ; Release the actual protection
; Switch to the system stack / 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
; Finished, return to the scheduling loop.
B TCT_Schedule ; Return to scheduling loop
;************************************************************************
;*
;* FUNCTION
;*
;* TCT_Current_Thread
;*
;* DESCRIPTION
;*
;* This function returns the current thread pointer.
;*
;* CALLED BY
;*
;* Application
;* System Components
;*
;* CALLS
;*
;* None
;*
;* INPUTS
;*
;* None
;*
;* OUTPUTS
;*
;* r0 - Pointer to current thread
;*
;* REGISTERS MODIFIED
;*
;* r0
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* Driscoll, D 01/24/2003 Released Version 1.14.1
;************************************************************************
;VOID *TCT_Current_Thread(VOID)
EXPORT TCT_Current_Thread
TCT_Current_Thread
; Return the current thread pointer.
LDR r0,TCT_Current_Thread1 ; Pickup address of thread pointer
LDR r0,[r0] ; Pickup current thread pointer
; Return to caller
BX lr
;************************************************************************
;*
;* FUNCTION
;*
;* TCT_Set_Execute_Task
;*
;* DESCRIPTION
;*
;* This function sets the current task to execute variable under
;* protection against interrupts.
;*
;* CALLED BY
;*
;* TCC Scheduling Routines
;*
;* CALLS
;*
;* None
;*
;* INPUTS
;*
;* r0 - Pointer to task control block
;*
;* OUTPUTS
;*
;* None
;*
;* REGISTERS MODIFIED
;*
;* r0, r1
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* Driscoll, D 01/24/2003 Released Version 1.14.1
;************************************************************************
;VOID TCT_Set_Execute_Task(TC_TCB *task)
EXPORT TCT_Set_Execute_Task
TCT_Set_Execute_Task
; Setup the TCD_Execute_Task pointer.
LDR r1,TCT_Execute_Task ; Pickup execute task ptr address
STR r0,[r1] ; Setup new task to execute
; Return to caller
BX lr
;************************************************************************
;*
;* FUNCTION
;*
;* TCT_Protect
;*
;* DESCRIPTION
;*
;* This function protects against multiple thread access.
;*
;* CALLED BY
;*
;* Application
;* System Components
;*
;* CALLS
;*
;* None
;*
;* INPUTS
;*
;* r0 - Pointer to protection block
;*
;* OUTPUTS
;*
;* None
;*
;* REGISTERS MODIFIED
;*
;* r1, r2, r3
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* Driscoll, D 01/24/2003 Released Version 1.14.1
;************************************************************************
;VOID TCT_Protect(TC_PROTECT *protect)
EXPORT TCT_Protect
TCT_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 it is non-NULL
BEQ TCT_Skip_Protect ; If NULL, skip protection
; Save current CPSR
MRS r2,CPSR ; Pickup current CPSR
STMDB sp!,{r2} ; Save CPSR on stack
TCT_Protect_Loop
; Lock-out interrupts
ORR r2,r2,#LOCKOUT ; Place lockout value in r2
MSR CPSR_cxsf,r2 ; Lockout interrupts
; Wait until the protect structure is available.
LDR r2,[r0, #TC_TCB_PTR] ; Pickup protection owner field
CMP r2,#0 ; Does another thread own this protection?
BEQ TCT_Protect_Available ; If NU_NULL, protection not owned
; Protection structure is not available.
; Indicate that another thread is waiting.
MOV r3,#1 ; Build thread waiting flag
STR r3,[r0, #TC_THREAD_WAIT] ; Set waiting field
; Save r0-r1 and lr on stack
STMDB sp!,{r0-r1,lr}
; Directly schedule the thread holding the protection
MOV r0,r2 ; Place thread owning protect into r0
BL TCT_Schedule_Protected ; Call routine to schedule the
; owner of the protection
; Recover r0-r1 and lr off stack
LDMIA sp!,{r0-r1,lr}
; Pickup current CPSR
MRS r2,CPSR
; Loop until protection available
B TCT_Protect_Loop
TCT_Protect_Available
; Protection structure is available.
; Indicate that current thread owns the protection.
STR r1,[r0, #TC_TCB_PTR]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -