最近碰到STM32在进行IAP升级时跳转至APP后无法进入中断,导致程序无法运行。正常情况下STM32进行IAP升级时,在跳转至APP程序之前,应该关闭外设,关闭中断。BootLoader中跳转程序如下:
typedef void (*pFunc)(void);
__set_FAULTMASK(1);
pFunc pApp;
pApp = (pFunc)(*(__IO uint32_t*)(APP_DEFAULT_IMAGE_ADDR + 4));
__set_MSP(*(__IO uint32_t*)APP_DEFAULT_IMAGE_ADDR);
pApp();
在APP程序中keil已经进行如下设置: 在system_stm32l4xx.c中打开USER_VECT_TAB_ADDRESS宏定义,并设置偏移量: 运行之后发现能正常跳转至APP程序中,并且没有跑飞,只是无法进入中断,最后发现是BootLoader程序中执行了__set_FAULTMASK(1);这行代码。
FAULTMASK是一个中断屏蔽寄存器,当它置1时,只有NMI能响应,其他的中断或者fault都无法响应,为0的时候表示没有异常,才能正常响应中断,属于特权级。
因此,在进入APP程序中,应该使用__set_FAULTMASK(0);打开FAULTMASK全局中断,可以加在SystemInit()函数开始部分或者main()函数中。
void SystemInit(void)
{
__set_FAULTMASK(0);
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;
#endif
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 20U)|(3UL << 22U));
#endif
RCC->CR |= RCC_CR_MSION;
RCC->CFGR = 0x00000000U;
RCC->CR &= 0xEAF6FFFFU;
RCC->PLLCFGR = 0x00001000U;
RCC->CR &= 0xFFFBFFFFU;
RCC->CIER = 0x00000000U;
}
SystemInit()函数在main()函数之前执行,可以在启动代码startup_stm32l431xx.s中看到:
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
同理,如果跳转前使用__disable_irq();关中断,在APP中要先使用__enable_irq();打开中断。
|