为什么要设置PendSV为最低优先级? 应用程序执行SVC 时都是希望所需的请求立即得到响应。 PendSV 则不同,它是可以像普通的中断一样被抢占挂起的(不像SVC 那样会上访)。 操作系统 可以利用它“缓期执行”一个异常,一直到其它重要的任务完成后才执行动作。 PendSV是为系统设备而设的“可悬挂请求”(pendable request)。 1)上下文切换 不能在中断中进行,会导致中断延期。为了解决这个问题,使用 PendSV。PendSV可以挂起,也就是等到别的 ISR结束后缓期执行。 2)为了实现缓期执行PendSV,PendSV一定要被设置为最低优先级的异常
如何设置PendSV? 看下图,对于系统异常,可编程的在编号4—15: 对于PendSV存储优先级的这个字节,其地址在0XE000_ED22,而寄存器的地址在0XE000_ED20,因此要做一些左移位操作 下图可知,是stm32f1X用了4个位来分配抢占优先级和子优先级 下图可知,configLIBRARY_LOWEST_INTERRUPT_PRIORITY为15 ,因为分组是4,即4个位都作为抢占优先级,有0—15,在中断中,数字越小优先级越高,所以15这个数字是最低优先级,用十六进制表示就是0x0000 000f。 对于configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS),_其中NVIC_PRIO_BITS 为4 ,所以就是configLIBRARY_LOWEST_INTERRUPT_PRIORITY <<4,也就是15<<4即 0x0000 000f<<4,结果为0x0000 00f0,即移到了最低字节的最高4位。 那么configKERNEL_INTERRUPT_PRIORITY=0x0000 00f0; 下图可知, ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) 左移16位后取别名portNVIC_PENDSV_PRI,代表0x 00f0 0000 ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY )左移24位后取别名 portNVIC_SYSTICK_PRI,代表0x f000 0000
再看下图:portNVIC_SYSPRI2_REG分别和portNVIC_PENDSV_PRI,portNVIC_SYSTICK_PRI按位或,这就是置位,即把优先级15写入对应的字节,0XE000_ED22(PendSV)处和0XE000_ED23(sysTick)处, 因为采用的是小端存储,即高地址对应高字节,低地址对应低字节,如下图