STM32 芯片 IAP 实现

  cheney

老早以前就知道很多芯片都有 IAP 功能,但是从来没有实际用过。现在因为有可能在项目中用到,就先看看

在 FLASH 内首先要用别的方式烧入两份程序,一份是真正的应用程序,一份是自己编写的BootLoader程序。两份程序的起始地址不同,因为上电一般直接执行应用程序,所以STM32的应用程序放在0x08000000,BootLoader一般不大,放在FLASH最后会比较好,这次测试程序放在0x08010000地址开始。 两份程序都有各自的中断向量表,都是从起始地址+4 开始。

工程配置

通过配置KEIL的工程,可以很方便的生成两个烧写不同的位置的程序。工程属性中的【Target】,把 IROM 的起始地址和大小修改掉就可以了(也可以编写sct,在【Linker】选项中调用,会稍微麻烦一点)。另外需要注意一点 FLASH 烧写的 Erace 选项一定不能选 Erace Full Chip 。

IAP升级的详细过程

1、上电后,硬件从0x08000000+4 取出复位中断的地址,然后跳到这个地址开始执行,这里会跳到main函数,C程序开始执行。

2、当接到用户做出特定输入,要升级程序时,从 0x08010000+4 的地方取出BootLoader程序的复位中断地址,从这个地址开始执行就能进入BootLoader程序的main。

3、BootLoader程序中要做串口或者别的通信口的接收程序,接收到新的程序后校验无错误后,擦除0x08000000起始的需要的空间,然后把程序写进去。然后从0x08000000+4 取出复位中断的地址,然后跳到这个地址开始执行。

程序参考

我已经做了一个能用的BootLoader 和一个测试用的程序,点击这里查看。

TEST

test目录下的测试程序,功能是LED灯双闪。由于我的硬件没有按键,所以采用运行若干次后直接跳转到BootLoader程序准备升级。

跳转步骤包括:

1.告诉硬件新的向量表位置。

2.设置堆栈

3.调用存储在0x08010000+4 位置的函数指针,该函数永不返回。

程序如下

	SetVectorTable(NVIC_VectTab_FLASH, 0x10000);
	BootLoaderApplication = (pFunction)*(u32 *)(0x08010000 + 4);
	__set_MSP(* (u32*)0x08010000 );
	BootLoaderApplication();  

BootLoader

BootLoader程序主要工作是接收串口数据,写入应用程序的地址,为了方便观察,增加了LED三闪的部分。串口接收的部分,在MT_STM32-IAP_BLD_V0.1.x 版本将使用一个简单的通信协议。应用程序由上位机发送过来,格式目前只支持 bin,所以需要HEX2BIN工具将编译后生成的HEX文件转为BIN文件。

1.上位机发送 0xF0C33C0F 握手请求,接收正确后响应,不正确不响应。

2.上位机发送BIN文件的长度,长度实际占用低16位,高16位为长度的取反值,以保证传输正确性。接收正确响应,不正确不响应。

3.上位机开始发送 BIN 文件,一次性全部发送完成。(目前只做了小程序支持,全部放在内存中,小心内存溢出。)

通信完成后,自动开始烧写至应用程序的地址,然后应该按照步骤重新跳转过去,但是实际上发现,软复位一次更方便。两种方法功能是等效的。

一期工作结束。