单片机BootLoader启动后,查看标志位,标志位=1168,读取data区保存长度的数据,下载到APP区。下载完成后,验证APP与data区数据是否一致。一致的话,清除标志位。跳转到APP开始程序运行。(后续升级功能,添加接收文件功能,可以在没有app程序的情况下自主下载app程序)
APP程序运行后,收到文件传输的请求后,开始接收文件,接收完毕后,下载到data区,然后单片机重新上电,即可自动完成烧录过程。(后续,data区下载后添加验证功能,验证成功后,在设置标志位,标志位与data区分开。防止下载中途断电,造成程序异常,同时添加跳转BootLoader功能,免除人为重新上电步骤。)功能扩展可添加蓝牙,sd卡,网络等多种模式的升级方式。
F103led app程序
F103ledboot BootLoader
STM32_IPA c#文件传输
BootLoader, 设置
设置boot文件大小为8kb。
#define APP_ADDR 0x08002000 //定义应用程序地址
#define DATA_ADDR 0x08005000 定义程序存储地址
typedef void(*pFunction)(void); 跳转函数指针定义。
pFunction Jump_To_Application;
跳转关键代码
__set_PRIMASK(1); 关闭中断,必须有该语句,
JumpAddress=*(__IO uint32_t *)(APP_ADDR+4); 应用程序地址,必须+4
Jump_To_Application=(pFunction)JumpAddress;
__set_MSP(*(__IO uint32_t *)APP_ADDR);
Jump_To_Application();
if (((*(volatile u32*)ApplicationAddress) & 0x2FFE0000 )== 0x20000000)官方代码有一个判断,应该是判断堆栈地址的,未使用。
存储空间,定义 0 1 两个字节为标志位,当标志位== 0x1168时 ,表示有新程序 开始更新程序,然后比较更新结果,擦除标志位,跳转。
uint16_t DATA_FLAG;
DATA_FLAG=FLASH_ReadHalfWord(DATA_ADDR);// 读取标志位
uint16_t FLASH_ReadHalfWord(uint32_t faddr) 读取函数
{
return *(__IO uint16_t*)faddr;
}
写flash代码
for(uint32_t i=0;i<DATA_LENGTH/2;i++)
{
TempBuf=FLASH_ReadHalfWord(DATA_ADDR+4+i*2);//
printf(" 0x%04x",TempBuf);
//TempBuf = pBuffer[i];
//printf(" 0x%04x",TempBuf);
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD , APP_ADDR + i * 2, TempBuf);
TempBuf=FLASH_ReadHalfWord(APP_ADDR + i * 2);//
printf(" 0x%04x\n",TempBuf);
}
应用程序
下载设定。
关键代码 修改中断向量表
__set_PRIMASK(1); 不关中断 修改向量表无效,????
SCB->VTOR = FLASH_BASE | 0x2000;
__set_PRIMASK(0);
生成bin keil设定
$K\ARM\ARMCC\bin\fromelf.exe --bin --output=@L.bin !L
该参数可自动生成bin文件