task的TCB结构:

  1. typedef struct TC_TCB_STRUCT
  2. {
  3. /* Standard thread information first. This information is used by
  4. the target dependent portion of this component. Changes made
  5. to this area of the structure can have undesirable side effects. */
  6. CS_NODE tc_created; /* Node for linking to */                                       //链接指向创建task链表
  7. /* created task list */
  8. UNSIGNED tc_id; /* Internal TCB ID */
  9. CHAR tc_name[NU_MAX_NAME]; /* Task name */
  10. DATA_ELEMENT tc_status; /* Task status */
  11. BOOLEAN tc_delayed_suspend; /* Delayed task suspension*/
  12. DATA_ELEMENT tc_priority; /* Task priority */
  13. BOOLEAN tc_preemption; /* Task preemption enable */                                  //是否抢占
  14. UNSIGNED tc_scheduled; /* Task scheduled count */
  15. UNSIGNED tc_cur_time_slice; /* Current time slice */
  16. VOID *tc_stack_start; /* Stack starting address */                                   //栈起始地址
  17. VOID *tc_stack_end; /* Stack ending address */
  18. VOID *tc_stack_pointer; /* Task stack pointer */
  19. UNSIGNED tc_stack_size; /* Task stack's size */
  20. UNSIGNED tc_stack_minimum; /* Minimum stack size */
  21. struct TC_PROTECT_STRUCT
  22. *tc_current_protect; /* Current protection */
  23. VOID *tc_saved_stack_ptr; /* Previous stack pointer */
  24. UNSIGNED tc_time_slice; /* Task time slice value */
  25. /* Information after this point is not used in the target dependent
  26. portion of this component. Hence, changes in the following section
  27. should not impact assembly language routines. */
  28. struct TC_TCB_STRUCT
  29. *tc_ready_previous, /* Previously ready TCB */                               //指向上一个TCB
  30. *tc_ready_next; /* next and previous ptrs */                                 //指向下一个TCB
  31. /* Task control information follows. */
  32. UNSIGNED tc_priority_group; /* Priority group mask bit*/
  33. struct TC_TCB_STRUCT
  34. **tc_priority_head; /* Pointer to list head */                                //指向TCB链表头
  35. DATA_ELEMENT *tc_sub_priority_ptr; /* Pointer to sub-group */
  36. DATA_ELEMENT tc_sub_priority; /* Mask of sub-group bit */
  37. DATA_ELEMENT tc_saved_status; /* Previous task status */
  38. BOOLEAN tc_signal_active; /* Signal active flag */
  39. #if PAD_3
  40. DATA_ELEMENT tc_padding[PAD_3];
  41. #endif
  42. /* Task entry function */
  43. VOID (*tc_entry)(UNSIGNED, VOID *);                                                              //task入口函数,下面是参数
  44. UNSIGNED tc_argc; /* Optional task argument */
  45. VOID *tc_argv; /* Optional task argument */
  46. VOID (*tc_cleanup) (VOID *);/* Clean-up routine */
  47. VOID *tc_cleanup_info; /* Clean-up information */
  48. struct TC_PROTECT_STRUCT
  49. *tc_suspend_protect; /* Protection at time of */
  50. /* task suspension */
  51. /* Task timer information. */                                                                    //计时器
  52. INT tc_timer_active; /* Active timer flag */
  53. TM_TCB tc_timer_control; /* Timer control block */
  54. /* Task signal control information. */
  55. UNSIGNED tc_signals; /* Current signals */
  56. UNSIGNED tc_enabled_signals; /* Enabled signals */
  57. /* tc_saved_status and tc_signal_active are now defined above in an
  58. attempt to keep DATA_ELEMENT types together. */
  59. /* Signal handling routine. */                                                                   //signal中断处理?
  60. VOID (*tc_signal_handler) (UNSIGNED);
  61. /* Reserved words for the system and a single reserved word for the
  62. application. */
  63. UNSIGNED tc_system_reserved_1; /* System reserved word */
  64. UNSIGNED tc_system_reserved_2; /* System reserved word */
  65. UNSIGNED tc_system_reserved_3; /* System reserved word */
  66. UNSIGNED tc_app_reserved_1; /* Application reserved */
  67. /* This information is accessed in assembly */
  68. #if ((NU_SUPERV_USER_MODE == 1)||(NU_MODULE_SUPPORT == 1))
  69. UNSIGNED tc_su_mode; /* Supervisor/User mode indicator */
  70. UNSIGNED tc_module; /* Module identifier */
  71. #endif
  72. } TC_TCB;

