从零实现 STM32F103X的bootloader

欢迎大家留言交流~


一、因为要做模块的升级所以需要用到bootloader。先捋清楚一下各步骤:

1.划分flash区间。我的模块是stm32f103RB,flash大小是128k字节(0x2000)。我打算将flash分为三个部分:bootloader(0x8000000~0x8004000)、应用程序代码(0x8004000~0x8012000)、待升级的IAP程序(0x8012000~0x8020000)。

2.划分FRAM区间,总共0x2000字节,bootloader要记录是否需要IAP所以需要占用一些FRAM空间(0x0000~0x0100),应用程序占用(0x0100~0x2000)。

3.bootloader先实现跳转到flash应用程序app的目标位置。(IAP先不考虑)

4.跳转后成功执行app。

二、先用cubeMX生成bootloader:

1.选择芯片

2.选上需要的功能,首先是必须的RCC、SYS、IWDG。因为要用到FRAM所以需要用到I2C2。

3.对照原理图核对管脚是否正确,并且增加LED灯用来辅助调试boot

FRAM-WP、LED3、LED4、LED5都设置为output。其他默认

4.配置时钟为72M

5.详细配置,默认即可

6.工程设置

然后生成代码即可。在代码中cubeMX只是初始化了配置,但是并没有使用,比如开启了看门狗,但是并未喂狗,需要自行喂狗。因为bootloader的特殊性,并不需要喂狗,也并不需要有什么内容是放在while(1)中的,因为bootloader只运行一次,主要就是执行跳转指令。

7.生成代码后打开工程,修改工程配置

因为bootloader大小设置为0x4000大小,所以size设置一下

然后就是debug设置为J-LINK,SWD

8.代码实现

创建代码后如何验证程序可用呢?我在while(1)里加了延时和翻转小灯的状态,这样每循环两次小灯就闪烁一次。在这里我是一次成功的。当然,需要喂狗。

那么如何跳转到flash目标地址呢?

app_iap.c

app_iap.h

加上这两个文件,然后在主函数中调用IAP_ExecuteApp(USER_ADDR_APP);

为了验证这个bootloader好用,我们在这个bootloader的小灯初始化时,让LED3常亮,LED4、LED5长灭。

让应用程序初始化小灯时LED3为灭,并且LED5常量,LED4闪烁。这样如果成功的话,那么理论上LED3亮一下,随后熄灭,LED4闪烁,LED5常亮。

9.设置启动

当然,要设置一下应用程序的配置,修改起始地址和大小

之后重新编译,烧录,但是结果并不对,LED3几乎是常亮,间歇短暂熄灭的时候LED4、LED5也短暂闪烁一下,随后熄灭。

找了很久的原因,以为是触发了看门狗,或者是没有关闭中断。但其实都不是,是因为向量表没有更改

 

在应用程序的中的这个文件VECT_TAB_OFFSET默认是0x00000000U,但是我们应该更改为起始地址中0x08004000的0x00004000U。

编译后,就可以正常跳转了。但是根据同事的意见,还是要在跳转指令前关闭一下全局中断才好。

__disable_irq();   // 关闭总中断
__enable_irq();    // 开启总中断

于是我在跳转指令前加了关闭总中断,但又出现跳转失败的情况。通过debug发现可以跳转到应用程序成功,但是还是会在初始化的过程中死机,所以我在应用程序中的第一句加上打开总中断,这时跳转成功并且应用程序运行正常了。

搞不清楚这个原因,时间有限暂且不研究了,不过这是一个值得尝试的地方。我还是暂且不用这两句话吧。

到此,bootloader的跳转功能实现了,接下来要实现程序升级。


总结:

bootloader是常用的引导程序,可以实现诸如IAP、U盘升级、引导程序等功能。

我们在做的时候需要注意,APP的中断向量表需要修改,因为中断向量表都是默认指向0x0000000的,bootloader一个启动文件、一个中断向量表。APP一个启动文件、一个中断向量表

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值