Nucleus源代码分析 - Task(1)

Task的创建与调度

Nucleus的系统入口函数是

  1. VOID  INC_Initialize(VOID  *first_available_memory)  
  2. {  
  3.   
  4. 。。。。。。。。  
  5. /* Invoke the application-supplied initialization function.  */  
  6. Application_Initialize(first_available_memory);  
  7.   
  8. /* Indicate that initialization is finished.  */  
  9. INC_Initialize_State =  INC_END_INITIALIZE;  
  10.   
  11. /* Start scheduling threads of execution.  */  
  12. TCT_Schedule();  
  13. }  

Application_Initialize(first_available_memory);这个函数是留给平台用来初始化系统框架和创建task用的。
Task的创建一般如下

  1. if ( NU_Create_Task (&TaskTable[Handle].TaskCB.TCB, Name, os_TaskEntry,  
  2. Handle, (VOID *)NULL,  
  3. (void*)(TaskTable[Handle].Stack+1), (ULONG) StackSize, (UCHAR) Priority,  
  4. #ifndef _TARGET_  
  5. 10,  
  6. #else  
  7. 0,  
  8. #endif  
  9. NU_PREEMPT, NU_NO_START) != NU_SUCCESS )  
  10. #define         NU_Resume_Task                  TCCE_Create_Task  

最关键的实现是

  1.    status =  TCC_Create_Task(task_ptr, name, task_entry, argc, argv,  
  2.          stack_address, stack_size, priority, time_slice, preempt, auto_start);  
  3. ……  
  4.     /* Move input task pointer into internal pointer.  */  
  5. task =  (TC_TCB *) task_ptr;  
  6.     /* Move input task pointer into internal pointer.  */  
  7. task =  (TC_TCB *) task_ptr;  
  8.  …  
  9. 填充TC_TCB结构体..  
  10.     /* Build a stack frame for this task by calling TCT_Build_Task_Stack.  */  
  11.     TCT_Build_Task_Stack(task);  
  12.   
  13. 这个函数是根据arm平台thumb模式下填充arm的15个寄存器。  
  14.     ; Build an initial stack frame as follows:  
  15.     ;  
  16.     ;     (Lower Address) Stack Top ->    1       (Interrupt stack type)  
  17.     ;                                     CPSR    Saved CPSR  
  18.     ;                                     r0      Saved r0  
  19.     ;                                     r1      Saved r1  
  20.     ;                                     r2      Saved r2  
  21.     ;                                     r3      Saved r3  
  22.     ;                                     r4      Saved r4  
  23.     ;                                     r5      Saved r5  
  24.     ;                                     r6      Saved r6  
  25.     ;                                     r7      Saved r7  
  26.     ;                                     r8      Saved r8  
  27.     ;                                     r9      Saved r9  
  28.     ;                                     r10     Saved r10  
  29.     ;                                     r11     Saved r11  
  30.     ;                                     r12     Saved r12  
  31.     ;                                     sp      Saved sp  
  32.     ;                                     lr      Saved lr  
  33.     ;     (Higher Address) Stack Bottom-> pc      Saved pc  
  34.   
  35.     /* Initialize the signal information of the task.  */  
  36.     task -> tc_signals =                0;  
  37.     task -> tc_enabled_signals =        0;  
  38.     task -> tc_signal_handler =         0;  
  39.     task -> tc_signal_active =          NU_FALSE;  
  40.     /* Initialize additional kernel options data */  
  41.   
  42. #if (NU_SUPERV_USER_MODE == 1)  
  43.     task->tc_su_mode = 0;              /* Initially in User mode */  
  44.     task->tc_module = 0;               /* Not initially bound to a module */  
  45. #endif  
  46.   
  47. 在初始化该task的timer  
  48.   
  49.     /* Initialize the task timer.  */  
  50.     task -> tc_timer_active =           NU_FALSE;  
  51.     TMC_Init_Task_Timer(&(task -> tc_timer_control), (VOID *) task);  
  52.   
  53.     /* Protect the list of created tasks.  */  
  54.     TCT_Protect(&TCD_List_Protect);  
  55.   
  56.     /* At this point the task is completely built.  The ID can now be 
  57.        set and it can be linked into the created task list.  */  
  58.     task -> tc_id =                     TC_TASK_ID;  
  59.   
  60. 将task放到相应的list中  
  61.     /* Link the task into the list of created tasks and increment the 
  62.        total number of tasks in the system.  */  
  63.     CSC_Place_On_List(&TCD_Created_Tasks_List, &(task -> tc_created));  
  64.     TCD_Total_Tasks++;  
  65. 如果创建参数是需要自动运行的,就通过resume来start task。  
  66. .......  

