/* * See header file for description. */ portBASE_TYPE xPortStartScheduler( void ) { /* Make PendSV, CallSV and SysTick the same priroity as the kernel. */ *(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; }
BaseType_t xPortStartScheduler( void ) { /* Setup the hardware to generate the tick. Interrupts are disabled when this function is called. */ configSETUP_TICK_INTERRUPT(); /* Restore the context of the first task that is going to run. */ vPortStartFirstTask(); /* Execution should not reach here as the tasks are now running! prvSetupTimerInterrupt() is called here to prevent the compiler outputting a warning about a statically declared function not being referenced in the case that the application writer has provided their own tick interrupt configuration routine (and defined configSETUP_TICK_INTERRUPT() such that their own routine will be called in place of prvSetupTimerInterrupt()). */ prvSetupTimerInterrupt(); return pdTRUE; }
/*-----------------------------------------------------------*/ BaseType_t xPortStartScheduler(void) { /* Make PendSV, SVCall and SysTick the lowest priority interrupts. SysTick priority will be set in vPortInitTickTimer(). */ #if 0 /* do NOT set the SVCall priority */ /* why: execution of an SVC instruction at a priority equal or higher than SVCall can cause a hard fault (at least on Cortex-M4), see https://community.freescale.com/thread/302511 */ *(portNVIC_SYSPRI2) |= portNVIC_SVCALL_PRI; /* set priority of SVCall interrupt */ #endif *(portNVIC_SYSPRI3) |= portNVIC_PENDSV_PRI; /* set priority of PendSV interrupt */ uxCriticalNesting = 0; /* Initialize the critical nesting count ready for the first task. */ vPortInitTickTimer(); /* initialize tick timer */ vPortStartTickTimer(); /* start tick timer */ #if configCPU_FAMILY==configCPU_FAMILY_ARM_M4F /* floating point unit */ vPortEnableVFP(); /* Ensure the VFP is enabled - it should be anyway */ *(portFPCCR) |= portASPEN_AND_LSPEN_BITS; /* Lazy register save always */ #endif vPortStartFirstTask(); /* Start the first task. */ /* Should not get here, unless you call vTaskEndScheduler()! */ return pdFALSE; }
/* * See header file for description. */ portBASE_TYPE xPortStartScheduler( void ) { /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Start the first task. */ vPortStartFirstTask(); /* Should not get here! */ return 0; }
portBASE_TYPE xPortStartScheduler( void ) { extern void vPortStartFirstTask( void ); extern void *pxCurrentTCB; /* Setup the software interrupt. */ mConfigIntCoreSW0( CSW_INT_ON | CSW_INT_PRIOR_1 | CSW_INT_SUB_PRIOR_0 ); /* Setup the timer to generate the tick. Interrupts will have been disabled by the time we get here. */ prvSetupTimerInterrupt(); /* Kick off the highest priority task that has been created so far. Its stack location is loaded into uxSavedTaskStackPointer. */ uxSavedTaskStackPointer = *( unsigned portBASE_TYPE * ) pxCurrentTCB; vPortStartFirstTask(); /* Should never get here as the tasks will now be executing. */ return pdFALSE; }
BaseType_t xPortStartScheduler( void ) { extern void vPortStartFirstTask( void ); extern void *pxCurrentTCB; #if ( configCHECK_FOR_STACK_OVERFLOW > 2 ) { /* Fill the ISR stack to make it easy to asses how much is being used. */ memset( ( void * ) xISRStack, portISR_STACK_FILL_BYTE, sizeof( xISRStack ) ); } #endif /* configCHECK_FOR_STACK_OVERFLOW > 2 */ /* Clear the software interrupt flag. */ IFS0CLR = _IFS0_CS0IF_MASK; /* Set software timer priority. */ IPC0CLR = _IPC0_CS0IP_MASK; IPC0SET = ( configKERNEL_INTERRUPT_PRIORITY << _IPC0_CS0IP_POSITION ); /* Enable software interrupt. */ IEC0CLR = _IEC0_CS0IE_MASK; IEC0SET = 1 << _IEC0_CS0IE_POSITION; /* Setup the timer to generate the tick. Interrupts will have been disabled by the time we get here. */ vApplicationSetupTickTimerInterrupt(); /* Kick off the highest priority task that has been created so far. Its stack location is loaded into uxSavedTaskStackPointer. */ uxSavedTaskStackPointer = *( UBaseType_t * ) pxCurrentTCB; vPortStartFirstTask(); /* Should never get here as the tasks will now be executing! Call the task exit error function to prevent compiler warnings about a static function not being called in the case that the application writer overrides this functionality by defining configTASK_RETURN_ADDRESS. */ prvTaskExitError(); return pdFALSE; }
/* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { /* 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 never get here as the tasks will now be executing! Call the task exit error function to prevent compiler warnings about a static function not being called in the case that the application writer overrides this functionality by defining configTASK_RETURN_ADDRESS. */ prvTaskExitError(); /* Should not get here! */ return 0; }
/* * See header file for description. */ BaseType_t xPortStartScheduler( void ) { #if( configASSERT_DEFINED == 1 ) { volatile uint32_t ulOriginalPriority; volatile uint8_t * const pucFirstUserPriorityRegister = ( uint8_t * ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); volatile uint8_t ucMaxPriorityValue; /* Determine the maximum priority from which ISR safe FreeRTOS API functions can be called. ISR safe functions are those that end in "FromISR". FreeRTOS maintains separate thread and ISR API functions to ensure interrupt entry is as fast and simple as possible. Save the interrupt priority value that is about to be clobbered. */ ulOriginalPriority = *pucFirstUserPriorityRegister; /* Determine the number of priority bits available. First write to all possible bits. */ *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; /* Read the value back to see how many bits stuck. */ ucMaxPriorityValue = *pucFirstUserPriorityRegister; /* Use the same mask on the maximum system call priority. */ ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; /* Calculate the maximum acceptable priority group value for the number of bits read back. */ ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) { ulMaxPRIGROUPValue--; ucMaxPriorityValue <<= ( uint8_t ) 0x01; } /* Shift the priority group value back to its position within the AIRCR register. */ ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; /* Restore the clobbered interrupt priority register to its original value. */ *pucFirstUserPriorityRegister = ulOriginalPriority; } #endif /* conifgASSERT_DEFINED */ /* Make PendSV and SysTick the lowest priority interrupts. */ portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI; portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI; /* Start the timer that generates the tick ISR. Interrupts are disabled here already. */ vPortSetupTimerInterrupt(); /* Initialise the critical nesting count ready for the first task. */ uxCriticalNesting = 0; /* Ensure the VFP is enabled - it should be anyway. */ vPortEnableVFP(); /* Lazy save always. */ *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS; /* Start the first task. */ vPortStartFirstTask(); /* Should not get here! */ return 0; }