TCC创建任务函数:

  1. STATUS TCC_Create_Task(NU_TASK *task_ptr, CHAR *name,
  2. VOID (*task_entry)(UNSIGNED, VOID *), UNSIGNED argc, VOID *argv,
  3. VOID *stack_address, UNSIGNED stack_size,
  4. OPTION priority, UNSIGNED time_slice,
  5. OPTION preempt, OPTION auto_start)
  6. {
  7. R1 TC_TCB *task; /* Task control block ptr */
  8. R2 INT i; /* Working index variable */
  9. STATUS status = NU_SUCCESS;
  10. NU_SUPERV_USER_VARIABLES
  11. /* Switch to supervisor mode */
  12. NU_SUPERVISOR_MODE();
  13. /* Move input task pointer into internal pointer. */
  14. task = (TC_TCB *) task_ptr;
  15. #ifdef NU_ENABLE_STACK_CHECK
  16. /* Call stack checking function to check for an overflow condition. */
  17. TCT_Check_Stack();
  18. #endif
  19. #ifdef NU_ENABLE_HISTORY
  20. /* Make an entry that corresponds to this function in the system history
  21. log. */
  22. HIC_Make_History_Entry(NU_CREATE_TASK_ID, (UNSIGNED) task,
  23. (UNSIGNED) name, (UNSIGNED) task_entry);
  24. #endif
  25. /* First, clear the task ID just in case it is an old Task
  26. Control Block. */
  27. task -> tc_id = 0;
  28. /* Fill in the task name. */
  29. for (i = 0; i < NU_MAX_NAME; i++)
  30. task -> tc_name[i] = name[i];
  31. /* Fill in the basic task information. */
  32. task -> tc_entry = task_entry;
  33. task -> tc_argc = argc;
  34. task -> tc_argv = argv;
  35. task -> tc_status = NU_PURE_SUSPEND;                                 //这里设定为pure_suspend,完全挂起。如果设定auto_start,调用resume_task()唤醒task
  36. task -> tc_delayed_suspend = NU_FALSE;
  37. task -> tc_scheduled = 0;
  38. task -> tc_time_slice = time_slice;
  39. task -> tc_cur_time_slice = time_slice;
  40. task -> tc_current_protect = NU_NULL;
  41. task -> tc_suspend_protect = NU_NULL;
  42. task -> tc_cleanup = NU_NULL;
  43. task -> tc_cleanup_info = NU_NULL;
  44. /* Setup task's preemption posture. */
  45. if (preempt == NU_PREEMPT)
  46. task -> tc_preemption = NU_TRUE;
  47. else
  48. task -> tc_preemption = NU_FALSE;
  49. /* Fill in information about the task's stack. */
  50. task -> tc_stack_start = stack_address;
  51. task -> tc_stack_end = 0;
  52. task -> tc_stack_size = stack_size;
  53. task -> tc_stack_minimum = stack_size;
  54. /* Setup priority information for the task. There are two bit maps
  55. associated with each task. The first bit map indicates which group
  56. of 8-priorities it is. The second bit map indicates the actual
  57. priority within the group. */
  58. task -> tc_priority = priority;
  59. task -> tc_priority_head = &(TCD_Priority_List[priority]);                                              //这里挂载进TCB双向链表指针
  60. task -> tc_sub_priority = (DATA_ELEMENT) (1 << (priority & 7));
  61. priority = priority >> 3;
  62. task -> tc_priority_group = ((UNSIGNED) 1) << priority;
  63. task -> tc_sub_priority_ptr = &(TCD_Sub_Priority_Groups[priority]);
  64. /* Initialize link pointers. */
  65. task -> tc_created.cs_previous = NU_NULL;
  66. task -> tc_created.cs_next = NU_NULL;
  67. task -> tc_ready_previous = NU_NULL;
  68. task -> tc_ready_next = NU_NULL;
  69. /* Build a stack frame for this task by calling TCT_Build_Task_Stack. */
  70. TCT_Build_Task_Stack(task);
  71. /* Initialize the signal information of the task. */
  72. task -> tc_signals = 0;
  73. task -> tc_enabled_signals = 0;
  74. task -> tc_signal_handler = 0;
  75. task -> tc_signal_active = NU_FALSE;
  76. /* Initialize additional kernel options data */
  77. #if (NU_SUPERV_USER_MODE == 1)
  78. task->tc_su_mode = 0; /* Initially in User mode */
  79. task->tc_module = 0; /* Not initially bound to a module */
  80. #endif
  81. /* Initialize the task timer. */
  82. task -> tc_timer_active = NU_FALSE;
  83. TMC_Init_Task_Timer(&(task -> tc_timer_control), (VOID *) task);
  84. /* Protect the list of created tasks. */
  85. TCT_Protect(&TCD_List_Protect);
  86. /* At this point the task is completely built. The ID can now be
  87. set and it can be linked into the created task list. */
  88. task -> tc_id = TC_TASK_ID;
  89. #if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0)
  90. /* If executing in a thread's context, bind to that thread's module */
  91. if(TCD_Current_Thread != NU_NULL)
  92. {
  93. status = MSC_Bind_Module_Task(
  94. (MS_MODULE*)(((TC_TCB*)(TCD_Current_Thread))->tc_module), task);
  95. }
  96. else /* It must be initialization time, so use the current module */
  97. {
  98. status = MSC_Bind_Module_Task(msd_current_module, task);
  99. }
  100. #endif /* NU_MODULE_SUPPORT */
  101. /* Link the task into the list of created tasks and increment the
  102. total number of tasks in the system. */
  103. CSC_Place_On_List(&TCD_Created_Tasks_List, &(task -> tc_created));
  104. TCD_Total_Tasks++;
  105. #ifdef INCLUDE_PROVIEW
  106. _RTProf_DumpTask(task,RT_PROF_CREATE_TASK);
  107. #endif
  108. /* Release the protection. */
  109. TCT_Unprotect();
  110. /* Determine if the task should be automatically started. */
  111. if (auto_start == NU_START)
  112. {
  113. /* Protect the system data structures. */
  114. TCT_Protect(&TCD_System_Protect);
  115. /* Start the task by resuming it. If the preemption is required,
  116. leave the current task. */
  117. if (TCC_Resume_Task(task_ptr, NU_PURE_SUSPEND))
  118. /* Transfer control back to the system. */
  119. TCT_Control_To_System();
  120. else
  121. /* Release the protection. */
  122. TCT_Unprotect();
  123. }
  124. /* Return to user mode */
  125. NU_USER_MODE();
  126. /* Return successful completion. */
  127. return(status);
  128. }

