RT-Thread系统的SysTick和pendSV的中断优先级

问题描述:

SysTick和pendSV的中断优先级分别设置为0和15。
SysTick中断用于系统心跳。
pendSV中断用于任务调度。

代码证明:

RT-Thread中设置pendSV中断优先级的代码在cpu文件夹下context_rvds.S的汇编部分,中断优先级设置为15,代码如下:
其中
RT-Thread系统的SysTick和pendSV的中断优先级_第1张图片
汇编代码解释如下:

; set the PendSV exception priority设置PendSV的中断优先级
    LDR     r0, =NVIC_SYSPRI2 ;r0中加载中断优先级寄存器2的地址
    LDR     r1, =NVIC_PENDSV_PRI ; r1中加载设置PendSV中断为低优先级的数据地址
    LDR.W   r2, [r0,#0x00]       ; 读取r0中断优先级寄存器2地址上的数据,存入r2
    ORR     r1,r1,r2             ; r2与r1相或的结果存入r1中
    STR     r1, [r0]             ; 设置PendSV中断优先级为低优先级

查阅手册得知:
PendSV优先级设置寄存器地址为0xe000ed22
SysTick优先级设置寄存器地址为0xe000ed23

这段代码的意思是读取地址为0xe000ed20的连续四个字节的值或上0X00FF0000,然后给0xe000ed20这个地址赋值。
假如首地址为0xe000ed20的连续四个字节的值为0x00000000,那么0xe000ed20地址上的值为0X00,0xe000ed21地址上的值为0X00,0xe000ed22地址上的值为0XFF,0xe000ed23地址上的值为0X00。

SysTick的中断优先级设置在Drivers文件夹下的drv_common.c,优先级设置为0,代码如下:
RT-Thread系统的SysTick和pendSV的中断优先级_第2张图片
程序中两个优先级设置顺序:
RT-Thread系统的SysTick和pendSV的中断优先级_第3张图片
在rtthread_startup()中先调用rt_hw_board_init()设置了systic的优先级(根据参数设置中断优先级寄存器2),后调用rt_system_scheduler_start()函数设置pendSV优先级(如果在汇编中设置了中断优先级寄存器2的高四位值,使systic的优先级低于在rt_hw_board_init()设置的systic的优先级,这段汇编代码会改变systic的优先级为更低优先级,否则不会改变systic的优先级)在调度器启动第一个线程的时候调用rt_hw_context_switch_to()这个函数,进入的汇编代码,改了优先级,调度器启动以后就不会再改变优先级了。

总结为SysTick和pendSV的中断优先级分别设置为0和15,通过MDK软件仿真证明如下:
RT-Thread系统的SysTick和pendSV的中断优先级_第4张图片

中断优先级设置逻辑:

SysTick系统嘀嗒定时器是Cortex内核的部分,尤其对于有实时操作系统的软件,它一般会作为整个系统的时基,所以这个对操作系统非常重要。
在NVIC 有一个专门的寄存器:中断优先级寄存器NVIC_IPRx(在F429 中,x=0…90)用来配置外部中断的优先级,IPR 宽度为8bit,原则上每个外部中断可配置的优先级为
0~255,数值越小,优先级越高。但是绝大多数CM4 芯片都会精简设计,以致实际上支持的优先级数减少,在M4中,只使用了高4bit,如下所示:
在这里插入图片描述
优先级的分组由内核外设SCB 的应用程序中断及复位控制寄存器AIRCR 的PRIGROUP[10:8]位决定,使用NVIC_PriorityGroupConfig()实现:
RT-Thread系统的SysTick和pendSV的中断优先级_第5张图片
优先级设置有HAL_NVIC_SetPriority()函数实现。
中断分为内核中断和外设的中断,配置的寄存器位置不同。外设的中断配置在NVIC的IP内,内核的中断配置在SCB内。

更改SysTick的中断优先级的方法:

1.把汇编部分的NVIC_PENDSV_PRI EQU 0x00FF0000 改为 NVIC_PENDSV_PRI EQU 0xF0F00000 ;这样就可以在第一次启动任务调度的时候把SysTick和pendSV的中断优先级一起改为15。
在这里插入图片描述
2.优先级设置有HAL_NVIC_SetPriority(),更改其中的参数
RT-Thread系统的SysTick和pendSV的中断优先级_第6张图片
在程序运行到rt_system_scheduler_start()时会调用rt_hw_context_switch_to()这个函数进入汇编,如果在汇编中设置了中断优先级寄存器2的高四位值,使systic的优先级低于在HAL_NVIC_SetPriority()设置的systic的优先级,这段汇编代码会改变systic的优先级为更低优先级,否则不会改变systic的优先级。

你可能感兴趣的:(RT-Thread)