颜色加深的表项为异常,这些属于cm3内核自带的。其中-3,-2,-1异常的优先级固定,是不可更改的,其余的异常中断优先级可以设置。
颜色未加深的表项为中断,这些属于stm32带出的。优先级 可设置。表格最前面的数字用来记录是第几个中断。
用户级想操作一些特权级的操作,是不可行的。假如修改底层寄存器的值是特权级操作,用户想修改底层的寄存器怎么办呢?方法就是用这个SVC 异常。
OS会提供一些系统服务函数,用户调用这些服务函数,OS会发出SVC异常,从而进入异常服务函数里面, 再调用相关函数对寄存器进行 修改。
如果当前没有更高优先级的异常或者中断需要执行,那么就执行pendsv的异常服务函数。 可以看出它有个特点,就是 缓期执行。cpu先执行比它高的服务函数,然后在执行它,
OS 可以利用它“缓期执行”一个异常——直到其它重要的任务完成后才执行动 作。悬起 PendSV 的方法是:手工往 NVIC的 PendSV悬起寄存器中写 1。悬起后,如果优先级不够 高,则将缓期等待执行。
RTOS就是利用了这个特性,来显示 任务切换的。请看下面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为什么要这样延后切换, 而不是直接进行任务切换呢?因为任务切换的时间 开销较大,这样会导致其他中断迟迟不能执行。
SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。
Cortex‐M3处理器内部包含了一个简单的定时器。因为所有的CM3芯片都带有这个定时器,软件在不同 CM3器件间的移植工作得以化简。该定时器的时钟源可以是内部时钟(FCLK,CM3上的自由运行时钟),或者是外部时钟( CM3处理器上的STCLK信号)。不过,STCLK的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能会大不相同,你需要检视芯片的器件手册来决定选择什么作为时钟源。
SysTick定时器能产生中断,CM3为它专门开出一个异常类型,并且在向量表中有它的一席之地。它使操作系统和其它系统软件在CM3器件间的移植变得简单多了,因为在所有CM3产品间对其处理都是相同的。
https://blog.csdn.net/guozhongwei1/article/details/49544671?utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromMachineLearnPai2~default-1.control