完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
1个回答
|
|
想来做iap升级了,应该不是什么新手。
下面的程序需要用到一些简单的功能
stm32的通信方式有串口,spi,iic,以及sdio等。也就是说我们的固件可以通过这些方式传输到mcu,不过普遍常用的是串口或者用sdio(外接sd卡)这两种方式。个人觉得用sd卡来回copy也不怎么方便。简单点还是再加一个串口网络模块,然后把固件存到服务器,经由串口网络模块透传到mcu。比如用http协议把固件发送下来。远程下载就这么简单一说。接下来重点分析更新的事情。 #固件生成 远程更新使用的固件和我们平时烧录程序用的固件格式有点区别,我们需要用二进制格式(.bin)文件。生成方式以mdk为例介绍一下,只需要添加一条命令行。 在mdk工程配置选项选择User,这个页面是让我们添加自定义命令行的,我们要添加的命令添加到第三个选项,即在编译完成后执行。下面是命令内容,需要注意的是 bin前面两个-,app1.bin就是生成的固件,名字可以自定义,**.axf是你工程实际的.axf文件,路径要正确。不知道你的axf在那在output页面查看。 fromelf.exe --bin -o ../app1.bin ./**.axf 现在我们就可以生成bin文件了,但是还差一点步骤。 一般使用下mcu启动后会自动把0x0800 0000映射到地址0x0000 0000,然后取指令执行。但是现在我们程序可以理解成分成了两部分。 app就是我们实际实现各种功能的固件,BootLoader为控制更新的固件。可以看到加入iap升级功能后我们app的起始地址变了,所以对应工程也要做这部分修改 如图,我这里把地址偏移了0x20000,同时在Linker中把“Use Memory Layout from Target Dialog”勾选,让我们的修改生效。 如此设置以后就一些ok了 图中上半部分是起始地址为0x800 0000 下半部分为起始地址0x802 0000,可以看到复位中断地址,以及下面一系列入口地址都相应变化了。 关于固件有一点需要注意,因为起始地址修改了,所以导致我们的中断向量表也整体偏移了,所以需要在app程序起始添加一行代码,本文是偏移0x20000,根据实际使用做相应改动 NVIC_SetVectorTable(NVIC_VectTab_FLASH,0x2000); #固件保存 下载到板子的方式自选,下到板子后,我们需要把固件保存到内置flash对应的地址, int writeToFlash(unsigned char *data, unsigned int len,unsigned int baseAddress ) { unsigned char i = 0; unsigned char pageNum = 0; FLASH_Status FLASHStatus; pageNum = len/FLASH_PAGE_SIZE+1;//求出总页数 FLASH_Unlock(); FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); for (i=0; i < pageNum; i++) { FLASHStatus = FLASH_ErasePage(baseAddress + FLASH_PAGE_SIZE*i); if (FLASHStatus != FLASH_COMPLETE) { FLASH_Lock(); return -1; } } pageNum = (len+1)>> 1; for (i=0; i < pageNum; i++) { FLASHStatus = FLASH_ProgramHalfWord(baseAddress+i*2, *((unsigned short*)data+i)); if (FLASHStatus != FLASH_COMPLETE) { FLASH_Lock(); return -1; } } FLASH_Lock(); return 0; } 本文上面设置的偏移是0x2 0000,所以此处写入flash的地址也必须是0x802 0000(0x800 0000 + 0x2 0000) 除了写入外,还应该加一些必要的文件完整性检查,比如使用校验等方式,这部分自行处理。然后在flash特定区域立一个flag,通知BootLoader程序更新固件。 #固件更新 现在万事具备了,接下来就是更新的事情了,先简单说一下更新的思路。上电启动后运行BootLoader程序,在bootloader中检查是否是否需要更新,不需要的话就引导之前的app程序运行,需要更新就引导新的app程序。引导步骤大体就是重置栈顶指针,强制跳转app的reset复位中断。 #define APPLICATION_ADDRESS 0x08020000 typedef void (*pFunction)(void); int main(void) { SystemInit(); BootLoad_Jump(); } __asm void MSR_MSP(u32 addr) //设置堆栈指针 { MSR MSP, r0 BX r14 } void BootLoad_Jump(void) { u32 JumpAddress; pFunction Jump_To_Application; /* Check Vector Table: Test if user code is programmed starting from address "APPLICATION_ADDRESS" */ //d_printfhex32((*(__IO uint32_t*)APPLICATION_ADDRESS));d_printf("n"); if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) == 0x20000000) { __disable_irq(); JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS +4); //d_printfhex32(JumpAddress);d_printf("n"); Delay(100); Jump_To_Application = (pFunction) JumpAddress; /* Initialize user application's Stack Pointer */ MSR_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); Jump_To_Application(); } } 本文只贴出核心部分,也就是BootLoader直接引导app,没做其他判断。那些判断逻辑自行实现。 顺带一提,BootLoader程序的flash地址不需要修改,即正常的0x800 0000,正常使用烧录工具下载。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1683 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1582 浏览 1 评论
1013 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
703 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1627 浏览 2 评论
1892浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
675浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
538浏览 3评论
558浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
526浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-4 03:04 , Processed in 0.639607 second(s), Total 47, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号