Nucleus的task调度

  1. ;VOID  TCT_Schedule(VOID)  
  2.   
  3. .def    _TCT_Schedule  
  4. _TCT_Schedule  
  5. …..  
  6. ; Get the addresses of the HISR and Task to execute  
  7.   
  8. LDR     r2,TCT_Execute_HISR  
  9. //TCT_Execute_HISR是已经准备好需要运行的HISR  
  10. LDR     r3,TCT_Execute_Task  
  11. //TCT_Execute_Task是已经准备好需要运行的Task  
  12. .if NU_PROFILE_PLUS  
  13.   
  14. ; Check to see if there is a task to execute upon entering TCT_Schedule.  
  15. ; If not, we start IDLE.  
  16. //先查询是否有HISR需要运行,其运行是同task一样的流程  
  17. LDR     r0,[r2]                         ; Pickup highest priority HISR ptr  
  18. CMP     r0,#0                           ; Is there a HISR active?  
  19. BNE     TCT_Schedule_Thread             ; Found an HISR  
  20. //如果没有HISR需运行,就查询task。  
  21. LDR     r0,[r3]                         ; Pickup highest priority Task ptr  
  22. CMP     r0,#0                           ; Is there a task active?  
  23. BNE     TCT_Schedule_Thread             ; If not, start IDLE.  
  24. //如果也没有就开始loop,一直查询.  
  25. STMDB   sp!,{r2-r3}                     ; Save r2-r3  
  26. BL      __NU_Idle_Hook  
  27. LDMIA   sp!,{r2-r3}                     ; Restore r2-r3  
  28.   
  29. .endif  
  30.   
  31. .def    TCT_Schedule_Loop  
  32. TCT_Schedule_Loop  
  33.   
  34. ; Wait until a thread (task or HISR) is available to execute.  
  35. ; When a thread is available, branch to TCT_Schedule_Thread.  
  36.   
  37. LDR     r0,[r2]                         ; Pickup highest priority HISR ptr  
  38. CMP     r0,#0                           ; Is there a HISR active?  
  39. BNE     TCT_Schedule_Thread             ; Found a HISR  
  40. LDR     r0,[r3]                         ; Pickup highest priority Task ptr  
  41.   
  42. CMP     r0,#0                           ; Is there a task active?  

TCT_Schedule_Thread中主要是调用TCT_Control_To_Thread
TCT_Control_To_Thread先判断该task的时间片是否为0,然后设置时间片状态。

  1. ; Pickup the thread's stack pointer and resume the thread.  
  2.   
  3. LDR     sp,[r0, #TC_STACK_POINTER]  
  4.   
  5. ; Pop off the stack top to determine stack type  
  6.   
  7. LDR     r1,[sp], #4  
  8.   
  9. ; Remove CPSR from stack and put in SPSR  
  10.   
  11. LDR     r0,[sp], #4                     ; Pop off the CPSR  
  12. MSR     SPSR,r0                         ; Place it into the SPSR  
  13. //以上偏移是根据创建时的各个位的定义  
  14. ; Check if interrupt stack or solicited stack  
  15. //r1此时存的为上次中断的类型  
  16. CMP     r1,#1                           ; Compare stack type with 1  
  17. BEQ     TCT_Interrupt_Resume            ; If equal to 1, interrupt stack frame  
  18.   
  19. ; Recover all solicited stack frame registers and return  
  20. //将task堆栈中存的上次中断时arm的各个寄存器的值复位就恢复了task的运行,和被中断前一样  
  21. LDMIA   sp!,{r4-r12,pc}^                ; A solicited return is required.  
  22. ; This type of return only  
  23. ; Recovers r4-r12 & pc  
  24. TCT_Interrupt_Resume  
  25.   
  26. ; Recover all registers and resume at point of interrupt  
  27.   
  28. LDMIA   sp,{r0-pc}^  
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值