stm32实现iap远程固件更新
前提
想来做iap升级了,应该不是什么新手。
下面的程序需要用到一些简单的功能
串口收发数据
开关总中断
虽然本文标题是实现远程固件更新,但是具体远程方案本文不做详细说明,重点在于介绍mcu接收到新的固件后怎么保存更新,以及更新失败回滚等。下面简单说明一下远程的事情。
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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
本文上面设置的偏移是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();
}
}
stm32实现iap远程固件更新的更多相关文章
- Azure IOT 设备固件更新技巧,看这一篇就够了
嫌长不看版 今天为大家准备的硬菜是:在 Azure IoT 中心创建 Node.js 控制台应用,进行端到端模拟固件更新,为基于 Intel Edison 的设备安装新版固件的流程.通过创建模拟设备应 ...
- can总线实现stm32的IAP
使用stm32f105rct6的can通信做IAP,实现固件的远程更新功能.IAP的实现包括两个程序:BootLoader和应用程序.启动过程先启动BootLoader,等待1s,若接收到烧写指令则开 ...
- 关于STM32的IAP与APP互相跳转
关于STM32的IAP与APP互相跳转 之前做了一个不带系统的IAP与APP互相跳转,在网上找了资料后,很顺畅就完成了,后来在IAR集成开发环境下,IAP无系统,APP用UCOS系统做互相跳转出现了很 ...
- STM32f103x IAP远程升级小结
最近在面试的时候遇到一个关于IAP远程程序升级的问题,由于之前所做的项目没有涉及到远程升级需求,当时一脸懵呆,不过回答的还是不错的,今天针对STM32F103系列调试了IAP的程序,这里做一下小结,如 ...
- STM32的IAP实现
STM32的IAP实现 2014年07月28日 16:31:06 Stylesen 阅读数:556 IAP,全称是“In-Application Programming”,中文解释为“在程序中编程 ...
- STM32的IAP方案
from: http://bbs.eeworld.com.cn/thread-294115-1-1.html 几乎所有的同类书籍都介绍综合性的应用示例如“万年历 + 温度显示 + 闹钟响铃 + 计 ...
- IAP远程在线升级
IAP远程在线升级 在上一篇中实现了LWIP网口通讯,那么肯定要加个在线升级功能,这个功能所占用的资源很少,但在物联网中很重要也很实用.在线升级就是像手机一样,先下载好系统,然后点击升级~然后就没然后 ...
- STM32串口IAP实验笔记
STM32的IAP功能确实方便,以前对此如何实现有所了解,但是一直没去测试,这两天来练了下,可谓困难重重,搞了两天问题也一一解决,下面做些简要的笔记 IAP就是在线应用编程,方便程序升级,可以不用打开 ...
- 基于libUSB的USB设备固件更新程序(下载数据)(转)
源:基于libUSB的USB设备固件更新程序(下载数据) 本文紧接上一篇日志:基于libUSB-Win32的USB设备固件更新程序(前言),相关背景以及起因等,此处不再赘述,如感兴趣请移步. libU ...
随机推荐
- [noip模拟赛]跑跑步
https://www.zybuluo.com/ysner/note/1298652 题面 小胡同学是个热爱运动的好孩子. 每天晚上,小胡都会去操场上跑步,学校的操场可以看成一个由\(n\)个格子排成 ...
- SPOJ OTOCI 动态树 LCT
SPOJ OTOCI 裸的动态树问题. 回顾一下我们对树的认识. 最初,它是一个连通的无向的无环的图,然后我们发现由一个根出发进行BFS 会出现层次分明的树状图形. 然后根据树的递归和层次性质,我们得 ...
- 提交图片base64格式问题
提交图片base64格式给后台,一定把data:image/png;base64,去掉,不然提交后后台返回的图片URL打开是一个破坏的图片.使用split("base64,")[1 ...
- spring-boot-configuration-processor的作用
spring默认使用yml中的配置,但有时候要用传统的xml或properties配置,就需要使用spring-boot-configuration-processor了 先引入pom依赖 <d ...
- OAuth2.0最简向导
无论你是否有技术背景,你都能看懂授权协议框架OAuth2.0 翻译来自:川崎高彦对自己投资人讲解自己的SaaS安全产品. Got it! https://medium.com/@darutk/the- ...
- Agar.io 简单但是有趣的网页游戏
攻略,进阶 上榜第一次 (有点水,九百多分) 上榜第二次 (完成四杀,逆袭上榜) 上榜第三次 (忘写名字,自己补上) 上榜第四次 (人生巅峰!) 上榜第五次 (踩了狗屎运,上榜这么容易了?收了一个小 ...
- LIS UVA 10534 Wavio Sequence
题目传送门 题意:找对称的,形如:123454321 子序列的最长长度 分析:LIS的nlogn的做法,首先从前扫到尾,记录每个位置的最长上升子序列,从后扫到头同理.因为是对称的,所以取较小值*2-1 ...
- 二分+RMQ/双端队列/尺取法 HDOJ 5289 Assignment
题目传送门 /* 题意:问有几个区间最大值-最小值 < k 解法1:枚举左端点,二分右端点,用RMQ(或树状数组)求区间最值,O(nlog(n))复杂度 解法2:用单调队列维护最值,O(n)复杂 ...
- 转 MySQL数据库基础
http://lib.csdn.net/article/mysql/57883 1 数据库基础 一.数据库与数据库管理系统 1.数据库(DB):存放数据的仓库,从广义来说,数据不仅包括数字,还包括了文 ...
- UML中类之间的关系
UML中类之间的关系分为以下几种:依赖.关联.泛化.聚合.组合. 依赖是指一个类使用了另一个类,它是一种使用关系,描述了一个事物的规格说明的变化可能会影响到使用它的另一个事物(反之不一定).最常见的依 ...