Cortex-A7的GIC(通用中断控制器)使用方法(6):基于stm32MP135的IRQ初始化及处理流程分析

31 篇文章 0 订阅
28 篇文章 0 订阅

0 参考资料

STM32MP13xx参考手册.pdf(RM0475)
ARM Generic Interrupt Controller Architecture version 2.0 - Architecture Specification.pdf

1 基于Cortex-A7的STM32MP135的IRQ初始化及处理流程分析

熟悉基于Cortex-M内核的stm32系列MCU的一定对中断向量表非常熟悉,在Cortex-M中断向量表存放了所有中断服务函数的地址,使用前需要设置中断向量偏移地址确定中断向量基地址,一旦产生异常或中断处理器就会自动跳转到相应的中断服务函数中执行中断(例如EXTI0_IRQHandler、USART1_IRQHandler等)。如下是基于Cortex-M7的stm32H743的部分中断向量表:O
在这里插入图片描述

在Cortex-A7中也有中断向量表,不过并没有包含所有的IRQ中断,而是将所有中断均归类到IRQ中。中断向量表如下:
在这里插入图片描述
因此发生中断时不会直接跳转到相应的中断服务函数内执行,而是跳转到IRQ中断服务函数统一处理。下面分析STM32MP135的IRQ初始化及处理流程。

1.1 初始化向量表基地址

   /* Set Vector Base Address Register (VBAR) to point to this application's vector table */
  "LDR    R0, =Vectors                             \n"
  "MCR    p15, 0, R0, c12, c0, 0                   \n"
  "ISB                                             \n"

这里通过设置VBAR(向量基地址寄存器)初始化向量基地址。
Vectors函数定义如下:

/*----------------------------------------------------------------------------
  Exception / Interrupt Vector Table
 *----------------------------------------------------------------------------*/
void Vectors(void) {
  __asm__ volatile(
  ".align 7                                         \n"
  "LDR    PC, =Reset_Handler                        \n"
  "LDR    PC, =Undef_Handler                        \n"
  "LDR    PC, =SVC_Handler                          \n"
  "LDR    PC, =PAbt_Handler                         \n"
  "LDR    PC, =DAbt_Handler                         \n"
  "LDR    PC, =Rsvd_Handler                         \n"
  "LDR    PC, =IRQ_Handler                          \n"
  "LDR    PC, =FIQ_Handler                          \n"
  );
}

编译之后的地址如下:
在这里插入图片描述
正好和Cortex-A7中定义的异常/中断偏移地址相对应,当发生IRQ中断时,PC指针便移动到相对于中断向量基地址+0x18的位置,然后执行语句“LDR PC, =IRQ_Handler”,将IRQ_Handler函数的地址放入PC指针,便开始执行IRQ_Handler函数。
需要注意的是,Reset_Handler函数被定义在代码段最开始的位置,这样当从BOOT跳转到APP或者stm32内部bootloader跳转时,只需要将PC指针指向代码段首地址便可以实现跳转。
在这里插入图片描述
注:0x2ffe0000是代码段首地址。

1.2 IRQ_Handler函数处理中断流程

IRQ_Handler函数如下:

void __attribute__((interrupt("IRQ"))) IRQ_Handler(void)
{
#elif defined(__ICCARM__)
__irq __arm void IRQ_Handler(void)
{
#endif
    uint32_t ItId;
    IRQHandler_t handler;

    while (1U)
    {
        /* Get highest pending Interrupt Id from GIC driver*/
        ItId = (uint32_t)IRQ_GetActiveIRQ();

        if (ItId <= GIC_HIGHEST_INTERRUPT_VALUE) /* Highest value of GIC Valid Interrupt */
        {
            /* Check validity of IRQ */
            if (ItId >= (uint32_t)MAX_IRQ_n)
            {
                SystemInit_IRQ_ErrorHandler();
            }
            else
            {
                /* Find appropriate IRQ Handler (Require registration before!) */
                handler = IRQ_GetHandler((IRQn_ID_t)ItId);

                if (handler != NULL)
                {
                    /* Call IRQ Handler */
                    handler();
                }
                else
                {
                    /* Un register Handler , error ! */
                    SystemInit_IRQ_ErrorHandler();
                }
            }

            /* End Acknowledge interrupt */
            IRQ_EndOfInterrupt((IRQn_ID_t)ItId);
        }
        else
        {
            /* Normal case: whenever there is no more pending IRQ , IAR returns ACKNOWLEDGE special IRQ value */
            if (ItId == GIC_ACKNOWLEDGE_RESPONSE)
            {
                break;
            }
            /* Spurious IRQ Value (1022)  ... */
            else
            {
                SystemInit_IRQ_ErrorHandler();
            }
        }
    }
}

执行步骤如下:
(1)获取激活/挂起的最高优先级中断ID
(2)查找中断ID对应的中断服务函数
(3)跳转到中断服务函数执行中断服务
(4)发送中断处理结束信号,本次中断处理完毕
(5)继续步骤(1)直到中断全部处理完毕
从以上步骤可以看到一个和Corex-M处理中断明显不同的地方,那就是高优先级中断已经无法抢占低优先级中断,这个在后面的实验中可以看到。

2 总结

(1)基于Cortex-A7的STM32MP135的IRQ不支持高优先级中断抢占低优先级中断执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NW嵌入式开发

感谢您的支持,让我们一起进步!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值