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品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
随机推荐
- python不能运行
运行python文件出现,报错please select a valid interpreter 这是因为没有选择interpreter 就是更改目录时需要重新选择pytho解析器 解决方法如下 更 ...
- 【HDOJ6586】String(枚举)
题意:给定一个由小写字母组成的字符串S,要求从中选出一个长度为k的子序列,使得其字典序最小,并且第i个字母在子序列中出现的次数在[l[i],r[i]]之间 n,k<=1e5 思路:大概就是记一下 ...
- 'Error Domain=NSURLErrorDomain Code=-999' AFNetworking请求报错
早上请求app请求登录接口发现了下面的错误信息: Error Domain=NSURLErrorDomain Code=-999 "已取消" UserInfo={NSErrorFa ...
- python的map、reduce和filter(过滤器)函数(廖雪峰老师python基础)
1.map 语法: map(func,Iterable) map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返 ...
- Html代码查看器
Html代码查看器 效果: 分析: 1.连接网络需要权限 <uses-permission android:name="android.permission.INTERNET" ...
- error C2065: ‘_bstr_t’ : undeclared identifier
转自VC错误:http://www.vcerror.com/?p=828 问题描述: error C2065: '_bstr_t' : undeclared identifier 解决方法: 详细的解 ...
- Linux随笔 - linux 多个会话同时执行命令后history记录不全的解决方案【转载】
基本认识linux默认配置是当打开一个shell终端后,执行的所有命令均不会写入到~/.bash_history文件中,只有当前用户退出后才会写入,这期间发生的所有命令其它终端是感知不到的. 问题场景 ...
- 用 Flask 来写个轻博客 (33) — 使用 Flask-RESTful 来构建 RESTful API 之二
Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 构建 RESTful Flask API 定义资源路由 格式 ...
- java--二叉树解析及基本实现
一.二叉树的结构 在进行链表结构开发的过程之中,会发现所有的数据按照首尾相连的状态进行保存,那么 在进行数据查询时为了判断数据是否存在,这种情况下它所面对的时间复杂度就是"O(n)" ...
- python面试题之什么是Tkinter ?
TKinter是一款很知名的Python库,用它我们可以制作图形用户界面.其支持不同的GUI工具和窗口构件,比如按钮.标签.文本框等等.这些工具和构件均有不同的属性,比如维度.颜色.字体等. > ...