从这篇文章开始,就是真正去了解FreeRTOS内部较为复杂的运行模式了。可能会比较乱,请耐心观看。
首先作者认为一切的源头要从这个xPortSysTickHandler
开始说起,那么这个中断在32版本的例程中是存在于滴答定时器中断SysTick_Handler
中的,在vivado sdk的freertos源码例程中存在于zynq创建的软件定时器中断中(绑定软件定时器中断即为FreeRTOS的中断)。当然,在不同的版本中,这个中断的名字不一样,32的例程中叫做xPortSysTickHandler
,zynq的例程中叫做FreeRTOS_Tick_Handler
,不管是什么版本,他都应该在你为FreeRTOS提供时基的那个定时器中断里。源码如下:
//M4
void xPortSysTickHandler( void )
{
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
executes all interrupts must be unmasked. There is therefore no need to
save and then restore the interrupt mask value as its value is already
known - therefore the slightly faster vPortRaiseBASEPRI() function is used
in place of portSET_INTERRUPT_MASK_FROM_ISR(). */
vPortRaiseBASEPRI();
{
/* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
{
/* A context switch is required. Context switching is performed in
the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
}
vPortClearBASEPRIFromISR();
}
//A9
void FreeRTOS_Tick_Handler( void )
{
/* Set interrupt mask before altering scheduler structures. The tick
handler runs at the lowest priority, so interrupts cannot already be masked,
so there is no need to save and restore the current mask value. It is
necessary to turn off interrupts in the CPU itself while the ICCPMR is being
updated. */
portCPU_IRQ_DISABLE();
portICCPMR_PRIORITY_MASK_R