最近搞了个基于CAN 的IAP;
有个板子控制了电源,不能直接调用 NVIC_SystemReset()
所以想到只复位CPU,这样就保持 GPIO不变了;
代码如下:
/* Only CoreReset.
*/
__set_FAULTMASK(1);
__DSB();
SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) |
(SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
SCB_AIRCR_VECTRESET_Msk);
__DSB();
这样在 App 收到指令先调用全部外设的
HAL_DeInit(); 或者一个个调用类似 HAL_RCC_DeInit();这样些函数;
/* Timers DeInit.
*/
HAL_TIM_Base_DeInit(&htim2);
HAL_TIM_Base_DeInit(&htim3);
HAL_TIM_Base_DeInit(&htim4);
HAL_TIM_Base_DeInit(&htim5);
HAL_TIM_Base_DeInit(&htim6);
/* DMA DeInit.
*/
HAL_DMA_DeInit(&hdma_tim4_ch2);
HAL_DMA_DeInit(&hdma_tim5_ch1);
LL_DMA_DeInit(DMA2, LL_DMA_STREAM_2);
LL_DMA_DeInit(DMA2, LL_DMA_STREAM_7);
LL_DMA_DeInit(DMA2, LL_DMA_STREAM_1);
LL_DMA_DeInit(DMA2, LL_DMA_STREAM_6);
HAL_DMA_DeInit(&hdma_usart2_rx);
HAL_DMA_DeInit(&hdma_usart2_tx);
HAL_DMA_DeInit(&hdma_usart3_rx);
HAL_DMA_DeInit(&hdma_usart3_tx);
HAL_DMA_DeInit(&hdma_uart5_rx);
HAL_DMA_DeInit(&hdma_uart5_tx);
/* CAN DeInit.
*/
HAL_CAN_DeInit(&hcan1);
HAL_CAN_DeInit(&hcan2);
/* UART DeInit.
*/
LL_USART_DeInit(USART1);
LL_USART_DeInit(USART6);
HAL_UART_MspDeInit(&huart2);
HAL_UART_MspDeInit(&huart3);
HAL_UART_MspDeInit(&huart5);
/* SPI DeInit.
*/
HAL_SPI_DeInit(&hspi1);
/* RCC Reset.
*/
HAL_RCC_DeInit();
再进行复位后,就会进入到 0x08000000 开始的bootloader;
升级完成后;bootloader 会跳转到 App运行(0x08002000);
现在的问题是,仅仅 core reset 会在 App 初始化外设,并产生中断的时候,PC指针会出现0 的情况,CPU 就进入 HardFault 了;
用 __disable_irq(); 在初始化时钟之后,其他外设初始化之前,屏蔽掉全部中断,在全部外设初始化之后,再调用 __enable_irq(); 开启全部中断;也会出现
PC指针= 0 的情况,CPU 进入 HardFault ;
不知道有大侠出现过类似的情况吗?
|