SUPER_tool
介绍
用于stm32工业控制芯片的最小boot更新程序。程序整体小于1k,对ram较小,flash充足,有程序备份区域的适用。其它单片机快速移植使用
软件架构
说明:极简boot程序,确保更新鲁棒性,稳定。
仅需app区程序下载更新包到备份区,设置用户数据区更新标志,然后重启,boot会自动根据标志更新app区
boot功能
在app中进行备份区域数据的校验,boot仅实现备份区数据读和app数据写。完成后清除标志位。
/**********************************************************
F410http_FLASH_testv2.0
***********************************************************/
#include "stm32f10x.h"
#define APP_CNT (100)
/* 基地址和分区大小 */
#define ADDR_START (0x08000000)
#define SIZE_FLASH (256*1024)
#define SIZE_BOOT (10*1024)
#define SIZE_APP (100*1024)
#define SIZE_COPY (100*1024)
#define SIZE_DATA (44*1024)
#define SIZE_REG (2*1024)
/* 分区起始地址 */
#define ADDR_BOOT (ADDR_START) //起始 地址
#define ADDR_APP (ADDR_START+SIZE_BOOT) //app 地址
#define ADDR_COPY (ADDR_START+SIZE_BOOT+SIZE_APP) //备份 地址
#define ADDR_DATA (ADDR_START+SIZE_BOOT+SIZE_APP+SIZE_COPY) //数据 地址
#define ADDR_REG (ADDR_START+SIZE_BOOT+SIZE_APP+SIZE_COPY+SIZE_DATA) //三元组地址
#define ADDR_END (ADDR_START+SIZE_FLASH) //结束 地址
/* BKP区 */
#define RTC_ENABLE (0X5679)
#define RTC_DISABLE (0X3265)
//BKP_DR1可以有20个且均为16位
#define ADDR_RTC BKP_DR1
#define ADDR_UPDATE BKP_DR2
#define PWR_BackupAccessCmd_ENABLE() {RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR|RCC_APB1Periph_BKP,ENABLE); PWR_BackupAccessCmd(ENABLE);}//开启备份区域写入权限 和 配置时钟
#define PWR_BackupAccessCmd_DISABLE() {PWR_BackupAccessCmd(DISABLE);} //关闭备份区域写入权限
/* 写BKP寄存器 */
void PWR_BackupAccessCmd_WRITE(uint16_t BKP_DR, uint16_t DataA){
PWR_BackupAccessCmd_ENABLE();//开启备份区域写入权限
BKP_WriteBackupRegister(BKP_DR, DataA);
PWR_BackupAccessCmd_DISABLE();//关闭备份区域写入权限
}
//=========================复制校验
void copy(void)
{
u32 i = 0;
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPTERR | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
for(;i < APP_CNT;i++) FLASH_ErasePage(ADDR_APP+(i*1024)); /* 擦除 */
for (i = 0; i < SIZE_APP / 4; i++) FLASH_ProgramWord(ADDR_APP+4 * i, *((u32 *)(ADDR_COPY + 4 * i))); /* 写入 */
FLASH_Lock();
}
int copy_check(void)
{
u32 i = 0;
u32 * sour = (u32 *)ADDR_COPY;
u32 * neww = (u32 *)ADDR_APP;
for (i = 0; i < SIZE_APP / 4; i++,sour++,neww++)
if(*sour != *neww)
return -1;
/* 清除标志位 */
PWR_BackupAccessCmd_WRITE(ADDR_UPDATE,RTC_DISABLE);
return 1;
}
//======================APP跳转
__asm void MSR_MSP(u32 addr)
{
MSR MSP, r0 //set Main Stack value
BX r14
}
typedef void (*iapfun)(void); //定义一个函数类型的参数.
void iap_load_app(u32 appxaddr)
{
iapfun jump2app; //
if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000) //检查栈顶地址是否合法.
{
jump2app=(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址)
MSR_MSP(*(vu32*)appxaddr); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址)
jump2app(); //跳转到APP.
}
}
//====================== 主函数==
int main(void)
{
int i = 0;
if(BKP_ReadBackupRegister(ADDR_RTC) == RTC_ENABLE&&BKP_ReadBackupRegister(ADDR_UPDATE) == RTC_ENABLE){ //检测更新
do copy(); //执行更新
while(copy_check() < 0&&i++ < 10); //检测更新结果
}
iap_load_app(ADDR_APP); //跳转app
while(1){}; //死锁
}
参考源码下载:https://download.csdn.net/download/qq_42074368/86261470
参考 https://gitee.com/llbgbirdjj/f410-a4_supper_boot