1.概述
NMI(不可屏蔽的外部中断)是一个特殊的异常。因为它处于异常区,所以它不受全局中断使能位MSTATUS.MIE的控制。NMI作为外部事件,E906 将其异常向量号定义为24,优先级在所有的中断和异常中最高。
在APT32F173中,可以升级为NMI的外部中断源有:
-
外部时钟检测错误
-
EXI0
-
内存(Flash,SRAM)校验错误
-
掉电检测
上述中断源的NMI使能后,不会影响原有的中断通路,比如EMCM的中断通路也是有效的,当然NMI的优先级是最高的,所以会以NMI的形式请求中断。
2.寄存器控制配置
在SYSCON系统配置OPT1寄存器中,选择NMI触发源控制位,如下图所示,当需要使用NMI中断的时候,需要将该位置1。例如:需要使用LVD的NMI中断,需要将Bit[27]置1。
3.如何使用NMI中断
一、在vectors.S中添加NMI中断处理函数入口
.NMI_Handler:
lw t0, 0x0(sp)
lw t1, 0x4(sp)
addi sp, sp, 8
addi sp, sp, -64
sw ra, 0(sp)
sw t0, 4(sp)
sw t1, 8(sp)
sw t2, 12(sp)
sw a0, 16(sp)
sw a1, 20(sp)
sw a2, 24(sp)
sw a3, 28(sp)
sw a4, 32(sp)
sw a5, 36(sp)
sw a6, 40(sp)
sw a7, 44(sp)
sw t3, 48(sp)
sw t4, 52(sp)
sw t5, 56(sp)
sw t6, 60(sp)
la t0, nmi_int_handler
jalr t0
二、EXI0 NMI中断实例
void nmi_int_handler(void)
{
if(csp_syscon_get_int_st(SYSCON) & LVD_INT)
{
nop;
csp_syscon_int_clr(SYSCON, LVD_INT);
}
if(csp_exi_port_get_isr(SYSCON) & STATUS_EXI0)
{
nop;
gpio_irqhandler(0);
}
}
void gpio_nmi_int_testing(void)
{
csp_nmi_int_enable(SYSCON, NMI_EXI0_INT); //NMI_SEL触发源选择控制位EXI0中断事件置bit位置1
csi_pin_set_mux(PA0, PA0_INPUT); //PA0 配置为输入
csi_pin_pull_mode(PA0, GPIO_PULLUP); //PA0 上拉
csi_pin_irq_mode(PA0, EXI_GRP0, GPIO_IRQ_FALLING_EDGE); //PA0 下降沿产生中断,选择中断组0
csi_pin_irq_enable(PA0, ENABLE); //PA0 中断使能
csi_pin_vic_irq_enable(EXI_GRP0, ENABLE); //VIC中断使能,选择中断组0
__disable_excp_irq(); //在enable的情况下,也会进入NMI处理函数
}
当PA0检测到下降沿输入信号时,产生EXI0中断,首先会进入NMI的nmi_irq_handler()中断处理函数中,因为NMI的中断优先级较高,如果在NMI中断处理函数中,不及时清除中断标志位,又会进入EXI0的CLINT中断处理函数中。