远程升级详细说明
升级分为三个部分:1.bootload,2.app,3.待加载的bin文件.
其先后关系是:首先下载bootload,然后下载app,最后通过app工程的串口加载bin文件.其详细点的步骤说明如下:
1.Bootload制作过程
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//失能JTAG功能--以便使用其复用脚
USART_Config();//Usart3 串口打印调试
printf("bootloader\r\n");
/* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000)//flash后半扇区有程序更新,将这后半扇区程序移植到前边扇区
{
FLASH_If_Erase(APPLICATION_ADDRESS_run,APPLICATION_ADDRESS);//擦除16k到56k扇区
Move_code(APPLICATION_ADDRESS_run,APPLICATION_ADDRESS,30*1024);//max 40k
FLASH_If_Erase(APPLICATION_ADDRESS,APPLICATION_ADDRESS+30*1024);//擦除56k到30k扇区--否则每次重启将重新加载
}
/* Test if user code is programmed starting from address "APPLICATION_ADDRESS" */
if (((*(__IO uint32_t*)APPLICATION_ADDRESS_run) & 0x2FFE0000 ) == 0x20000000)//前边扇区有加载程序
{
/* Jump to user application */
JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS_run + 4);
JumpToApplication = (pFunction) JumpAddress;
/* Initialize user application's Stack Pointer */
__set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS_run);
JumpToApplication();
}
while(1)
{
}
}
这是主要程序.详见bootload工程.解说下bootload的工作原理:首先描述下整个工作中将内部flash分为了三个部分(如果程序太大,可将程序下载外部的存储器中,上电后判断外部存储器是否加载程序了,如果有,将程序加载到内部Flash中):bootload工程小,就给他分配个16k,剩下的空间分为两份,一份是存储当前再跑的程序,另一份空间预留给待加载的程序.最后预留一些空间存储变量.
好了现在开始了:bootload首先通过if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000),APPLICATION_ADDRESS=0x0800e000判断flash待加载的程序空间是否有加载程序,如果有的话,则将这部分程序从0x0800e000---50k的code加载到0x08004000--50k的空间处.然后同理通过if (((*(__IO uint32_t*)APPLICATION_ADDRESS_run) & 0x2FFE0000 ) == 0x20000000)判断待运行的flash空间是否加载了程序,有加载则跳转到0x08004000处开始执行.bootload的编译配置设置如图:
2.App制作过程
程序看APP工程.详细说下工作原理://将中断向量移植到程序运行的开头地址处
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000);这句话非常重要,将中断向量表移植到新的程序空间的首地址(0x08004000)开始的处,否则中断函数不可用.那么编译配置也得对应如图:
意味着程序主程序将从0X08004000地址开始存储.大小是50k,因为中断向量是从0X08004000开始的位置,所以主程序的存储配置IROM1必须是0X08004000.否则将失败.app工程加载程序使用的是串口3的阻塞式方式,使用ymodem协议(如果wifi通信模块支持硬件流控制也可以通过串口的RTS,CTS两硬件流控制引脚控制串口一次接收数据的个数http://blog.csdn.net/zeroboundary/article/details/8966586)加载,那么串口软件或者是上位机得使用ymodem协议(详细说明https://www.cnblogs.com/hiker-blogs/archive/2013/03/17/stm32.html)发送才能被app工程正确接收,根据串口提示输入即可.详细步骤如图:打开超级终端hypertrm.出现此图随便输入一个名字,点击确认.
进入如下界面配置串口.
点击发送文件按键,进入如下界面,选择对应的.bin文件.选择Ymodem协议,然后点击发送.
3.目标工程编译配置及待加载bin文件生成
因为重启后更新是擦除了App存储区然后加载目标.bin文件到App存储区,所以目标工程的编译的配置必须和app的一样,才能正常运行.如图:
其程序的的开头也得加上
//将中断向量移植到程序运行的开头地址处
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000);工程编译生成的HEX文件(HEX文件与bin文件区别:
http://blog.csdn.net/zhangliang_571/article/details/8519469)是不可用的,因为HEX带有不必要的地址信息,所以得将HEX文件转化为.bin文件,有很多方法:a.下载hex转bin文件工具,b.直接在keil编译配置User选择下的After Build/Rebuild 的Run #1的方框内容输入fromelf --bin -o ..\Output\app.bin ..\Output\SmartDoorLock.axf那么在对应的HEX文件目录下生成.bin文件.