📄 tct.s
字号:
STR lr,[sp, #4]! ; Store lr on the stack
MOV r0,#3 ; Build NU_STACK_OVERFLOW code
LDR r3,=ERC_System_Error ; Call system error handler. Note:
BX r3 ; control is not returned!
; ; Examine stack to find return
; ; address of this routine.
TCT_No_Stack_Error
;
; /* Determine if this is a new minimum amount of stack space. */
; if (remaining < thread -> tc_stack_minimum)
;
LDR r2,[r0,#TC_STACK_MINIMUM]
CMP r3,r2
STRCC r3,[r0,#TC_STACK_MINIMUM]
;
; /* Save the new stack minimum. */
; thread -> tc_stack_minimum = remaining;
; }
; else
;
; /* Set the remaining bytes to 0. */
; remaining = 0;
;
; /* Return the remaining number of bytes on the stack. */
; return(remaining);
;
TCT_Skip_Stack_Check
MOV r0,r3 ; Return remaining bytes
BX lr ; Return to caller
;}
;
;
;
;/*************************************************************************/
;/* */
;/* FUNCTION */
;/* */
;/* TCC_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 */
;/* */
;/* CALLS */
;/* */
;/* TCT_Control_To_Thread Transfer control to a thread */
;/* */
;/* INPUTS */
;/* */
;/* TCD_Execute_Task Pointer to task to execute */
;/* */
;/* OUTPUTS */
;/* */
;/* None */
;/* */
;/* HISTORY */
;/* */
;/* NAME DATE REMARKS */
;/* */
;/* W. Lamie 02-15-1994 Created initial version 1.0 */
;/* D. Lamie 02-15-1994 Verified version 1.0 */
;/* */
;/*************************************************************************/
;VOID TCT_Schedule(void)
;{
EXPORT TCT_Schedule
TCT_Schedule
;
; /* Restore interrupts according to the value contained in
; TCD_Interrupt_Level. */
;
LDR r1,Int_Level ; Build address of interrupt level
MRS r0,CPSR ; Pickup current CPSR
LDR r2,[r1, #0] ; Pickup current interrupt lockout
BIC r0,r0,#LOCK_MSK ; Clear the interrupt lockout bits
ORR r0,r0,r2 ; Build new interrupt lockout CPSR
MSR CPSR_cxsf,r0 ; Setup new CPSR
LDR r2,Execute_HISR ; Pickup TCD_Execute_HISR address
LDR r3,Execute_Task ; Pickup TCD_Execute_Task address
;
IF INCLUDE_PROVIEW
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Nucleus ProView Hook
;
; We check if upon entering TCT_Schedule we already have a task to excute.
; if not, we start IDLE.
LDR r0,[r2, #0] ; Pickup highest priority HISR ptr
CMP r0,#0 ; Is there a HISR active?
BNE TCT_Schedule_Thread ; Found an HISR
LDR r0,[r3, #0] ; Pickup highest priority Task ptr
CMP r0,#0 ; Is there a task active?
BNE TCT_Schedule_Thread ; If not, start IDLE.
STR r2,[sp, #-4]! ; Save r2 on the stack
STR r3,[sp, #-4]! ; Save r3 on the stack
BL _NU_Idle_Hook
LDR r3,[sp], #4 ; Recover r2
LDR r2,[sp], #4 ; Recover r3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ENDIF
; /* Wait until a thread (task or HISR) is available to execute. */
; do
; {
TCT_Schedule_Loop
;
; } while ((!TCD_Execute_HISR) && (!TCD_Execute_Task));
;
LDR r0,[r2, #0] ; Pickup highest priority HISR ptr
CMP r0,#0 ; Is there a HISR active?
BNE TCT_Schedule_Thread ; Found an HISR
LDR r0,[r3, #0] ; Pickup highest priority Task ptr
CMP r0,#0 ; Is there a task active?
BEQ TCT_Schedule_Loop ; If not, continue the search
;
; /* Yes, either a task or an HISR is ready to execute. Lockout
; interrupts while the thread is transferred to. */
;
TCT_Schedule_Thread
MRS r1,CPSR ; Pickup CPSR again
ORR r1,r1,#LOCKOUT ; Build interrupt lockout value
MSR CPSR_cxsf,r1 ; Lockout interrupts
;
; /* Transfer control to the thread by falling through to the following
; routine. */
;}
;
;
;
;/*************************************************************************/
;/* */
;/* 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 */
;/* */
;/* thread Thread control block pointer */
;/* */
;/* OUTPUTS */
;/* */
;/* None */
;/* */
;/* HISTORY */
;/* */
;/* NAME DATE REMARKS */
;/* */
;/* W. Lamie 02-15-1994 Created initial version 1.0 */
;/* D. Lamie 02-15-1994 Verified version 1.0 */
;/* */
;/*************************************************************************/
;VOID TCT_Control_To_Thread(TC_TCB *thread)
;{
EXPORT TCT_Control_To_Thread
TCT_Control_To_Thread
;
; /* Setup the current thread pointer. */
; TCD_Current_Thread = (VOID *) thread;
;
LDR r1,Current_Thread ; Pickup current thread ptr address
LDR r2,[r0, #TC_SCHEDULED] ; Pickup scheduled count
STR r0,[r1, #0] ; Setup current thread pointer
;
; /* Increment the thread scheduled counter. */
; thread -> tc_scheduled++;
;
LDR r3,[r0, #TC_CUR_TIME_SLICE] ; Pickup time slice value
ADD r2,r2,#1 ; Increment the scheduled count
STR r2,[r0, #TC_SCHEDULED] ; Store new scheduled count
;
; /* Check for time slice option. */
; if (thread -> tc_cur_time_slice)
; {
CMP r3,#0 ; Is there a time slice?
BEQ TCT_No_Start_TS_1 ; If 0, there is no time slice
;
; /* Start a time slice. */
; TMD_Time_Slice = thread -> tc_cur_time_slice;
; TMD_Time_Slice_State = 0;
;
LDR r2,Time_Slice ; Pickup address of TMD_Time_Slice
LDR r1,Slice_State ; Pickup address of
; TMD_Time_Slice_State
STR r3,[r2, #0] ; Setup the time slice
MOV r2,#0 ; Build active state flag
STR r2,[r1,#0] ; Set the active flag
; }
TCT_No_Start_TS_1
;
IF INCLUDE_PROVIEW
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Nucleus ProView Hook
;
STR r0,[sp, #-4]! ; Save r0 on the stack
BL _NU_Schedule_Task_Hook ; Branch to RTView
LDR r0,[sp], #4 ; Recover return address
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ENDIF
; /* Pickup the stack pointer and resume the thread. */
; REG_Stack_Ptr = thread -> tc_stack_pointer;
;
LDR sp,[r0, #TC_STACK_POINTER] ; Switch to thread's stack pointer
;
; /* Pop off the saved information associated with the thread. After we
; determine which type of stack is present. A 1 on the top of the
; stack indicates an interrupt stack, while a 0 on the top of the
; stack indicates a solicited type of stack. */
;
; /* Remember that the interrupt level that is restored must represent
; the interrupt level in TCD_Interrupt_Level. */
;
LDR r1,[sp], #4 ; Pop off the stack type
CMP r1,#1 ; See if it is an interrupt stack
BEQ TCT_Interrupt_Resume ; If so, an interrupt resume of
; thread is required
LDR r1,Int_Level ; Pickup address of interrupt
; lockout
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -