关于PendSV异常和SVC异常

  • Post author:
  • Post category:其他

这里先说什么是异常,什么是中断?请下这张图

颜色加深的表项为异常,这些属于cm3内核自带的。其中-3,-2,-1异常的优先级固定,是不可更改的,其余的异常中断优先级可以设置。

颜色未加深的表项为中断,这些属于stm32带出的。优先级 可设置。表格最前面的数字用来记录是第几个中断。

PendSv:可悬挂异常。如果当前没有更高优先级的异常或者中断需要执行,那么就执行pendsv的异常服务函数。 可以看出它有个特点,就是 缓期执行。cpu先执行比它高的服务函数,然后在执行它,

OS 可以利用它“缓期执行”一个异常——直到其它重要的任务完成后才执行动 作。悬起 PendSV 的方法是:手工往 NVIC的 PendSV悬起寄存器中写 1。悬起后,如果优先级不够 高,则将缓期等待执行。

FreeRTOS就是利用了这个特性,来显示 任务切换的。请看下面systick异常中断服务函数的内容

void xPortSysTickHandler( void )
{
	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();
}

vPortRaiseBASEPRI();设置basepri寄存器,开启中断屏蔽作用,这里是大于等于5的优先级异常和中断都将被屏蔽。

portNVIC_INT_CTRL_REG=portNVIC_PENDSVSET_BIT就是悬起PendSv。

然后清除中断屏蔽 中断位,退出systick服务函数。

FreeRTOS为什么要这样延后切换, 而不是直接进行任务切换呢?因为任务切换的时间 开销较大,这样会导致其他中断迟迟不能执行。

 

SVC:系统服务异常。用户级想操作一些特权级的操作,是不可行的。假如修改底层寄存器的值是特权级操作,用户想修改底层的寄存器怎么办呢?方法就是用这个SVC 异常。OS会提供一些系统服务函数,用户调用这些服务函数,OS会发出SVC异常,从而进入异常服务函数里面, 再调用相关函数对寄存器进行 修改。如下图。

更多具体内容可以看这篇文章http://blog.sina.com.cn/s/blog_13e68b0390102xgrh.html

 

 


版权声明:本文为tangjienihaoma原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。