nucleus学习
task的TCB結(jié)構(gòu):
typedef struct TC_TCB_STRUCT
{
????/* Standard thread information first. This information is used by
???????the target dependent portion of this component. Changes made
???????to this area of the structure can have undesirable side effects. */
????CS_NODE tc_created; /* Node for linking to */ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //鏈接指向創(chuàng)建task鏈表
???????????????????????????????????????????????/* created task list */
????UNSIGNED tc_id; /* Internal TCB ID */
????CHAR tc_name[NU_MAX_NAME]; /* Task name */
????DATA_ELEMENT tc_status; /* Task status */
????BOOLEAN tc_delayed_suspend; /* Delayed task suspension*/
????DATA_ELEMENT tc_priority; /* Task priority */
????BOOLEAN tc_preemption; /* Task preemption enable */ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//是否搶占
????UNSIGNED tc_scheduled; /* Task scheduled count */
????UNSIGNED tc_cur_time_slice; /* Current time slice */
????VOID *tc_stack_start; /* Stack starting address */ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //棧起始地址
????VOID *tc_stack_end; /* Stack ending address */
????VOID *tc_stack_pointer; /* Task stack pointer */
????UNSIGNED tc_stack_size; /* Task stack's size */
????UNSIGNED tc_stack_minimum; /* Minimum stack size */
????struct TC_PROTECT_STRUCT
???????????????????????*tc_current_protect; /* Current protection */
????VOID *tc_saved_stack_ptr; /* Previous stack pointer */
????UNSIGNED tc_time_slice; /* Task time slice value */
????/* Information after this point is not used in the target dependent
???????portion of this component. Hence, changes in the following section
???????should not impact assembly language routines. */
????struct TC_TCB_STRUCT
???????????????????????*tc_ready_previous, /* Previously ready TCB */ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //指向上一個(gè)TCB
???????????????????????*tc_ready_next; /* next and previous ptrs */ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //指向下一個(gè)TCB
????/* Task control information follows. */
????UNSIGNED tc_priority_group; /* Priority group mask bit*/
????struct TC_TCB_STRUCT
??????????????????????**tc_priority_head; /* Pointer to list head */ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//指向TCB鏈表頭
????DATA_ELEMENT *tc_sub_priority_ptr; /* Pointer to sub-group */
????DATA_ELEMENT tc_sub_priority; /* Mask of sub-group bit */
????DATA_ELEMENT tc_saved_status; /* Previous task status */
????BOOLEAN tc_signal_active; /* Signal active flag */
#if PAD_3
????DATA_ELEMENT tc_padding[PAD_3];
#endif
???????????????????????????????????????????????/* Task entry function */
????VOID (*tc_entry)(UNSIGNED, VOID *); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//task入口函數(shù),下面是參數(shù)
????UNSIGNED tc_argc; /* Optional task argument */
????VOID *tc_argv; /* Optional task argument */
????VOID (*tc_cleanup) (VOID *);/* Clean-up routine */
????VOID *tc_cleanup_info; /* Clean-up information */
????struct TC_PROTECT_STRUCT
???????????????????????*tc_suspend_protect; /* Protection at time of */
???????????????????????????????????????????????/* task suspension */
????/* Task timer information. */ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//計(jì)時(shí)器
????INT tc_timer_active; /* Active timer flag */
????TM_TCB tc_timer_control; /* Timer control block */
????/* Task signal control information. */
????UNSIGNED tc_signals; /* Current signals */
????UNSIGNED tc_enabled_signals; /* Enabled signals */
????/* tc_saved_status and tc_signal_active are now defined above in an
???????attempt to keep DATA_ELEMENT types together. */
????/* Signal handling routine. */ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //signal中斷處理?
????VOID (*tc_signal_handler) (UNSIGNED);
????/* Reserved words for the system and a single reserved word for the
???????application. */
????UNSIGNED tc_system_reserved_1; /* System reserved word */
????UNSIGNED tc_system_reserved_2; /* System reserved word */
????UNSIGNED tc_system_reserved_3; /* System reserved word */
????UNSIGNED tc_app_reserved_1; /* Application reserved */
????/* This information is accessed in assembly */
#if ((NU_SUPERV_USER_MODE == 1)||(NU_MODULE_SUPPORT == 1))
????UNSIGNED tc_su_mode; /* Supervisor/User mode indicator */
????UNSIGNED tc_module; /* Module identifier */
#endif
} TC_TCB; TCC創(chuàng)建任務(wù)函數(shù):
STATUS TCC_Create_Task(NU_TASK *task_ptr, CHAR *name,
??????????VOID (*task_entry)(UNSIGNED, VOID *), UNSIGNED argc, VOID *argv,
??????????VOID *stack_address, UNSIGNED stack_size,
??????????OPTION priority, UNSIGNED time_slice,
??????????OPTION preempt, OPTION auto_start)
{
R1 TC_TCB *task; /* Task control block ptr */
R2 INT i; /* Working index variable */
STATUS status = NU_SUCCESS;
NU_SUPERV_USER_VARIABLES
????/* Switch to supervisor mode */
????NU_SUPERVISOR_MODE();
????/* Move input task pointer into internal pointer. */
????task = (TC_TCB *) task_ptr;
#ifdef NU_ENABLE_STACK_CHECK
????/* Call stack checking function to check for an overflow condition. */
????TCT_Check_Stack();
#endif
#ifdef NU_ENABLE_HISTORY
????/* Make an entry that corresponds to this function in the system history
???????log. */
????HIC_Make_History_Entry(NU_CREATE_TASK_ID, (UNSIGNED) task,
????????????????????????????????(UNSIGNED) name, (UNSIGNED) task_entry);
#endif
????/* First, clear the task ID just in case it is an old Task
???????Control Block. */
????task -> tc_id = 0;
????/* Fill in the task name. */
????for (i = 0; i < NU_MAX_NAME; i++)
????????task -> tc_name[i] = name[i];
????/* Fill in the basic task information. */
????task -> tc_entry = task_entry;
????task -> tc_argc = argc;
????task -> tc_argv = argv;
????task -> tc_status = NU_PURE_SUSPEND; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //這里設(shè)定為pure_suspend,完全掛起。如果設(shè)定auto_start,調(diào)用resume_task()喚醒task
????task -> tc_delayed_suspend = NU_FALSE;
????task -> tc_scheduled = 0;
????task -> tc_time_slice = time_slice;
????task -> tc_cur_time_slice = time_slice;
????task -> tc_current_protect = NU_NULL;
????task -> tc_suspend_protect = NU_NULL;
????task -> tc_cleanup = NU_NULL;
????task -> tc_cleanup_info = NU_NULL;
????/* Setup task's preemption posture. */
????if (preempt == NU_PREEMPT)
????????task -> tc_preemption = NU_TRUE;
????else
????????task -> tc_preemption = NU_FALSE;
????/* Fill in information about the task's stack. */
????task -> tc_stack_start = stack_address;
????task -> tc_stack_end = 0;
????task -> tc_stack_size = stack_size;
????task -> tc_stack_minimum = stack_size;
????/* Setup priority information for the task. There are two bit maps
???????associated with each task. The first bit map indicates which group
???????of 8-priorities it is. The second bit map indicates the actual
???????priority within the group. */
????task -> tc_priority = priority; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
????task -> tc_priority_head = &(TCD_Priority_List[priority]); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//這里掛載進(jìn)TCB雙向鏈表指針
????task -> tc_sub_priority = (DATA_ELEMENT) (1 << (priority & 7));
????priority = priority >> 3;
????task -> tc_priority_group = ((UNSIGNED) 1) << priority;
????task -> tc_sub_priority_ptr = &(TCD_Sub_Priority_Groups[priority]);
????/* Initialize link pointers. */
????task -> tc_created.cs_previous = NU_NULL;
????task -> tc_created.cs_next = NU_NULL;
????task -> tc_ready_previous = NU_NULL;
????task -> tc_ready_next = NU_NULL;
????/* Build a stack frame for this task by calling TCT_Build_Task_Stack. */
????TCT_Build_Task_Stack(task);
????/* Initialize the signal information of the task. */
????task -> tc_signals = 0;
????task -> tc_enabled_signals = 0;
????task -> tc_signal_handler = 0;
????task -> tc_signal_active = NU_FALSE;
????/* Initialize additional kernel options data */
#if (NU_SUPERV_USER_MODE == 1)
????task->tc_su_mode = 0; /* Initially in User mode */
????task->tc_module = 0; /* Not initially bound to a module */
#endif
????/* Initialize the task timer. */
????task -> tc_timer_active = NU_FALSE;
????TMC_Init_Task_Timer(&(task -> tc_timer_control), (VOID *) task);
????/* Protect the list of created tasks. */
????TCT_Protect(&TCD_List_Protect);
????/* At this point the task is completely built. The ID can now be
???????set and it can be linked into the created task list. */
????task -> tc_id = TC_TASK_ID;
#if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0)
????/* If executing in a thread's context, bind to that thread's module */
????if(TCD_Current_Thread != NU_NULL)
????{
????????status = MSC_Bind_Module_Task(
??????????(MS_MODULE*)(((TC_TCB*)(TCD_Current_Thread))->tc_module), task);
????}
????else /* It must be initialization time, so use the current module */
????{
????????status = MSC_Bind_Module_Task(msd_current_module, task);
????}
#endif /* NU_MODULE_SUPPORT */
????/* Link the task into the list of created tasks and increment the
???????total number of tasks in the system. */
????CSC_Place_On_List(&TCD_Created_Tasks_List, &(task -> tc_created));
????TCD_Total_Tasks++;
#ifdef INCLUDE_PROVIEW
????_RTProf_DumpTask(task,RT_PROF_CREATE_TASK);
#endif
????/* Release the protection. */
????TCT_Unprotect();
????/* Determine if the task should be automatically started. */
????if (auto_start == NU_START)
????{
????????/* Protect the system data structures. */
????????TCT_Protect(&TCD_System_Protect);
????????/* Start the task by resuming it. If the preemption is required,
???????????leave the current task. */
????????if (TCC_Resume_Task(task_ptr, NU_PURE_SUSPEND))
????????????/* Transfer control back to the system. */
????????????TCT_Control_To_System();
????????else
????????????/* Release the protection. */
????????????TCT_Unprotect();
????}
????/* Return to user mode */
????NU_USER_MODE();
????/* Return successful completion. */
????return(status);
} TCC創(chuàng)建HISR函數(shù):
STATUS TCC_Create_HISR(NU_HISR *hisr_ptr, CHAR *name,
??????????VOID (*hisr_entry)(VOID), OPTION priority,
??????????VOID *stack_address, UNSIGNED stack_size)
{
R1 TC_HCB *hisr; /* HISR control block ptr */
R2 INT i; /* Working index variable */
STATUS status = NU_SUCCESS;
NU_SUPERV_USER_VARIABLES
????/* Switch to supervisor mode */
????NU_SUPERVISOR_MODE();
????/* Move input HISR pointer into internal pointer. */
????hisr = (TC_HCB *) hisr_ptr;
#ifdef NU_ENABLE_STACK_CHECK
????/* Call stack checking function to check for an overflow condition. */
????TCT_Check_Stack();
#endif
#ifdef NU_ENABLE_HISTORY
????/* Make an entry that corresponds to this function in the system history
???????log. */
????HIC_Make_History_Entry(NU_CREATE_HISR_ID, (UNSIGNED) hisr,
????????????????????????????????(UNSIGNED) name, (UNSIGNED) hisr_entry);
#endif
????/* First, clear the HISR ID just in case it is an old HISR
???????Control Block. */
????hisr -> tc_id = 0;
????/* Fill in the HISR name. */
????for (i = 0; i < NU_MAX_NAME; i++)
????????hisr -> tc_name[i] = name[i];
????/* Fill in the basic HISR information. */
????hisr -> tc_entry = hisr_entry;
????hisr -> tc_scheduled = 0;
????hisr -> tc_activation_count = 0;
????hisr -> tc_cur_time_slice = 0;
????/* Fill in information about the HISR's stack. */
????hisr -> tc_stack_start = stack_address;
????hisr -> tc_stack_end = 0;
????hisr -> tc_stack_size = stack_size;
????hisr -> tc_stack_minimum = stack_size;
????/* Setup priority information for the HISR. Priorities range from 0 to
???????TC_HISR_PRIORITIES - 1. */
????hisr -> tc_priority = priority & 3; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //這里優(yōu)先級(jí)與上了3,所以只有0、1、2三種。優(yōu)先級(jí)會(huì)更高
????/* Initialize link pointers. */
????hisr -> tc_created.cs_previous = NU_NULL; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //這里不加雙向鏈表
????hisr -> tc_created.cs_next = NU_NULL;
????hisr -> tc_active_next = NU_NULL;
????/* Clear protect pointer. */
????hisr -> tc_current_protect = NU_NULL;
????/* Initialize additional kernel options data */
#if (NU_SUPERV_USER_MODE == 1)
????hisr->tc_su_mode = 1; /* TCT_HISR_Shell in Supervisor mode */
????hisr->tc_module = 0; /* Not initially bound to a module */
#endif
????/* Build a stack frame for this HISR by calling TCT_Build_HISR_Stack. */
????TCT_Build_HISR_Stack(hisr);
????/* Protect the list of created HISRs. */
????TCT_Protect(&TCD_HISR_Protect);
????/* At this point the HISR is completely built. The ID can now be
???????set and it can be linked into the created HISR list. */
????hisr -> tc_id = TC_HISR_ID;
#if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0)
????/* If executing in a thread's context, bind to that thread's module */
????if(TCD_Current_Thread != NU_NULL)
????{
????????status = MSC_Bind_Module_HISR(
??????????(MS_MODULE*)(((TC_TCB*)(TCD_Current_Thread))->tc_module), hisr);
????}
????else /* It must be initialization time, so use the current module */
????{
????????status = MSC_Bind_Module_HISR(msd_current_module, hisr);
????}
#endif /* NU_MODULE_SUPPORT */
????/* Link the HISR into the list of created HISRs and increment the
???????total number of HISRs in the system. */
????CSC_Place_On_List(&TCD_Created_HISRs_List, &(hisr -> tc_created)); ? ? ? ? ? ? ? ? ? ? ? ? ? //在這里加入了鏈表?
????TCD_Total_HISRs++; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //增加了鏈表長(zhǎng)度計(jì)數(shù)
#ifdef INCLUDE_PROVIEW
????_RTProf_DumpHisr(hisr,RT_PROF_CREATE_HISR);
#endif
????/* Release the protection. */
????TCT_Unprotect();
????/* Return to user mode */
????NU_USER_MODE();
????/* Return successful completion. */
????return(status);
}
在tct.s中有TCT_Control_To_System,主要要建立新的system_stack:
;************************************************************************
;*
;* 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
;*
;* HISTORY
;*
;* NAME DATE REMARKS
;*
;* W. Lamie 02-15-1994 Created initial version 1.0
;* D. Lamie 02-15-1994 Verified version 1.0
;* C. Meredith 03-01-1994 Corrected problem in time-slice
;* reset logic, resulting in
;* version 1.1
;* D. Lamie 03-18-1994 Verified version 1.1
;*
;************************************************************************
;VOID TCT_Control_To_System(void)
;{
????.def $TCT_Control_To_System
$TCT_Control_To_System ; Dual-state interworking veneer
????.state16
????BX r15
????NOP
????.state32
????B _TCT_Control_To_System
????????.def _TCT_Control_To_System
_TCT_Control_To_System
????; Lockout interrupts.
????????MRS r0,CPSR ; Pickup current CPSR ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //獲取CPSR值
????????ORR r0,r0,#LOCKOUT ; Build interrupt lockout value
????????MSR CPSR,r0 ; Lockout interrupts ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//寫(xiě)入CPSR中斷屏蔽位
????; Save a minimal context of the thread.
????????STMDB r13!,{r4-r12,r14} ; Save minimal context of thread on ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //保存上下文
????????????????????????????????????????????; the current stack
????????.if THUMB ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //如果是THUMB模式
?????????
?????????MOV r2,r14 ; Determine what state the caller
?????????MOV r2,r2,LSL #31 ; was in and build an
?????????MOV r2,r2,LSR #26 ; appropriate state mask
?????????STR r2,[r13, #-4]! ; Place it on the stack
?????????
????????.endif
????????MOV r2,#0 ; Build solicited stack type value ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//建立solicited stack(請(qǐng)求棧?)
????????????????????????????????????????????; and NU_NULL value
????????STR r2,[r13, #-4]! ; Place it on the top of the stack ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //用r2替換r13下面一格的內(nèi)容,r2不是0嗎。那不是刪除了r4的內(nèi)容嗎?
????; Setup a pointer to the thread control block.
; REG_Thread_Ptr = (TC_TCB *) TCD_Current_Thread;
????????LDR r1,Current_Thread ; Pickup current thread ptr address ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//獲取當(dāng)前進(jìn)程指針地址
????????LDR r0,[r1, #0] ; Pickup current thread pointer
????; Clear the current thread control block pointer.
; TCD_Current_Thread = NU_NULL;
????????LDR r3,Slice_State ; Pickup time slice state address ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //獲取time Slice_State地址
????????STR r2,[r1, #0] ; Set current thread pointer to ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//又把進(jìn)程指針清零了
????????????????????????????????????????????; NU_NULL
; Check to see if a time slice is active. If so, copy the original time
; slice into the current time slice field of the task's control block.
; if (TMD_Time_Slice_State == 0)
; {
????????LDR r1,[r3, #0] ; Pickup time slice state flag ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //r3是Slice_State中的值到r1
????????CMP r1,#0 ; Compare with active value ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//比較是否是0
????????BNE TCT_No_Stop_TS_1 ; If non-active, don't disable ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//如果不是0,跳轉(zhuǎn)到TCT_No_Stop_TS_1
????
????; Insure that the next time the task runs it gets a fresh time
????; slice.
; REG_Thread_Ptr -> tc_cur_time_slice = REG_Thread_Ptr -> tc_time_slice;
????????LDR r1,[r0, #40h] ; Pickup original time slice ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //從另一個(gè)地方找了time slice
????????; Clear any active time slice by setting the state to NOT_ACTIVE.
; TMD_Time_Slice_State = 1;
????????MOV r2,#1 ; Build disable value ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //設(shè)置了1關(guān)閉
????????STR r2,[r3, #0] ; Disable time slice ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//設(shè)置time_slice_state
????????STR r1,[r0, #20h] ; Reset current time slice ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//明明已經(jīng)禁止了為什么還要賦值current time_slice呢。
; }
TCT_No_Stop_TS_1: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??//這里是TCT_No_Stop_TS_1
?????; Save off the current stack pointer in the control block.
; REG_Thread_Ptr -> tc_stack_pointer = (VOID *) REG_Stack_Ptr;
????????STR r13,[r0, #2ch] ; Save the thread's stack pointer ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//保存進(jìn)程棧指針,為什么Slice_State加上#2ch就是進(jìn)程棧指針呢,可能是結(jié)構(gòu)體向下移動(dòng)了幾位
?????; Clear the task's current protection.
; (REG_Thread_Ptr -> tc_current_protect) -> tc_tcb_pointer = NU_NULL;
; REG_Thread_Ptr -> tc_current_protect = NU_NULL;
????????LDR r1,[r0, #38h] ; Pickup current thread pointer ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //獲取當(dāng)前進(jìn)程指針
????????MOV r2,#0 ; Build NU_NULL value ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //r2置0
????????STR r2,[r0, #38h] ; Clear the protect pointer field ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //清除保護(hù)指針字段
????????STR r2,[r1, #0] ; Release the actual protection ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //釋放實(shí)際保護(hù)
????; Switch to the system stack.
; REG_Stack_Ptr = TCD_System_Stack;
????????LDR r1, System_Stack ; Pickup address of stack pointer ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//這里應(yīng)該建立了新的system棧
????????LDR r2, System_Limit ; Pickup address of stack limit ptr
????????LDR r13,[r1, #0] ; Switch to system stack
????????LDR r10,[r2, #0] ; Setup system stack limit
????; Finished, return to the scheduling loop.
????????B _TCT_Schedule ; Return to scheduling loop ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //跳轉(zhuǎn)到_TCT_Schedule
;} 在tct.s中有TCT_Schedule(void)內(nèi)容,這里開(kāi)關(guān)的中斷屏蔽寄存器,來(lái)使得進(jìn)程能跟切換(進(jìn)程指針的獲取):
;************************************************************************
;*
;* 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
;*
;* 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)
;{
????.def $TCT_Schedule
$TCT_Schedule ; Dual-state interworking veneer
????.state16 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //16位模式下?
????BX r15
????NOP
????.state32 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //32位模式下
????B _TCT_Schedule
????????.def _TCT_Schedule
_TCT_Schedule ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//明明下面就是_TCT_Schedule為什么要跳轉(zhuǎn)
????; Restore interrupts according to the value contained in ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //根據(jù)在TCD_Interrupt_Level中值恢復(fù)中斷?
; TCD_Interrupt_Level.
????????LDR r1,Int_Level ; Build address of interrupt level ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//把Int_Level地址讀取到r1? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
????????MRS r0,CPSR ; Pickup current CPSR ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//讀取CPSR到r0
????????LDR r2,[r1, #0] ; Pickup current interrupt lockout ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //獲取當(dāng)前中斷屏蔽字段
????????BIC r0,r0,#LOCK_MSK ; Clear the interrupt lockout bits ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //清除中斷屏蔽
????????ORR r0,r0,r2 ; Build new interrupt lockout CPSR ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//設(shè)置新的中斷屏蔽字段
????????MSR CPSR,r0 ; Setup new CPSR ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //寫(xiě)回CPSR
????????LDR r2,Execute_HISR ; Pickup TCD_Execute_HISR address ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//獲取TCD_Execute_HISR地址到r2
????????LDR r3,Execute_Task ; Pickup TCD_Execute_Task address ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//獲取TCD_Execute_Task地址到r3
????.if $$isdefed("INCLUDE_PROVIEW")
; Nucleus ProView Hook
; We check if upon entering TCT_Schedule we already have a task to excute. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //確認(rèn)是否進(jìn)入了TCT_Schedule時(shí)已經(jīng)運(yùn)行了task
; if not, we start IDLE. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //如果沒(méi)運(yùn)行就空閑
????????LDR r0,[r2, #0] ; Pickup highest priority HISR ptr ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //獲取最高有限級(jí)的HISR指針
????????CMP r0,#0 ; Is there a HISR active? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//是否已經(jīng)運(yùn)行,0是運(yùn)行
????????BNE TCT_Schedule_Thread ; Found an HISR ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//建立一個(gè)HISR,下面是TCT_Schedule_Thread
????????LDR r0,[r3, #0] ; Pickup highest priority Task ptr ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //獲取任務(wù)的最高優(yōu)先級(jí)
????????CMP r0,#0 ; Is there a task active? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//判斷是否運(yùn)行
????????BNE TCT_Schedule_Thread ; If not, start IDLE. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//不是0就開(kāi)始IDLE
????????STR r2,[r13, #-4]! ; Save r2 on the stack ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//把r2壓入棧Execute_HISR地址
????????STR r3,[r13, #-4]! ; Save r3 on the stack ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//把r3壓入棧Execute_Task地址
????????BL __NU_Idle_Hook ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//跳轉(zhuǎn)到__NU_IDLE_HOOK這個(gè)是進(jìn)等待吧,鉤子
????????LDR r3,[r13], #4 ; Recover r2
????????LDR r2,[r13], #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)); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //TCD_Execute_HISR或TCD_Execute_Task為空就一直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?
????????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: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//這里應(yīng)該是調(diào)度任務(wù)了
????????MRS r1,CPSR ; Pickup CPSR again ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //獲取CPSR
????????ORR r1,r1,#LOCKOUT ; Build interrupt lockout value ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//進(jìn)行邏輯或設(shè)置中斷屏蔽值
????????MSR CPSR,r1 ; Lockout interrupts ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//為什么設(shè)置了中斷屏蔽就會(huì)運(yùn)行了,是不是通過(guò)開(kāi)關(guān)中斷屏蔽,來(lái)讓任務(wù)自動(dòng)搶占?上面獲取了HISR最高優(yōu)先級(jí)的指針地址
; Transfer control to the thread by falling through to the following
; routine.
;} control_to_thread,只要確認(rèn)了time slice有沒(méi)有正常工作。: ;************************************************************************
;*
;* 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)
;{
_TCT_Control_To_Thread
????; Setup the current thread pointer.
; TCD_Current_Thread = (VOID *) thread; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//設(shè)置當(dāng)前進(jìn)程指針
????????LDR r1,Current_Thread ; Pickup current thread ptr address
????????LDR r2,[r0, #1ch] ; Pickup scheduled count
????????STR r0,[r1, #0] ; Setup current thread pointer
????; Increment the thread scheduled counter.
; thread -> tc_scheduled++; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//增加scheduled計(jì)數(shù)
????????LDR r3,[r0, #20h] ; Pickup time slice value
????????ADD r2,r2,#1 ; Increment the scheduled count
????????STR r2,[r0, #1ch] ; Store new scheduled count
????; Check for time slice option.
; if (thread -> tc_cur_time_slice) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //確認(rèn)time_slice
; {
????????CMP r3,#0 ; Is there a time slice?
????????BEQ TCT_No_Start_TS_1 ; If 0, there is no time slice ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //如果是0,表明沒(méi)有。time slice沒(méi)有運(yùn)行
????????; 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 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//獲取time slice
????????LDR r1,Slice_State ; Pickup address of? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //獲取time slice state
????????????????????????????????????????????; TMD_Time_Slice_State
????????STR r3,[r2, #0] ; Setup the time slice ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//設(shè)置time slice
????????MOV r2,#0 ; Build active state flag ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //置0
????????STR r2,[r1,#0] ; Set the active flag ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//設(shè)置活動(dòng)標(biāo)志
; }
TCT_No_Start_TS_1: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//這里是TCT_No_Start_TS_1
????.if $$isdefed("INCLUDE_PROVIEW") ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//如果定義了INCLUDE_PROVIEW
; Nucleus ProView Hook
????????STR r0,[r13, #-4]! ; Save r0 on the stack ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//把r0壓入棧
????????BL __NU_Schedule_Task_Hook ; Branch to RTView ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//跳轉(zhuǎn)到__NU_Schedule_Task_Hook?
????????LDR r0,[r13], #4 ; Recover return address
????.endif
????; Pickup the stack pointer and resume the thread.
; REG_Stack_Ptr = thread -> tc_stack_pointer;
????????LDR r13,[r0, #2ch] ; Switch to thread ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //運(yùn)行新的thread ?
?任務(wù)的切換主要是上下文的切換,也就是task棧的切換,函數(shù)的調(diào)用會(huì)保存部分regs和返回地址,這些動(dòng)作都是編譯器來(lái)完成的,而OS中的任務(wù)切換是運(yùn)行時(shí)(runtime)的一種狀態(tài)變化,因此編譯器也無(wú)能為力,所以對(duì)于上下文的保存需要代碼來(lái)實(shí)現(xiàn)。
?
?任務(wù)的搶占是異步的因此必須要通過(guò)中斷來(lái)實(shí)現(xiàn),一般每次timer的中斷決定當(dāng)前的task的slice time是否expired,然后設(shè)置TCT_Set_Execute_Task為相同優(yōu)先級(jí)的其他task或更高優(yōu)先級(jí)的task;高優(yōu)先級(jí)的task搶占低優(yōu)先級(jí)的task,一般是外部中斷觸發(fā),在HISR中resume_task()喚醒高優(yōu)先級(jí)的task,然后schedule到高優(yōu)先級(jí)的task中,因?yàn)閠imer的HISR是在系統(tǒng)初始化就已經(jīng)注冊(cè)的,只是執(zhí)行timeout和time slice超時(shí)后的操作,并沒(méi)有執(zhí)行resume_task的動(dòng)作。
http://blog.chinaunix.net/uid-22003667-id-3291833.html
在tct.s中有TCT_Control_To_System,主要要建立新的system_stack:
?任務(wù)的切換主要是上下文的切換,也就是task棧的切換,函數(shù)的調(diào)用會(huì)保存部分regs和返回地址,這些動(dòng)作都是編譯器來(lái)完成的,而OS中的任務(wù)切換是運(yùn)行時(shí)(runtime)的一種狀態(tài)變化,因此編譯器也無(wú)能為力,所以對(duì)于上下文的保存需要代碼來(lái)實(shí)現(xiàn)。
?
?任務(wù)的搶占是異步的因此必須要通過(guò)中斷來(lái)實(shí)現(xiàn),一般每次timer的中斷決定當(dāng)前的task的slice time是否expired,然后設(shè)置TCT_Set_Execute_Task為相同優(yōu)先級(jí)的其他task或更高優(yōu)先級(jí)的task;高優(yōu)先級(jí)的task搶占低優(yōu)先級(jí)的task,一般是外部中斷觸發(fā),在HISR中resume_task()喚醒高優(yōu)先級(jí)的task,然后schedule到高優(yōu)先級(jí)的task中,因?yàn)閠imer的HISR是在系統(tǒng)初始化就已經(jīng)注冊(cè)的,只是執(zhí)行timeout和time slice超時(shí)后的操作,并沒(méi)有執(zhí)行resume_task的動(dòng)作。
http://blog.chinaunix.net/uid-22003667-id-3291833.html
轉(zhuǎn)載于:https://www.cnblogs.com/ch122633/p/7363282.html
總結(jié)
- 上一篇: IPCamera WiFi配置方案
- 下一篇: 大数据入门(Hadoop生态系统)