TCC创建HISR函数:

  1. STATUS TCC_Create_HISR(NU_HISR *hisr_ptr, CHAR *name,
  2. VOID (*hisr_entry)(VOID), OPTION priority,
  3. VOID *stack_address, UNSIGNED stack_size)
  4. {
  5. R1 TC_HCB *hisr; /* HISR control block ptr */
  6. R2 INT i; /* Working index variable */
  7. STATUS status = NU_SUCCESS;
  8. NU_SUPERV_USER_VARIABLES
  9. /* Switch to supervisor mode */
  10. NU_SUPERVISOR_MODE();
  11. /* Move input HISR pointer into internal pointer. */
  12. hisr = (TC_HCB *) hisr_ptr;
  13. #ifdef NU_ENABLE_STACK_CHECK
  14. /* Call stack checking function to check for an overflow condition. */
  15. TCT_Check_Stack();
  16. #endif
  17. #ifdef NU_ENABLE_HISTORY
  18. /* Make an entry that corresponds to this function in the system history
  19. log. */
  20. HIC_Make_History_Entry(NU_CREATE_HISR_ID, (UNSIGNED) hisr,
  21. (UNSIGNED) name, (UNSIGNED) hisr_entry);
  22. #endif
  23. /* First, clear the HISR ID just in case it is an old HISR
  24. Control Block. */
  25. hisr -> tc_id = 0;
  26. /* Fill in the HISR name. */
  27. for (i = 0; i < NU_MAX_NAME; i++)
  28. hisr -> tc_name[i] = name[i];
  29. /* Fill in the basic HISR information. */
  30. hisr -> tc_entry = hisr_entry;
  31. hisr -> tc_scheduled = 0;
  32. hisr -> tc_activation_count = 0;
  33. hisr -> tc_cur_time_slice = 0;
  34. /* Fill in information about the HISR's stack. */
  35. hisr -> tc_stack_start = stack_address;
  36. hisr -> tc_stack_end = 0;
  37. hisr -> tc_stack_size = stack_size;
  38. hisr -> tc_stack_minimum = stack_size;
  39. /* Setup priority information for the HISR. Priorities range from 0 to
  40. TC_HISR_PRIORITIES - 1. */
  41. hisr -> tc_priority = priority & 3;                                                   //这里优先级与上了3,所以只有0、1、2三种。优先级会更高
  42. /* Initialize link pointers. */
  43. hisr -> tc_created.cs_previous = NU_NULL;                                             //这里不加双向链表
  44. hisr -> tc_created.cs_next = NU_NULL;
  45. hisr -> tc_active_next = NU_NULL;
  46. /* Clear protect pointer. */
  47. hisr -> tc_current_protect = NU_NULL;
  48. /* Initialize additional kernel options data */
  49. #if (NU_SUPERV_USER_MODE == 1)
  50. hisr->tc_su_mode = 1; /* TCT_HISR_Shell in Supervisor mode */
  51. hisr->tc_module = 0; /* Not initially bound to a module */
  52. #endif
  53. /* Build a stack frame for this HISR by calling TCT_Build_HISR_Stack. */
  54. TCT_Build_HISR_Stack(hisr);
  55. /* Protect the list of created HISRs. */
  56. TCT_Protect(&TCD_HISR_Protect);
  57. /* At this point the HISR is completely built. The ID can now be
  58. set and it can be linked into the created HISR list. */
  59. hisr -> tc_id = TC_HISR_ID;
  60. #if defined(NU_MODULE_SUPPORT) && (NU_MODULE_SUPPORT > 0)
  61. /* If executing in a thread's context, bind to that thread's module */
  62. if(TCD_Current_Thread != NU_NULL)
  63. {
  64. status = MSC_Bind_Module_HISR(
  65. (MS_MODULE*)(((TC_TCB*)(TCD_Current_Thread))->tc_module), hisr);
  66. }
  67. else /* It must be initialization time, so use the current module */
  68. {
  69. status = MSC_Bind_Module_HISR(msd_current_module, hisr);
  70. }
  71. #endif /* NU_MODULE_SUPPORT */
  72. /* Link the HISR into the list of created HISRs and increment the
  73. total number of HISRs in the system. */
  74. CSC_Place_On_List(&TCD_Created_HISRs_List, &(hisr -> tc_created));                           //在这里加入了链表?
  75. TCD_Total_HISRs++;                                                                           //增加了链表长度计数
  76. #ifdef INCLUDE_PROVIEW
  77. _RTProf_DumpHisr(hisr,RT_PROF_CREATE_HISR);
  78. #endif
  79. /* Release the protection. */
  80. TCT_Unprotect();
  81. /* Return to user mode */
  82. NU_USER_MODE();
  83. /* Return successful completion. */
  84. return(status);
  85. }

