STM32上添加bootloader+application,在外部flash中备份及升级程序

本文介绍了一个基于STM32F103VET6的Bootloader设计,用于实现远程程序升级。通过外部8M SPI Flash进行程序备份与更新,详细阐述了工程配置、流程及代码实现。

近期看到一篇关于bootloader的博文,亲手也尝试了一下,这里做下笔记,方便日后查看,根据项目修改可以加个DTU,用服务器远程升级一下程序。

一、工程配置

使用的是stm32f103vet6芯片,512的ROM,64kRAM,外部flash用的是8M芯片W25Q64,分成三部分,每部分1Mb,第一块(0x000000-0x100000)存放升级应用程序,第二块(0x100000-0x200000)存放备份程序(即当前应用程序),第三块用来存放标志位(新旧程序校验码、旧程序备份标志、新程序更新标志)。

1.BootLoader程序工程配置

在这里插入图片描述在这里插入图片描述

2.Application程序工程配置

在这里插入图片描述
在这里插入图片描述

二、大体流程,细节需完善

1.需要注意对flash写操作前,先擦除对应的扇区,外部flash一次查出一扇区4kb,stm32大容量一次擦除2kb,像stm32f103c8t6这种一次擦除1kb。
在这里插入图片描述

  • 扩展一下
    在这里插入图片描述

三、代码

1.BootLoader

main.c

 /**
  ******************************************************************************
  * @file    main.c
  ******************************************************************************
  */ 
#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./led/bsp_led.h"
#include "./flash/bsp_spi_flash.h"
#include "app_update.h"	

typedef enum {
   
    FAILED = 0, PASSED = !FAILED} TestStatus;

__IO uint32_t DeviceID = 0;
__IO uint32_t FlashID = 0;
__IO TestStatus TransferStatus1 = FAILED;

void Delay(__IO uint32_t nCount)
{
   
   
  for(; nCount != 0; nCount--);
}


int main(void)
{
   
    	
	LED_GPIO_Config();
	
	/* 配置串口为:115200 8-N-1 */
	USART_Config();
	printf("\r\n 这是一个bootloader程序 \r\n");
	
	/* 8M串行flash W25Q64初始化 */
	SPI_FLASH_Init();
	
	/* 获取 Flash Device ID */
	DeviceID = SPI_FLASH_ReadDeviceID();	
	Delay( 200 );
	
	/* 获取 SPI Flash ID */
	FlashID = SPI_FLASH_ReadID();	
	printf("\r\n FlashID is 0x%X,\
	Manufacturer Device ID is 0x%X\r\n", FlashID, DeviceID);
	
	/* 检验 SPI Flash ID */
	if (FlashID == sFLASH_ID)
	{
   
   	
		printf("\r\n 检测到串行flash W25Q64 !\r\n");
		
		// 读取更新标志
		SPI_FLASH_BufferRead(&Prog_Status_Flag.Backup_Flag,PROG_FLAG_ADDR,sizeof(struct _Prog_Status_Flag));
		// 判断是否需要备份程序,新的 FLASH 读出来都是 0xFF
		if(Prog_Status_Flag.Backup_Flag != 0xA5)
		{
   
   
				LED_GREEN;
				// 如果检测到是新的 Flash 或者是第一次开机,则备份当前的程序,
				// 备份后在进行校验,校验OK后将校验码写入 PROG_FLAG_ADDR 开始的地址中
				Backup_Current_Program();
		}
		// 判断是否需要更新程序
		if(Prog_Status_Flag.Update_Flag == 0x55)
		{
   
   
				LED_BLUE;
				// 显示屏显示提示,正在更新程序....
				Backup_Current_Program();
				Updata_New_Program();
		}
	}
	else
	{
   
    
		LED_RED;
		printf("\r\n 获取不到 W25Q64 ID!\n\r");
	}
	
	Load_App(STARTADDR);
	while(1);  
}
/*********************************************END OF FILE**********************/

app_update.c

/**
******************************************************************************
* @file    app_update.c
* @author  
******************************************************************************
*/ 
#include "stm32f10x.h"
#include "./usart/bsp_usart.h"
#include "./led/bsp_led.h"
#include "./flash/bsp_spi_flash.h"
#include "app_update.h"	

struct _Prog_Status_Flag Prog_Status_Flag;
uint32_t JumpAddress;       // 跳转地址
u8 ReadBuf[2048];           // 缓存,2048 , 每次更新 2048 2k

typedef  void (*pFunction)(void);  // 申明一个函数指针
pFunction Jump_To_Application;




// 备分当前程序
void Backup_Current_Program(void)
{
   
   
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值