0 参考资料
STM32MP13xx参考手册.pdf(RM0475)
ARM Generic Interrupt Controller Architecture version 2.0 - Architecture Specification.pdf
1 GIC配置中断效果测试
前面我们已经实现了GIC的配置,为了验证GIC是否配置有效,本例使用软件触发EXTI中断,来测试这些GIC配置的优先级位数、主优先级位数是否有效。
1.1 优先级位数测试
测试方法(测试优先级位数是否有效):
初始化GIC优先级位数为5,主优先级个数也为5,这样配置以后主优先级0-30(大于31)的中断都会响应。配置外部中断EXTI0的主优先级为0,配置外部中断EXTI1的主优先级为30,同时触发这2个软件中断查看能否正常响应。
(1)测试代码
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
switch (GPIO_Pin)
{
case GPIO_PIN_0:
printf("EXTI0 Rising\r\n");
break;
case GPIO_PIN_1:
printf("EXTI1 Rising\r\n");
break;
}
}
void EXTI0_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
void EXTI1_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
}
void gic_test_example(void)
{
int ret;
ret = gic_init(5, 5);
printf("gic init : %s\r\n", ret == 0 ? "ok" : "fail");
ret = gic_prio_config(EXTI0_IRQn, 0, 0);
printf("gic prio config 0 : %s\r\n", ret == 0 ? "ok" : "fail");
ret = gic_prio_config(EXTI1_IRQn, 30, 0);
printf("gic prio config 1 : %s\r\n", ret == 0 ? "ok" : "fail");
SET_BIT(EXTI->SWIER1, 1);
HAL_Delay(100);
SET_BIT(EXTI->SWIER1, 2);
HAL_Delay(100);
}
(2)测试结果
0-30的抢占优先级中断均能响应。
1.2 主优先级测试
测试方法(测试高主优先级中断能否抢占低主优先级中断,前面代码分析已经得出结论:无法抢占):
初始化GIC优先级位数为5,主优先级个数也为5,这样配置以后主优先级在0-30(大于31)的中断都会响应。配置外部中断EXTI0的主优先级为30,配置外部中断EXTI1的主优先级为0,首先生成外部中断EXTI0,然后在EXTI0中生成外部中断EXTI1,查看EXTI1能否抢占EXTI0执行。相关测试代码如下:
(1)测试代码
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
switch (GPIO_Pin)
{
case GPIO_PIN_0:
imx_printf("EXTI0 Rising 1\r\n");
SET_BIT(EXTI->SWIER1, 2);
HAL_Delay(10);
imx_printf("EXTI0 Rising 2\r\n");
break;
case GPIO_PIN_1:
imx_printf("EXTI1 Rising\r\n");
break;
}
}
void EXTI0_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
void EXTI1_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
}
void gic_test_example(void)
{
int ret;
ret = gic_init(5, 5);
imx_printf("gic init : %s\r\n", ret == 0 ? "ok" : "fail");
ret = gic_prio_config(EXTI0_IRQn, 10, 0);
imx_printf("gic prio config 0 : %s\r\n", ret == 0 ? "ok" : "fail");
ret = gic_prio_config(EXTI1_IRQn, 0, 0);
imx_printf("gic prio config 1 : %s\r\n", ret == 0 ? "ok" : "fail");
SET_BIT(EXTI->SWIER1, 1);
HAL_Delay(100);
}
(2)测试结果
受限于目前STM32MP135对中断的处理方式,高抢占优先级中断无法抢占已经在执行的低抢占优先级中断。
1.2 子优先级测试
测试方法(测试主优先级相同情况下,子优先级更高的能否先响应):
初始化GIC优先级位数为5,主优先级个数为3。配置外部中断EXTI0的主优先级为5、子优先级为1,配置外部中断EXTI1的主优先级为5、子优先级为0。同时生成软件中断EXTI0、EXTI1,查看EXTI1能否先于EXTI0执行。
(1)测试代码
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
switch (GPIO_Pin)
{
case GPIO_PIN_0:
imx_printf("EXTI0 Rising\r\n");
break;
case GPIO_PIN_1:
imx_printf("EXTI1 Rising\r\n");
break;
}
}
void EXTI0_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}
void EXTI1_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
}
void gic_test_example(void)
{
int ret;
__disable_irq();
ret = gic_init(5, 3);
imx_printf("gic init : %s\r\n", ret == 0 ? "ok" : "fail");
ret = gic_prio_config(EXTI0_IRQn, 5, 1);
imx_printf("gic prio config 0 : %s\r\n", ret == 0 ? "ok" : "fail");
ret = gic_prio_config(EXTI1_IRQn, 5, 0);
imx_printf("gic prio config 1 : %s\r\n", ret == 0 ? "ok" : "fail");
SET_BIT(EXTI->SWIER1, 3);
__enable_irq();
HAL_Delay(100);
}
(2)测试结果
在相同抢占优先级情况下,响应优先级更高的中断先响应。
1.3 相同主、子优先级下谁先响应测试
如果中断主、子优先级均相同,则比较中断编号(ID),中断编号(ID)越小优先级越高。
EXTI0的中断编号比EXTI0小,应该先执行。
初始化GIC优先级位数为5,主优先级个数为3。配置外部中断EXTI0的主优先级为5、子优先级为0,配置外部中断EXTI1的主优先级为5、子优先级为0。同时生成软件中断EXTI0、EXTI1,查看EXTI0能否先于EXTI1执行。
EXTI0比EXTI1早响应,结论成立。
2 结论
(1)当前stm32MP135的中断处理方式无法实现中断抢占。
(2)主优先级更高的中断更先响应;主优先级一致则子优先级更高的中断优先响应;主优先级和子优先级都一致的中断编号(ID)更小的中断优先响应。