<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /> 2009-5-10   
       作为 main 函数中的最后一个重量级函数 vTaskStartScheduler 。今天就在这里做个了断吧!
       原来如此,这个函数一上来二话不啰嗦,直接 create 了一个 task ,嗯,就是大名鼎鼎的 idletask
xReturn = xTaskCreate( prvIdleTask, ( signed portCHAR * ) "IDLE", tskIDLE_STACK_SIZE, ( void * ) NULL, tskIDLE_PRIORITY, ( xTaskHandle * ) NULL );
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

       按理说在创建完 idletask 之后就应该直接 startscheduler 了,但是,这里还有很重要的一些动作还没有表演完。 Interrupts are turned off here, to ensure a tick does not occur before or during the call to xPortStartScheduler().The stacks of the created tasks contain a status word with interrupts switched on so interrupts will automatically get re-enabled when the first task starts to run. 嗯,就是这个,所以下面紧接着的是
portDISABLE_INTERRUPTS();// 对,这个也是平台相关的
#define portDISABLE_INTERRUPTS()   vPortSetInterruptMask()// 很明显这个是要平台来实现的了】

xSchedulerRunning = pdTRUE;
xTickCount = ( portTickType ) 0;
很正点的语句,且不可或缺!

 

       接下来才是主角的登场。 portBASE_TYPE xPortStartScheduler( void )
这个函数依然是平台相关的,从函数名也可以看出来的。具体实现在个平台下的 port.c 中。
portBASE_TYPE xPortStartScheduler( void )

{

       /* Make PendSV and SysTick the lowest priority interrupts. */

       *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;

       *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;

 

       /* Start the timer that generates the tick ISR.  Interrupts are disabled

       here already. */

       prvSetupTimerInterrupt();

      

       /* Initialise the critical nesting count ready for the first task. */

       uxCriticalNesting = 0;

 

       /* Start the first task. */

       vPortStartFirstTask();

 

       /* Should not get here! */

       return 0;

}

这个是 iar/arm_cm3 的实现,注释很详细,在此不多说了。还是说说最后的那个函数调用吧
void vPortStartFirstTask( void )
{
       asm volatile(
                     " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */
                     " ldr r0, [r0]                 \n"
                     " ldr r0, [r0]                 \n"
                     " msr msp, r0               \n" /* Set the msp back to the start of the stack. */
                     " svc 0                         \n" /* System call to start first task. */
              );
}
这就是精华,看来是要好好研究研究 arm 的汇编啊!