📄 tct.s
字号:
; Calculate the amount of available space on the stack.
SUB r3,sp,r2
; Determine if there is enough memory on the stack to save
; all of the registers.
CMP r3,#INT_STACK_SIZE
; If there is enough memory, there is no stack overflow yet
BGE TCT_No_Stack_Error
; Stack overflow condition is about to happen.
MOV r0,#3 ; Build NU_STACK_OVERFLOW code
BL _ERC_System_Error ; Call system error handler
TCT_No_Stack_Error
; Determine if this is a new minimum amount of stack space.
; If so, save the new stack minimum.
LDR r2,[r0,#TC_STACK_MINIMUM]
CMP r3,r2
STRCC r3,[r0,#TC_STACK_MINIMUM]
TCT_Skip_Stack_Check
; Return the remaining number of bytes on the stack.
MOV r0,r3
; Return to caller
BX lr
;************************************************************************
;*
;* FUNCTION
;*
;* TCT_Schedule
;*
;* DESCRIPTION
;*
;* This function waits for a thread to become ready. Once a thread
;* is ready, this function initiates a transfer of control to that
;* thread.
;*
;* CALLED BY
;*
;* INC_Initialize Main initialization routine
;* TCT_Control_To_System Transfers control to system
;* TCT_Signal_Exit Exit routine for signals
;* TCT_Unprotect_Specific Unprotects specific protect
;* TCT_Interrupt_Context_Restore Restore context after interrupt
;* TCT_HISR_Shell Entry point for HISRs
;*
;* CALLS
;*
;* TCT_Control_To_Thread Transfer control to a thread
;*
;* INPUTS
;*
;* None
;*
;* OUTPUTS
;*
;* r0 - Pointer to scheduled thread
;*
;* REGISTERS MODIFIED
;*
;* r0, r1, r2
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* S. Nguyen 03/28/2005 Released version 1.15.1
;*
;************************************************************************
;VOID TCT_Schedule(VOID)
.def _TCT_Schedule
_TCT_Schedule
.if NU_TEST2_SUPPORT
BL _Set_Suspend_Time
.endif
; Restore interrupts according to the value contained in TCD_Interrupt_Level.
LDR r1,TCT_Int_Level ; Get address of interrupt level
LDR r1,[r1] ; Pickup current interrupt lockout
MRS r0,CPSR ; Pickup current CPSR
BIC r0,r0,#LOCK_MSK ; Clear the interrupt lockout bits
ORR r0,r0,r1 ; Build new interrupt lockout CPSR
MSR CPSR,r0 ; Setup new CPSR
; Get the addresses of the HISR and Task to execute
LDR r2,TCT_Execute_HISR
LDR r3,TCT_Execute_Task
.if NU_PROFILE_PLUS
; Check to see if there is a task to execute upon entering TCT_Schedule.
; If not, we start IDLE.
LDR r0,[r2] ; Pickup highest priority HISR ptr
CMP r0,#0 ; Is there a HISR active?
BNE TCT_Schedule_Thread ; Found an HISR
LDR r0,[r3] ; Pickup highest priority Task ptr
CMP r0,#0 ; Is there a task active?
BNE TCT_Schedule_Thread ; If not, start IDLE.
STMDB sp!,{r2-r3} ; Save r2-r3
BL __NU_Idle_Hook
LDMIA sp!,{r2-r3} ; Restore r2-r3
.endif
.def TCT_Schedule_Loop
TCT_Schedule_Loop
; Wait until a thread (task or HISR) is available to execute.
; When a thread is available, branch to TCT_Schedule_Thread.
LDR r0,[r2] ; Pickup highest priority HISR ptr
CMP r0,#0 ; Is there a HISR active?
BNE TCT_Schedule_Thread ; Found a HISR
LDR r0,[r3] ; Pickup highest priority Task ptr
CMP r0,#0 ; Is there a task active?
;;;;; TI CODE : modification starts
.ref INT_Small_Sleep
BEQ INT_Small_Sleep ; No, enter the GSM Small Sleep mode
;;;;;BEQ TCT_Schedule_Loop ; If not, continue the search
;;;;!; TI CODE : modification ends
TCT_Schedule_Thread
; Either a task or HISR is ready to execute. Lockout interrupts while
; the thread is transferred (by falling through to the following routine).
MRS r1,CPSR ; Pickup CPSR again
ORR r1,r1,#LOCKOUT ; Build interrupt lockout value
MSR CPSR,r1 ; Lockout interrupts
;************************************************************************
;*
;* FUNCTION
;*
;* TCT_Control_To_Thread
;*
;* DESCRIPTION
;*
;* This function transfers control to the specified thread. Each
;* time control is transferred to a thread, its scheduled counter
;* is incremented. Additionally, time-slicing for task threads is
;* enabled in this routine. The TCD_Current_Thread pointer is
;* setup by this function.
;*
;* CALLED BY
;*
;* TCT_Schedule Indirectly called
;* TCT_Protect Protection task switch
;*
;* CALLS
;*
;* None
;*
;* INPUTS
;*
;* r0 - Thread pointer to schedule
;*
;* OUTPUTS
;*
;* None
;*
;* REGISTERS MODIFIED
;*
;* r0, r1, r2, r3, sp, pc, SPSR
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* S. Nguyen 03/28/2005 Released version 1.15.1
;*
;************************************************************************
;VOID TCT_Control_To_Thread(VOID *thread)
.def _TCT_Control_To_Thread
_TCT_Control_To_Thread
; Put thread pointer into TCD_Current_Thread
LDR r1,TCT_Current_Thread1 ; Pickup current thread ptr address
STR r0,[r1] ; Setup current thread pointer
; TI CODE : Call the Function that log the Current Thread.
.if OP_L1_STANDALONE = 0
.if TI_NUC_MONITOR = 1
.global _ti_nuc_monitor_Thread_log
STMFD sp!,{r0-r5}
BL _ti_nuc_monitor_Thread_log ; Call the Thread Log function.
LDMFD sp!,{r0-r5}
.endif
; WCP Profiler
.if WCP_PROF = 1
.global _prf_LogTaskSwitch
STMFD sp!,{a1-a4}
BL _prf_LogTaskSwitch
LDMFD sp!,{a1-a4}
.endif
.endif
; Increment the thread scheduled counter
LDR r2,[r0, #TC_SCHEDULED] ; Pickup scheduled count
ADD r2,r2,#1 ; Increment the scheduled count
STR r2,[r0, #TC_SCHEDULED] ; Store new scheduled count
; Check for time slice option
LDR r3,[r0, #TC_CUR_TIME_SLICE] ; Pickup time slice value
CMP r3,#0 ; Is there a time slice?
BEQ TCT_No_Start_TS_1 ; If 0, there is no time slice
; Set-up the time slice value
LDR r2,TCT_Time_Slice ; Pickup address of TMD_Time_Slice
STR r3,[r2] ; Setup the time slice
; Enable the time-slice timer
LDR r1,TCT_Slice_State ; Pickup address of TMD_Time_Slice_State
MOV r2,#0 ; Build active state flag
STR r2,[r1] ; Set the active flag
TCT_No_Start_TS_1
.if NU_PROFILE_PLUS
STMDB sp!,{r0} ; Push r0
BL _NU_Schedule_Task_Hook ; Branch to RTView
LDMIA sp!,{r0} ; Pop r0
.endif
; Pickup the thread's stack pointer and resume the thread.
LDR sp,[r0, #TC_STACK_POINTER]
; Pop off the stack top to determine stack type
LDR r1,[sp], #4
; Remove CPSR from stack and put in SPSR
LDR r0,[sp], #4 ; Pop off the CPSR
MSR SPSR,r0 ; Place it into the SPSR
; Check if interrupt stack or solicited stack
CMP r1,#1 ; Compare stack type with 1
BEQ TCT_Interrupt_Resume ; If equal to 1, interrupt stack frame
; Recover all solicited stack frame registers and return
LDMIA sp!,{r4-r12,pc}^ ; A solicited return is required.
; This type of return only
; Recovers r4-r12 & pc
TCT_Interrupt_Resume
; Recover all registers and resume at point of interrupt
LDMIA sp,{r0-pc}^
;************************************************************************
;*
;* 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
;*
;* S. Nguyen 03/28/2005 Released version 1.15.1
;*
;************************************************************************
;VOID TCT_Control_To_System(VOID)
.def _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,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
;*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -