如何从GPIO触发中断

时间:2018-04-06 08:22:26

标签: rust embedded stm32 cortex-m

我正在将玩具应用程序移植到https://firebase.google.com/docs/functions/beta-v1-diff#cloud-firestore框架,并且很难确定如何通过GPIO触发中断。

fn init(p: init::Peripherals, _r: init::Resources) -> init::LateResources {
    let dp: stm32f103xx::Peripherals = p.device;
    let mut rcc = dp.RCC.constrain();
    let mut gpioa = dp.GPIOA.split(&mut rcc.apb2);
    let int = gpioa.pa0.into_floating_input(&mut gpioa.crl);
    dp.EXTI.imr.write(|w| w.mr0().set_bit()); // unmask the interrupt (EXTI)
    dp.EXTI.ftsr.write(|w| w.tr0().set_bit()); // trigger interrupt on falling edge  

    init::LateResources {
        EXTI: dp.EXTI,
        INT: int
    }
}

fn idle(t: &mut Threshold, mut r: idle::Resources) -> ! {
    loop { rtfm::wfi(); }
}

fn exti0(_t: &mut Threshold, mut r: EXTI0::Resources) {
    // never called
}

这个设置使我能够触发中断,但是当应该调用处理程序时有一个SEGV。我转储了二进制文件,在INTERRUPTS部分,ext0中断8000058指向地址080024e7。我在二进制文件中找不到addr2line的相应函数,所以它可能是链接器错误?

我的印象是RTFM将中断映射到任务名称,我确实有一个名为“EXTI0”的任务。

1 个答案:

答案 0 :(得分:2)

我不知道Rust,但必要的硬件步骤是:

  1. 启用APB2时钟
  2. 配置GPIO
  3. 将EXTI0线连接到GPIO PA0引脚(通过SYSCFG单元)
  4. 配置EXTI模式(中断)和触发(下降沿)
  5. 配置NVIC(设置EXTI0优先级,启用EXIT0中断)
  6. 启用EXTI0中断
  7. 我无法在代码中看到第3步或第5步。必须在NVIC 中启用IRQ,并在中启用EXTI外设中的中断。

    在使用标准外设库的C中,步骤3将如下所示:

    SYSCFG_EXTILineConfig( EXTI_PortSourceGPIOA, EXTI_PinSource0 );
    

    我不知道Rust的等价物是什么。