使用内置bootloader进行串口IAP固件升级——STM32F103RCT6

注意:后续发现以下方法因为没有关闭中断,时钟等,可能在复杂程序中发生错误。有待后续修改。

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);
}
  1. 选择串口,“偶校验”
  1. 连接成功

3.选择文件,写入

因为内置bootloader有通信安全设置,所以自己用普通串口调试助手发送的bin文件是无法被使用的,需要配合stm32cubeProgrammer使用。

参考
《安富莱_STM32-V6开发板_用户手册 第28-30章》
《AN3155》

posted @ 2022-03-03 18:42  中庭之园  阅读(1983)  评论(0编辑  收藏  举报