nucleus学习
task的TCB结构:
- 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 */ //链接指向创建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 */ //指向上一个TCB
- *tc_ready_next; /* next and previous ptrs */ //指向下一个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入口函数,下面是参数
- 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. */ //计时器
- 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创建任务函数:
- 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; //这里设定为pure_suspend,完全挂起。如果设定auto_start,调用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]); //这里挂载进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创建HISR函数:
- 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; //这里优先级与上了3,所以只有0、1、2三种。优先级会更高
- /* 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++; //增加了链表长度计数
- #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 //写入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(请求栈?)
- ; and NU_NULL value
- STR r2,[r13, #-4]! ; Place it on the top of the stack //用r2替换r13下面一格的内容,r2不是0吗。那不是删除了r4的内容吗?
- ; 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 //获取当前进程指针地址
- 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 //又把进程指针清零了
- ; 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,跳转到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 //从另一个地方找了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 //设置了1关闭
- STR r2,[r3, #0] ; Disable time slice //设置time_slice_state
- STR r1,[r0, #20h] ; Reset current time slice //明明已经禁止了为什么还要赋值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 //保存进程栈指针,为什么Slice_State加上#2ch就是进程栈指针呢,可能是结构体向下移动了几位
- ; 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 //获取当前进程指针
- MOV r2,#0 ; Build NU_NULL value //r2置0
- STR r2,[r0, #38h] ; Clear the protect pointer field //清除保护指针字段
- STR r2,[r1, #0] ; Release the actual protection //释放实际保护
- ; Switch to the system stack.
- ; REG_Stack_Ptr = TCD_System_Stack;
- LDR r1, System_Stack ; Pickup address of stack pointer //这里应该建立了新的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 //跳转到_TCT_Schedule
- ;}
在tct.s中有TCT_Schedule(void)内容,这里开关的中断屏蔽寄存器,来使得进程能跟切换(进程指针的获取):
- ;************************************************************************
- ;*
- ;* 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为什么要跳转
- ; Restore interrupts according to the value contained in //根据在TCD_Interrupt_Level中值恢复中断
- ; 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 //获取当前中断屏蔽字段
- BIC r0,r0,#LOCK_MSK ; Clear the interrupt lockout bits //清除中断屏蔽
- ORR r0,r0,r2 ; Build new interrupt lockout CPSR //设置新的中断屏蔽字段
- MSR CPSR,r0 ; Setup new CPSR //写回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. //确认是否进入了TCT_Schedule时已经运行了task
- ; if not, we start IDLE. //如果没运行就空闲
- LDR r0,[r2, #0] ; Pickup highest priority HISR ptr //获取最高有限级的HISR指针
- CMP r0,#0 ; Is there a HISR active? //是否已经运行,0是运行
- BNE TCT_Schedule_Thread ; Found an HISR //建立一个HISR,下面是TCT_Schedule_Thread
- 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. //不是0就开始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 //跳转到__NU_IDLE_HOOK这个是进等待吧,钩子
- 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: //这里应该是调度任务了
- MRS r1,CPSR ; Pickup CPSR again //获取CPSR
- ORR r1,r1,#LOCKOUT ; Build interrupt lockout value //进行逻辑或设置中断屏蔽值
- MSR CPSR,r1 ; Lockout interrupts //为什么设置了中断屏蔽就会运行了,是不是通过开关中断屏蔽,来让任务自动抢占?上面获取了HISR最高优先级的指针地址
- ; Transfer control to the thread by falling through to the following
- ; routine.
- ;}
control_to_thread,只要确认了time slice有没有正常工作。:
- ;************************************************************************
- ;*
- ;* 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; //设置当前进程指针
- 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计数
- 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) //确认time_slice
- ; {
- CMP r3,#0 ; Is there a time slice?
- BEQ TCT_No_Start_TS_1 ; If 0, there is no time slice //如果是0,表明没有。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 //获取time slice
- LDR r1,Slice_State ; Pickup address of //获取time slice state
- ; TMD_Time_Slice_State
- STR r3,[r2, #0] ; Setup the time slice //设置time slice
- MOV r2,#0 ; Build active state flag //置0
- STR r2,[r1,#0] ; Set the active flag //设置活动标志
- ; }
- 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 //跳转到__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 //运行新的thread
任务的切换主要是上下文的切换,也就是task栈的切换,函数的调用会保存部分regs和返回地址,这些动作都是编译器来完成的,而OS中的任务切换是运行时(runtime)的一种状态变化,因此编译器也无能为力,所以对于上下文的保存需要代码来实现。
任务的抢占是异步的因此必须要通过中断来实现,一般每次timer的中断决定当前的task的slice time是否expired,然后设置TCT_Set_Execute_Task为相同优先级的其他task或更高优先级的task;高优先级的task抢占低优先级的task,一般是外部中断触发,在HISR中resume_task()唤醒高优先级的task,然后schedule到高优先级的task中,因为timer的HISR是在系统初始化就已经注册的,只是执行timeout和time slice超时后的操作,并没有执行resume_task的动作。
http://blog.chinaunix.net/uid-22003667-id-3291833.html
nucleus学习的更多相关文章
- nucleus 学习 中断
;************************************************************************ ;* ;* FUNCTION ;* ;* INT_I ...
- nucleus plus代码学习
int.S: ;************************************************************************ ;* ;* FUNCTION ;* ; ...
- nucleus plus学习总结
前言: 最近一直都在看nucleus plus,之前看过一些linux内核的一些东西,但都是停留在文字上,代码看的很少,这个nucleus plus内核的代码量不大,看过source code ...
- nucleus plus学习总结(后续)
前言: 刚刚抽筋点了保存发布,结果要审核,那就分开写个续好了. 内容: signal 信号是异步通知task的一种机制,HISR是不可以接收信号的,但是可以发送信号. TCB中 ...
- Android 学习资料收集
收集整理这份资料灵感来自于 trip_to_iOS, 征得同意引用了该资料的开头描述 收集整理这份资料主要帮助初学者学习 Android 开发, 希望能快速帮助到他们快速入门, 找到适合自己学习资料, ...
- Teaching Machines to Understand Us 让机器理解我们 之二 深度学习的历史
Deep history 深度学习的历史 The roots of deep learning reach back further than LeCun’s time at Bell Labs. H ...
- 吴恩达-coursera-机器学习-week4
第八.神经网络:表述(Neural Networks: Representation) 8.1 非线性假设 8.2 神经元和大脑 8.3 模型表示1 8.4 模型表示2 8.5 样本和直观理解1 8. ...
- Nucleus PLUS简单介绍
近些年来,随着嵌入式系统飞速的发展,嵌入式实时操作系统广泛地应用在制造工业.过程控制.通讯.仪器仪表.汽车.船舶.航空航天.军事.装备.消费类产 品等方面.今天嵌入式系统带来的工业年产值超过了1万亿美 ...
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
随机推荐
- puppet(一种Linux、Unix、windows平台的集中配置管理系统)
puppet是一种Linux.Unix.windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件.用户.cron任务.软件包.系统服务等.puppet把这些系统实体称之为资 ...
- AT2705 Yes or No(组合数学)
传送门 解题思路 首先将这个模型放到坐标轴上,\(x\)轴表示\(1\),\(y\)轴表示\(0\).问题就转化成了从\((0,0)\)走到\((n,m)\),每次可以猜测向\(x\)轴或向\(y\) ...
- window安装nexus和配置
原文 http://www.cnblogs.com/fxmemory/p/7133672.html 一. 认识mav仓库 1.1 maven仓库的作用 回想之前不用maven的时候,我们用ecli ...
- nodejs环境安装
centos7安装nodejs环境 原文地址: https://www.cnblogs.com/MY0101/p/6625344.html 下载地址: https://nodejs.org/dist/ ...
- 从单片机到系统之--uboot启动arm linux
UBOOT官网下载地址:http://ftp.denx.de/pub/u-boot/ 很详细的UBOOT解释: https://www.crifan.com/files/doc/docbook/ubo ...
- 使用 jQuery 实现 radio 的选中与反选
使用 jQuery 实现 radio 的选中与反选 我们知道在 Html 中当我们选中一个radio后,再次点击该 radio,那么该 radio 依然是一个选中的状态,但是有时我们需要实现这样的逻辑 ...
- 建议66,67 注意Arrays.asList()的使用
代码 public static void main(String[] args) { int[]data = {1,2,3,4,5}; List list = Arrays.asList(data) ...
- day 97 VUE第一天
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 报警插件Alertmanager 安装与使用
Alertmanager是一个独立的告警模块,接收Prometheus等客户端发来的警报,之后通过分组.删除重复等处理,并将它们通过路由发送给正确的接收器:告警方式可以按照不同的规则发送给不同的模块负 ...
- 后台获取html控件的值
string name = Request.Form["Name1"].ToString(); “xxx” 里的是name值 Request["xx"]取到相同 ...