在tct.s中有TCT_Control_To_System,主要要建立新的system_stack:

  1. ;************************************************************************
  2. ;*
  3. ;* FUNCTION
  4. ;*
  5. ;* TCT_Control_To_System
  6. ;*
  7. ;* DESCRIPTION
  8. ;*
  9. ;* This function returns control from a thread to the system. Note
  10. ;* that this service is called in a solicited manner, i.e. it is
  11. ;* not called from an interrupt thread. Registers required by the
  12. ;* compiler to be preserved across function boundaries are saved by
  13. ;* this routine. Note that this is usually a sub-set of the total
  14. ;* number of available registers.
  15. ;*
  16. ;* CALLED BY
  17. ;*
  18. ;* Other Components
  19. ;*
  20. ;* CALLS
  21. ;*
  22. ;* TCT_Schedule Schedule the next thread
  23. ;*
  24. ;* INPUTS
  25. ;*
  26. ;* None
  27. ;*
  28. ;* OUTPUTS
  29. ;*
  30. ;* None
  31. ;*
  32. ;* HISTORY
  33. ;*
  34. ;* NAME DATE REMARKS
  35. ;*
  36. ;* W. Lamie 02-15-1994 Created initial version 1.0
  37. ;* D. Lamie 02-15-1994 Verified version 1.0
  38. ;* C. Meredith 03-01-1994 Corrected problem in time-slice
  39. ;* reset logic, resulting in
  40. ;* version 1.1
  41. ;* D. Lamie 03-18-1994 Verified version 1.1
  42. ;*
  43. ;************************************************************************
  44. ;VOID TCT_Control_To_System(void)
  45. ;{
  46. .def $TCT_Control_To_System
  47. $TCT_Control_To_System ; Dual-state interworking veneer
  48. .state16
  49. BX r15
  50. NOP
  51. .state32
  52. B _TCT_Control_To_System
  53. .def _TCT_Control_To_System
  54. _TCT_Control_To_System
  55. ; Lockout interrupts.
  56. MRS r0,CPSR ; Pickup current CPSR                                                                                         //获取CPSR值
  57. ORR r0,r0,#LOCKOUT ; Build interrupt lockout value
  58. MSR CPSR,r0 ; Lockout interrupts                                                                                          //写入CPSR中断屏蔽位
  59. ; Save a minimal context of the thread.
  60. STMDB r13!,{r4-r12,r14} ; Save minimal context of thread on                                                               //保存上下文
  61. ; the current stack
  62. .if THUMB                                                                                                                 //如果是THUMB模式
  63. MOV r2,r14 ; Determine what state the caller
  64. MOV r2,r2,LSL #31 ; was in and build an
  65. MOV r2,r2,LSR #26 ; appropriate state mask
  66. STR r2,[r13, #-4]! ; Place it on the stack
  67. .endif
  68. MOV r2,#0 ; Build solicited stack type value                                                                              //建立solicited stack(请求栈?)
  69. ; and NU_NULL value
  70. STR r2,[r13, #-4]! ; Place it on the top of the stack                                                                     //用r2替换r13下面一格的内容,r2不是0吗。那不是删除了r4的内容吗?
  71. ; Setup a pointer to the thread control block.
  72. ; REG_Thread_Ptr = (TC_TCB *) TCD_Current_Thread;
  73. LDR r1,Current_Thread ; Pickup current thread ptr address                                                              //获取当前进程指针地址
  74. LDR r0,[r1, #0] ; Pickup current thread pointer
  75. ; Clear the current thread control block pointer.
  76. ; TCD_Current_Thread = NU_NULL;
  77. LDR r3,Slice_State ; Pickup time slice state address                                                                   //获取time Slice_State地址
  78. STR r2,[r1, #0] ; Set current thread pointer to                                                                        //又把进程指针清零了
  79. ; NU_NULL
  80. ; Check to see if a time slice is active. If so, copy the original time
  81. ; slice into the current time slice field of the task's control block.
  82. ; if (TMD_Time_Slice_State == 0)
  83. ; {
  84. LDR r1,[r3, #0] ; Pickup time slice state flag                                                                         //r3是Slice_State中的值到r1
  85. CMP r1,#0 ; Compare with active value                                                                                  //比较是否是0
  86. BNE TCT_No_Stop_TS_1 ; If non-active, don't disable                                                                    //如果不是0,跳转到TCT_No_Stop_TS_1
  87. ; Insure that the next time the task runs it gets a fresh time
  88. ; slice.
  89. ; REG_Thread_Ptr -> tc_cur_time_slice = REG_Thread_Ptr -> tc_time_slice;
  90. LDR r1,[r0, #40h] ; Pickup original time slice                                                                         //从另一个地方找了time slice
  91. ; Clear any active time slice by setting the state to NOT_ACTIVE.
  92. ; TMD_Time_Slice_State = 1;
  93. MOV r2,#1 ; Build disable value                                                                                         //设置了1关闭
  94. STR r2,[r3, #0] ; Disable time slice                                                                                    //设置time_slice_state
  95. STR r1,[r0, #20h] ; Reset current time slice                                                                            //明明已经禁止了为什么还要赋值current time_slice呢。
  96. ; }
  97. TCT_No_Stop_TS_1:                                                                                                               //这里是TCT_No_Stop_TS_1
  98. ; Save off the current stack pointer in the control block.
  99. ; REG_Thread_Ptr -> tc_stack_pointer = (VOID *) REG_Stack_Ptr;
  100. STR r13,[r0, #2ch] ; Save the thread's stack pointer                                                                    //保存进程栈指针,为什么Slice_State加上#2ch就是进程栈指针呢,可能是结构体向下移动了几位
  101. ; Clear the task's current protection.
  102. ; (REG_Thread_Ptr -> tc_current_protect) -> tc_tcb_pointer = NU_NULL;
  103. ; REG_Thread_Ptr -> tc_current_protect = NU_NULL;
  104. LDR r1,[r0, #38h] ; Pickup current thread pointer                                                                       //获取当前进程指针
  105. MOV r2,#0 ; Build NU_NULL value                                                                                         //r2置0
  106. STR r2,[r0, #38h] ; Clear the protect pointer field                                                                     //清除保护指针字段
  107. STR r2,[r1, #0] ; Release the actual protection                                                                         //释放实际保护
  108. ; Switch to the system stack.
  109. ; REG_Stack_Ptr = TCD_System_Stack;
  110. LDR r1, System_Stack ; Pickup address of stack pointer                                                                  //这里应该建立了新的system栈
  111. LDR r2, System_Limit ; Pickup address of stack limit ptr
  112. LDR r13,[r1, #0] ; Switch to system stack
  113. LDR r10,[r2, #0] ; Setup system stack limit
  114. ; Finished, return to the scheduling loop.
  115. B _TCT_Schedule ; Return to scheduling loop                                                                             //跳转到_TCT_Schedule
  116. ;}

在tct.s中有TCT_Schedule(void)内容,这里开关的中断屏蔽寄存器,来使得进程能跟切换(进程指针的获取):

  1. ;************************************************************************
  2. ;*
  3. ;* FUNCTION
  4. ;*
  5. ;* TCT_Schedule
  6. ;*
  7. ;* DESCRIPTION
  8. ;*
  9. ;* This function waits for a thread to become ready. Once a thread
  10. ;* is ready, this function initiates a transfer of control to that
  11. ;* thread.
  12. ;*
  13. ;* CALLED BY
  14. ;*
  15. ;* INC_Initialize Main initialization routine
  16. ;*
  17. ;* CALLS
  18. ;*
  19. ;* TCT_Control_To_Thread Transfer control to a thread
  20. ;*
  21. ;* INPUTS
  22. ;*
  23. ;* TCD_Execute_Task Pointer to task to execute
  24. ;*
  25. ;* OUTPUTS
  26. ;*
  27. ;* None
  28. ;*
  29. ;* HISTORY
  30. ;*
  31. ;* NAME DATE REMARKS
  32. ;*
  33. ;* W. Lamie 02-15-1994 Created initial version 1.0
  34. ;* D. Lamie 02-15-1994 Verified version 1.0
  35. ;*
  36. ;************************************************************************
  37. ;VOID TCT_Schedule(void)
  38. ;{
  39. .def $TCT_Schedule
  40. $TCT_Schedule ; Dual-state interworking veneer
  41. .state16                                                                                                                           //16位模式下?
  42. BX r15
  43. NOP
  44. .state32                                                                                                                           //32位模式下
  45. B _TCT_Schedule
  46. .def _TCT_Schedule
  47. _TCT_Schedule                                                                                                                          //明明下面就是_TCT_Schedule为什么要跳转
  48. ; Restore interrupts according to the value contained in                                                                           //根据在TCD_Interrupt_Level中值恢复中断
  49. ; TCD_Interrupt_Level.
  50. LDR r1,Int_Level ; Build address of interrupt level                                                                            //把Int_Level地址读取到r1
  51. MRS r0,CPSR ; Pickup current CPSR                                                                                              //读取CPSR到r0
  52. LDR r2,[r1, #0] ; Pickup current interrupt lockout                                                                             //获取当前中断屏蔽字段
  53. BIC r0,r0,#LOCK_MSK ; Clear the interrupt lockout bits                                                                         //清除中断屏蔽
  54. ORR r0,r0,r2 ; Build new interrupt lockout CPSR                                                                                //设置新的中断屏蔽字段
  55. MSR CPSR,r0 ; Setup new CPSR                                                                                                   //写回CPSR
  56. LDR r2,Execute_HISR ; Pickup TCD_Execute_HISR address                                                                          //获取TCD_Execute_HISR地址到r2
  57. LDR r3,Execute_Task ; Pickup TCD_Execute_Task address                                                                          //获取TCD_Execute_Task地址到r3
  58. .if $$isdefed("INCLUDE_PROVIEW")
  59. ; Nucleus ProView Hook
  60. ; We check if upon entering TCT_Schedule we already have a task to excute.                                                             //确认是否进入了TCT_Schedule时已经运行了task
  61. ; if not, we start IDLE.                                                                                                               //如果没运行就空闲
  62. LDR r0,[r2, #0] ; Pickup highest priority HISR ptr                                                                             //获取最高有限级的HISR指针
  63. CMP r0,#0 ; Is there a HISR active?                                                                                            //是否已经运行,0是运行
  64. BNE TCT_Schedule_Thread ; Found an HISR                                                                                        //建立一个HISR,下面是TCT_Schedule_Thread
  65. LDR r0,[r3, #0] ; Pickup highest priority Task ptr                                                                             //获取任务的最高优先级
  66. CMP r0,#0 ; Is there a task active?                                                                                            //判断是否运行
  67. BNE TCT_Schedule_Thread ; If not, start IDLE.                                                                                  //不是0就开始IDLE
  68. STR r2,[r13, #-4]! ; Save r2 on the stack                                                                                      //把r2压入栈Execute_HISR地址
  69. STR r3,[r13, #-4]! ; Save r3 on the stack                                                                                      //把r3压入栈Execute_Task地址
  70. BL __NU_Idle_Hook                                                                                                              //跳转到__NU_IDLE_HOOK这个是进等待吧,钩子
  71. LDR r3,[r13], #4 ; Recover r2
  72. LDR r2,[r13], #4 ; Recover r3
  73. .endif
  74. ; Wait until a thread (task or HISR) is available to execute.
  75. ; do
  76. ; {
  77. TCT_Schedule_Loop:
  78. ; } while ((!TCD_Execute_HISR) && (!TCD_Execute_Task));                                                                                 //TCD_Execute_HISR或TCD_Execute_Task为空就一直IDLE
  79. LDR r0,[r2, #0] ; Pickup highest priority HISR ptr
  80. CMP r0,#0 ; Is there a HISR active?
  81. BNE TCT_Schedule_Thread ; Found an HISR
  82. LDR r0,[r3, #0] ; Pickup highest priority Task ptr
  83. CMP r0,#0 ; Is there a task active?
  84. BEQ TCT_Schedule_Loop ; If not, continue the search
  85. ; Yes, either a task or an HISR is ready to execute. Lockout
  86. ; interrupts while the thread is transferred to.
  87. TCT_Schedule_Thread:                                                                                                                    //这里应该是调度任务了
  88. MRS r1,CPSR ; Pickup CPSR again                                                                                                 //获取CPSR
  89. ORR r1,r1,#LOCKOUT ; Build interrupt lockout value                                                                              //进行逻辑或设置中断屏蔽值
  90. MSR CPSR,r1 ; Lockout interrupts                                                                                                //为什么设置了中断屏蔽就会运行了,是不是通过开关中断屏蔽,来让任务自动抢占?上面获取了HISR最高优先级的指针地址
  91. ; Transfer control to the thread by falling through to the following
  92. ; routine.
  93. ;}

control_to_thread,只要确认了time slice有没有正常工作。:

  1. ;************************************************************************
  2. ;*
  3. ;* FUNCTION
  4. ;*
  5. ;* TCT_Control_To_Thread
  6. ;*
  7. ;* DESCRIPTION
  8. ;*
  9. ;* This function transfers control to the specified thread. Each
  10. ;* time control is transferred to a thread, its scheduled counter
  11. ;* is incremented. Additionally, time-slicing for task threads is
  12. ;* enabled in this routine. The TCD_Current_Thread pointer is
  13. ;* setup by this function.
  14. ;*
  15. ;* CALLED BY
  16. ;*
  17. ;* TCT_Schedule Indirectly called
  18. ;* TCT_Protect Protection task switch
  19. ;*
  20. ;* CALLS
  21. ;*
  22. ;* None
  23. ;*
  24. ;* INPUTS
  25. ;*
  26. ;* thread Thread control block pointer
  27. ;*
  28. ;* OUTPUTS
  29. ;*
  30. ;* None
  31. ;*
  32. ;* HISTORY
  33. ;*
  34. ;* NAME DATE REMARKS
  35. ;*
  36. ;* W. Lamie 02-15-1994 Created initial version 1.0
  37. ;* D. Lamie 02-15-1994 Verified version 1.0
  38. ;*
  39. ;************************************************************************
  40. ;VOID TCT_Control_To_Thread(TC_TCB *thread)
  41. ;{
  42. _TCT_Control_To_Thread
  43. ; Setup the current thread pointer.
  44. ; TCD_Current_Thread = (VOID *) thread;                                                                                //设置当前进程指针
  45. LDR r1,Current_Thread ; Pickup current thread ptr address
  46. LDR r2,[r0, #1ch] ; Pickup scheduled count
  47. STR r0,[r1, #0] ; Setup current thread pointer
  48. ; Increment the thread scheduled counter.
  49. ; thread -> tc_scheduled++;                                                                                            //增加scheduled计数
  50. LDR r3,[r0, #20h] ; Pickup time slice value
  51. ADD r2,r2,#1 ; Increment the scheduled count
  52. STR r2,[r0, #1ch] ; Store new scheduled count
  53. ; Check for time slice option.
  54. ; if (thread -> tc_cur_time_slice)                                                                                     //确认time_slice
  55. ; {
  56. CMP r3,#0 ; Is there a time slice?
  57. BEQ TCT_No_Start_TS_1 ; If 0, there is no time slice                                                           //如果是0,表明没有。time slice没有运行
  58. ; Start a time slice.
  59. ; TMD_Time_Slice = thread -> tc_cur_time_slice;
  60. ; TMD_Time_Slice_State = 0;
  61. LDR r2,Time_Slice ; Pickup address of TMD_Time_Slice                                                          //获取time slice
  62. LDR r1,Slice_State ; Pickup address of                                                                        //获取time slice state
  63. ; TMD_Time_Slice_State
  64. STR r3,[r2, #0] ; Setup the time slice                                                                        //设置time slice
  65. MOV r2,#0 ; Build active state flag                                                                           //置0
  66. STR r2,[r1,#0] ; Set the active flag                                                                          //设置活动标志
  67. ; }
  68. TCT_No_Start_TS_1:                                                                                                    //这里是TCT_No_Start_TS_1
  69. .if $$isdefed("INCLUDE_PROVIEW")                                                                                  //如果定义了INCLUDE_PROVIEW
  70. ; Nucleus ProView Hook
  71. STR r0,[r13, #-4]! ; Save r0 on the stack                                                                    //把r0压入栈
  72. BL __NU_Schedule_Task_Hook ; Branch to RTView                                                                //跳转到__NU_Schedule_Task_Hook
  73. LDR r0,[r13], #4 ; Recover return address
  74. .endif
  75. ; Pickup the stack pointer and resume the thread.
  76. ; REG_Stack_Ptr = thread -> tc_stack_pointer;
  77. 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学习的更多相关文章

  1. nucleus 学习 中断

    ;************************************************************************ ;* ;* FUNCTION ;* ;* INT_I ...

  2. nucleus plus代码学习

    int.S: ;************************************************************************ ;* ;* FUNCTION ;* ; ...

  3. nucleus plus学习总结

    前言:     最近一直都在看nucleus plus,之前看过一些linux内核的一些东西,但都是停留在文字上,代码看的很少,这个nucleus plus内核的代码量不大,看过source code ...

  4. nucleus plus学习总结(后续)

    前言:     刚刚抽筋点了保存发布,结果要审核,那就分开写个续好了. 内容: signal     信号是异步通知task的一种机制,HISR是不可以接收信号的,但是可以发送信号.     TCB中 ...

  5. Android 学习资料收集

    收集整理这份资料灵感来自于 trip_to_iOS, 征得同意引用了该资料的开头描述 收集整理这份资料主要帮助初学者学习 Android 开发, 希望能快速帮助到他们快速入门, 找到适合自己学习资料, ...

  6. Teaching Machines to Understand Us 让机器理解我们 之二 深度学习的历史

    Deep history 深度学习的历史 The roots of deep learning reach back further than LeCun’s time at Bell Labs. H ...

  7. 吴恩达-coursera-机器学习-week4

    第八.神经网络:表述(Neural Networks: Representation) 8.1 非线性假设 8.2 神经元和大脑 8.3 模型表示1 8.4 模型表示2 8.5 样本和直观理解1 8. ...

  8. Nucleus PLUS简单介绍

    近些年来,随着嵌入式系统飞速的发展,嵌入式实时操作系统广泛地应用在制造工业.过程控制.通讯.仪器仪表.汽车.船舶.航空航天.军事.装备.消费类产 品等方面.今天嵌入式系统带来的工业年产值超过了1万亿美 ...

  9. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

随机推荐

  1. puppet(一种Linux、Unix、windows平台的集中配置管理系统)

    puppet是一种Linux.Unix.windows平台的集中配置管理系统,使用自有的puppet描述语言,可管理配置文件.用户.cron任务.软件包.系统服务等.puppet把这些系统实体称之为资 ...

  2. AT2705 Yes or No(组合数学)

    传送门 解题思路 首先将这个模型放到坐标轴上,\(x\)轴表示\(1\),\(y\)轴表示\(0\).问题就转化成了从\((0,0)\)走到\((n,m)\),每次可以猜测向\(x\)轴或向\(y\) ...

  3. window安装nexus和配置

    原文 http://www.cnblogs.com/fxmemory/p/7133672.html 一. 认识mav仓库 1.1 maven仓库的作用   回想之前不用maven的时候,我们用ecli ...

  4. nodejs环境安装

    centos7安装nodejs环境 原文地址: https://www.cnblogs.com/MY0101/p/6625344.html 下载地址: https://nodejs.org/dist/ ...

  5. 从单片机到系统之--uboot启动arm linux

    UBOOT官网下载地址:http://ftp.denx.de/pub/u-boot/ 很详细的UBOOT解释: https://www.crifan.com/files/doc/docbook/ubo ...

  6. 使用 jQuery 实现 radio 的选中与反选

    使用 jQuery 实现 radio 的选中与反选 我们知道在 Html 中当我们选中一个radio后,再次点击该 radio,那么该 radio 依然是一个选中的状态,但是有时我们需要实现这样的逻辑 ...

  7. 建议66,67 注意Arrays.asList()的使用

    代码 public static void main(String[] args) { int[]data = {1,2,3,4,5}; List list = Arrays.asList(data) ...

  8. day 97 VUE第一天

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  9. 报警插件Alertmanager 安装与使用

    Alertmanager是一个独立的告警模块,接收Prometheus等客户端发来的警报,之后通过分组.删除重复等处理,并将它们通过路由发送给正确的接收器:告警方式可以按照不同的规则发送给不同的模块负 ...

  10. 后台获取html控件的值

    string name = Request.Form["Name1"].ToString(); “xxx” 里的是name值 Request["xx"]取到相同 ...