STM32F4 RTC警报中断未初始化就被调用

问题描述 投票:0回答:1

RTC警报中断(IRQ编号41)在我的开发板上使用STM32F411CEU MCU不断被调用,甚至没有初始化RTC。我有这个默认的中断处理程序(我在startup_stm32F411ceux.s中注释了Default_Handler):

void Default_Handler(void)
{
    uint32_t irq_number = __get_IPSR() & IPSR_ISR_Msk;
    for(int i=0; i<nf::HAL_IRQ_map::n_interrupts;i++)
    {
        if(nf::HAL_IRQ_map::map[i].irq == irq_number)
        {
            nf::HAL_IRQ_map::map[i].irq_handler(nf::HAL_IRQ_map::map[i].params);
            break;
        }
    }

    HAL_NVIC_ClearPendingIRQ((IRQn_Type) irq_number);
}

在第一行上,我得到了IRQ号,它始终是41,这意味着RTC警报中断。在最后一行,我尝试清除IRQ,但是处理程序被连续调用。我的堆栈如下所示:

Default_Handler() at hal_irq_map.cpp:15 0x801d3e0   
<signal handler called>() at 0xfffffff9 
HAL_TIM_Base_Start_IT() at stm32f4xx_hal_tim.c:447 0x8016eec    
HAL_InitTick() at stm32f4xx_hal_timebase_tim.c:83 0x80131ea 
HAL_Init() at stm32f4xx_hal.c:176 0x8013448 
main() at main.c:95 0x8012696   

中断被一遍又一遍地调用,并且堆栈始终看起来像这样(程序无法执行)。 HAL_Init()在main()的第一行。我有Stm32CubeIDE和ST-LINK V2。

问题:

尝试清除中断时我做错什么了吗?

为什么不初始化而调用RTC警报中断?

编辑:

我尝试过:

    void Default_Handler(void)
{
    //Check if we handle the interrupt
    uint32_t irq_number = __get_IPSR() & IPSR_ISR_Msk;
    bool handled = false;
    for(int i=0; i<nf::HAL_IRQ_map::n_interrupts;i++)
    {
        if(nf::HAL_IRQ_map::map[i].irq == irq_number)
        {
            nf::HAL_IRQ_map::map[i].irq_handler(nf::HAL_IRQ_map::map[i].params);
            handled = true;
            break;
        }
    }
    if(!handled)
        HAL_NVIC_DisableIRQ((IRQn_Type) irq_number);
    HAL_NVIC_ClearPendingIRQ((IRQn_Type) irq_number);
}

现在,我正在显式禁用该中断,但是同一中断仍在触发。

arm interrupt hal stm32f4
1个回答
0
投票

问题是“一半”解决了:

__ get_IPSR()&IPSR_ISR_Msk似乎没有返回正确的IRQ编号。我现在通过HAL_NVIC_GetActive获取IRQ号。我还是ARM编程的新手,并且对文档的阅读不够充分。 “活动” IRQ表示正在处理它,即当前正在执行其处理程序。 “挂起” IRQ意味着将尽快调用其处理程序。因此,当您处于默认处理程序中并且想知道是哪个中断导致了此调用时,您会寻找“活动的” IRQ。

但是,我仍然不知道为什么RTC警报中断待处理,为什么不能将其禁用或清除。我认为它甚至从未启用过。

现在我的Default_Handler看起来像这样:

void Default_Handler(void)
{
    uint32_t irq_number;
    for(int i=0; i<50; i++)  // loop is for debugging only - comment out when not used
    {
        if(HAL_NVIC_GetActive((IRQn_Type) i))
        {
            irq_number = i;
            break;
        }
    }
    bool handled = false;
    for(int i=0; i<nf::HAL_IRQ_map::n_interrupts;i++)
    {
        if(HAL_NVIC_GetActive(nf::HAL_IRQ_map::map[i].irq))
        {
            nf::HAL_IRQ_map::map[i].irq_handler(nf::HAL_IRQ_map::map[i].params);
            handled = true;
            HAL_NVIC_ClearPendingIRQ(nf::HAL_IRQ_map::map[i].irq);
            break;
        }
    }
    if(!handled)
        for(;;); //sit here forever
}

当我遍历IRQ编号时,我发现actual活动IRQ编号是TIM1_UP_TIM10_IRQn。但是为什么要调用Default_Handler而不是(正确的处理程序)TIM1_UP_TIM10_IRQHandler

我想可能是因为我自己定义了Default_Handlerstartup_stm32f411ceux.s

中有两行
.weak      TIM1_UP_TIM10_IRQHandler            
.thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler

TIM1_UP_TIM10_IRQHandler定义为。weak,这意味着,如果您自己定义处理程序,则它是强定义,将被使用。第二行的含义对我来说有点模糊,但是我认为,如果未定义TIM1_UP_TIM10_IRQHandler,则将使用Default_Handler代替作为处理程序。在我的代码中,对于[[TIM1_UP_TIM10_IRQHandler和Default_Handler都有严格的定义。由于我不清楚的原因,链接器选择Default_Handler作为计时器1更新中断的处理程序。

尝试使用

pragmaweak

__ attribute __((weak))定义我自己的Default_Handler弱点没有帮助。因此,我只是在startup_stm32f411ceux.s中注释了。thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler,现在正确调用了[[TIM1_UP_TIM10_IRQHandler。
© www.soinside.com 2019 - 2024. All rights reserved.