任务切换
进程栈指针 PSP
1:任务切换就是在就绪列表中寻找优先级最高的就绪任务,然后去执行该任务,但是现在编写的还不支持优先级,仅实现两个任务的轮流切换
2:任务切换具体过程是在PendSV中断服务函数中完成的,只需将ICSR寄存器bit28置1就能引起PendSV中断,PendSV具体内容参考M3权威指南
3:任务切换一般都是调用portYIELD这个函数还有一个中断中的portYIELD_FROM_ISR( x )
4:上下文(任务)切换场合:
1)可以执行一个系统调用,比如:vTaskDelay->portYIELD_WITHIN_API->portYIELD
2)系统滴答定时器中断
5:xPortPendSVHandler中断服务函数是真正实现任务切换的地方
1)保存当前寄存器值到任务堆栈中
2)调用函数 vTaskSwitchContext(),此函数用来获取下一个要运行的任务,并将pxCurrentTCB 更新为这个要运行的任务
6: vTaskSwitchContext查找下一个要运行的任务
#define taskYIELD() portYIELD() //任务切换的本质就是将PendSV的悬起位置1,当没有其他中断运行的时候相应PendSV中断,去执行PendSV中断服务函数,在里面实现任务切换
#define portYIELD() \
{
\
/* Set a PendSV to request a context switch. #define portNVIC_PENDSVSET_BIT ( 1UL << 28UL ) */ \
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. */ \
__dsb( portSY_FULL_READ_WRITE ); \
__isb( portSY_FULL_READ_WRITE ); \
}
中断服务函数是真正实现任务切换的地方
#define xPortPendSVHandler PendSV_Handler
__asm void xPortPendSVHandler( void )