注意:后續發現以下方法因為沒有關閉中斷,時鍾等,可能在復雜程序中發生錯誤。有待后續修改。
STM系列有內置的bootloader,支持通過CAN、SPI、I2C、USB DFU、USART進行固件升級。
需配合STM32CubeProgrammer使用,以下為串口接收到0x55后,進入內置bootloader的例子,其中地址0x1FFFF000
需要查詢《AN2606
Application note—STM32 microcontroller system memory boot mode》
/*
*********************************************************************************************************
* 函 數 名: JumpToBootloader
* 功能說明: 跳轉到系統BootLoader
* 形 參: 無
* 返 回 值: 無
*********************************************************************************************************
*/
void JumpToBootloader(void)
{
uint32_t i = 0;
void (*SysMemBootJump)(void); /* 聲明一個函數指針 */
__IO uint32_t BootAddr = 0x1FFFF000; // STM32F1系列內置bootloader地址
/* 關閉全局中斷 */
__set_PRIMASK(1);
/* 關閉滴答定時器,復位到默認值 */
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
/* 設置所有時鍾到默認狀態,使用HSI時鍾 */
HAL_RCC_DeInit();
/* 關閉所有中斷,清除所有中斷掛起標志 */
for (i = 0; i < 8; i++)
{
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
/* 使能全局中斷 */
__set_PRIMASK(0);
/* 跳轉到系統BootLoader,首地址是MSP,地址+4是復位中斷服務程序地址 */
SysMemBootJump = (void (*)(void))(*((uint32_t *)(BootAddr + 4)));
/* 設置主堆棧指針 */
__set_MSP(*(uint32_t *)BootAddr);
/* 在RTOS工程,這條語句很重要,設置為特權級模式,使用MSP指針 */
__set_CONTROL(0);
/* 跳轉到系統BootLoader */
SysMemBootJump();
/* 跳轉成功的話,不會執行到這里,用戶可以在這里添加代碼 */
while (1)
{
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (aRxBuffer[0] == 0x55)
{
JumpToBootloader();
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 1);
}
- 選擇串口,“偶校驗”

- 連接成功

3.選擇文件,寫入

因為內置bootloader有通信安全設置,所以自己用普通串口調試助手發送的bin文件是無法被使用的,需要配合stm32cubeProgrammer使用。

參考
《安富萊_STM32-V6開發板_用戶手冊 第28-30章》
《AN3155》