portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } portENABLE_INTERRUPTS(); } xTaskIncrementTick 以设定频率增加计数,处理延时任务。 BaseType_t xTaskIncrementTick( void ) { TCB_t * pxTCB; TickType_t xItemValue; BaseType_t xSwitchRequired = pdFALSE; if( uxSchedulerSuspended == ( UB...
无论portYIELD_FROM_ISR( x )还是portYIELD_WITHIN_API()最终都是通过portYIELD() 函数实现任务切换。 portNVIC_INT_CTRL_REG 是内存为0xE000_ED04的指针,portNVIC_PENDSVSET_BIT是1左移28位。 通过portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;这条命令触发PendSV事件。 PendSV中断服务函数xPortPendSVHa...
1.1 portYIELD #defineportNVIC_INT_CTRL_REG ( *( ( volatile uint32_t * ) 0xe000ed04 ) ) 在Cortex M3与M4权威指南的7.9.1有关于该寄存器的描述,该寄存器处于系统控制块(SCB)中,CMSIS-Core符号为SCB->ICSR,系统异常的控制和状态。 每一位的描述如下图所示: #defineportNVIC_PENDSVSET_BIT ( 1UL <...
vPortRaiseBASEPRI(); //关闭中断 { if( xTaskIncrementTick() != pdFALSE ){ //增加时钟计数器xTickCount的值 /* 通过向中断控制和状态寄存器的bit28位写入1挂起PendSV来启动PendSV中断 */ portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; } } vPortClearBASEPRIFromISR(); //打开中断 } 1. 2. ...
5vPortRaiseBASEPRI();//关中断6{7if( xTaskIncrementTick() != pdFALSE )//判断返回值,如果为pdTURE就要进行一次上下文切换8{9portNVIC_INT_CTRL_REG =portNVIC_PENDSVSET_BIT;10}11}12vPortClearBASEPRIFromISR();//开中断13} 为了保证计数的正常执行,需要先关闭系统中断,但是值得注意的是,FreeRTOS系统可...
portNVIC_INT_CTRL_REG=portNVIC_PENDSVSET_BIT;\ \/* 触发PendSV,产生上下文切换 */\__dsb(portSY_FULL_READ_WRITE);\__isb(portSY_FULL_READ_WRITE);\} portYIELD()任务切换函数,主要就是将PendSV的悬起位置1,在没有其它中断运行时执行PendSV中断服务函数,在这个中断函数中实现任务切换。
在port.c 文件中找到 vPortEnterCritical() 和 vPortExitCritical() 函数的实现: void vPortEnterCritical( void ) { portDISABLE_INTERRUPTS(); uxCriticalNesting++; if( uxCriticalNesting == 1 ) { configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 ); ...
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT; \ \ /* 触发PendSV,产生上下文切换 */ \ __dsb( portSY_FULL_READ_WRITE ); \ __isb( portSY_FULL_READ_WRITE ); \ } 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ...
portNVIC_INT_CTRL_REG=portNVIC_PENDSVSET_BIT;\ \/* Barriers are normally not required but do ensure the code is completely \ * within the specified behaviour for the architecture. */\ __asmvolatile("dsb":::"memory");\ __asmvolatile("isb");\} ...
portNVIC_INT_CTRL_REG=portNVIC_PENDSVSET_BIT;//步骤1 __dsb(portSY_FULL_READ_WRITE); __isb(portSY_FULL_READ_WRITE); } 步骤1表示通过向中断控制和状态寄存器ICSR的bit28写入1挂起PendSV来启动PendSV中断。这样就可以在PendSV中断服务函数中进行任务切换了。