张思聪+胡社教
摘 要:随着嵌入式设备的广泛应用,对嵌入式设备程序升级的要求也越来越高。在探讨应用编程(IAP)原理的基础上,设计一种基于STM32的充电桩系统远程升级方案。系统阐述了在应用中编程的技术原理以及升级流程,并通过TFTP方案实现了充电桩固件远程升级。实际应用表明,该方案具有较高的应用价值和推广价值。
关键词:STM32;Flash;在应用中编程(IAP);远程升级;充电桩
DOIDOI:10.11907/rjdk.162697
中图分类号:TP319
文献标识码:A 文章编号:1672-7800(2017)007-0077-04
0 引言
随着新能源电动汽车的推广与普及,电动汽车配套设施充电桩正在蓬勃发展。当前充电桩的布设往往采取建立充电站的形式,各充电站之间距离远,充电桩数量多。充电桩设备投入使用后,由于程序本身的漏洞或者用户新的需求,需要对桩程序进行升级。传统的升级方法是相关技术人员到现场用代码烧写工具对设备进行升级,工作量大,升级过程复杂。本文提出的基于STM32的充电桩远程升级方案,可以让用户通过以太网实现对目标充电桩系统程序的实时更新,提高充电桩系统的可拓展性和可维护性。
1 设计原理
1.1 STM32存储原理
STM32是一种32位微处理器[1],共有4GB线性地址空间,分为8个存储块,每个存储块512MB。第一块为代码区,用来存储程序的代码文件以及常量,主要分为嵌入式闪存、系统存储区、选项字节等。第二块内部包含嵌入式SRAM区等,程序的变量以及堆栈存储在这一块。不同型号的STM32芯片,闪存存储器(Flash)容量也不同[2],最小的只有16K字节,最多的能达到1 024K字节[3]。本方案采用的STM32F207微控制器具有1 024K的Flash,起始地址为0x80000000,终止地址为0x080FFFFF,总共分为12个扇区,其中0~3号扇区大小为16K,4号扇区大小为64K,5~11号扇区大小为128K,Flash模块组织如表1所示。
1.2 IAP原理
IAP(In-Application Programming)是指在用户程序运行过程中对其Flash区域进行程序烧写[4],烧写完成后,运行新的程序,完成升级。要实现IAP功能,需要将项目代码分成两部分进行设计。第一部分称为装载区,即Bootload区,这一区域程序主要用来判断设备是否需要进行用户程序升级并进行相应的跳转,装载区代码必须从Flash首地址开始烧写。第二部分称为用户区,即App区,这一区域用来存放真正的功能代码。两部分代码分别存储在Flash的不同地址上,设备上电以后系统首先执行装载区程序,并根据是否需要升级跳转执行升级代码或者用户代码。在实际设计过程中,可以设计多个App区,以防止在升级失败时系统可以运行之前的程序。
2 IAP的实现
2.1 装载程序
装载程序是IAP实现过程中最重要的一步,在进行装载程序设计时,需要保证逻辑清晰、代码简明。当设备上电开始运行时,系统从Flash的首地址即0x8000000开始执行装载程序。首先完成的是STM32的初始化工作,包括堆栈和内核的初始化。接着读取存储器中的用户升级标志位[5],若标志位为0x55,则说明没有升级请求,程序跳转执行用户区代码;若标志位为0xAA,说明有升级请求,需要对用户程序进行更新,接下来要对时钟和外设进行相应的初始化,并在主循环中等待用户程序文件写入FLash的用户程序区,接受完成后将用户升级标志位置为0x55,同时执行软件复位。整个装载程序的流程如图1所示。
要保证装载程序能够正常运行,需注意两个方面:一是在跳转执行用户程序时,要将程序指针重定向并指向程序用户程序起始地址,堆栈指针指向用户堆栈的起始地址;二是在将用户程序文件写入Flash之前需要对Flash进行解锁并擦除当前Flash区域中的代码。
2.1.1 跳转实现
STM32内部通过中断向量表来响应中断,程序正常启动时,将首先从中断向量表中取出复位中断向量执行复位中断程序完成启动。中断向量表的起始地址是0x80000004[6],当有中断来临时,STM32内部硬件机制会将PC指针强制指向中断向量表处,并根据中断源取出对应中断向量执行中断服务程序。加入IAP以后,如果没有升級请求,程序需跳转执行用户代码,启动流程如图2所示。
(1)STM32复位后,从0x80000004取出复位中断向量的地址,并跳转到复位中断服务程序,在执行完中断复位程序之后跳转到IAP的main函数当中。
(2)在执行完IAP以后(如果需要新的用户代码写入Flash或者没有更新直接跳转,用户代码的复位中断向量起始地址应为0x80000004+N+M)跳转至用户程序的复位中断向量表。
(3)取出用户程序的复位中断向量地址,并跳转执行新程序的复位中断服务程序,随后跳转至新程序的main函数。
(4)在main函数死循环(while(1))中,如果有中断请求,应注意在Flash上有两个中断向量表,PC指针被强制跳转到地址0x80000004中断向量地址处,而不是用户程序的中断向量表。
(5)程序再根据设置的中断向量偏移量,跳转到对应中断源的用户中断服务程序中。
(6)执行完中断服务程序后,程序返回main函数继续执行。跳转部分的代码如下:
//定义pFunction为函数指针数据类型
typedef void (*pFunction)(void);
//定义Jump_To_Application为函数指针
pFunction Jump_To_Application;
//定义一个32位的跳转地址
uint32_t JumpAddress;
//取出存储器中的升级标志位
Flag=Rx1_Buffer[0];
//判断是否需要升级
If(Flag==0x55)
{
//判断用户的栈定地址值是否在,0x20000000~0x20002000之间
if(((*(__IOuint32_t*)USER_FLASH_FIRST_PAGE_ADDRESS) & 0x2FFE0000 ) == 0x20000000)
{
//取复位地址
JumpAddres = *(__IO uint32_t*) (USER_FLASH_FIRST_PAGE_ADDRESS + 4);
//强制转化为函数指针
Jump_To_Application = (pFunction)JumpAddress;
//将用户代码的栈顶地址设为栈顶指针
_set_MSP(*(_IO uint32_t*) USER_FLASH_FIRST_PAGE_ADDRESS);
//设置程序指针为复位地址
Jump_To_Application();
}
}
2.1.2 Flash编程
在进行IAP过程中,接收到的数据必须写入STM32的Flash中。在对STM32的Flash进行擦除或者写操作时,必须先打开内部的RC振荡器(HSI),然后对Flash编程控制器进行解锁,再对需要写入数据的Flash扇区进行擦除操作,最后进行写操作。需要注意的是,在写操作完成后必须对Flash编程控制器进行锁定[7-8]。具体实现Flash编程代码如下:
//初始化Flash,包括打开RC振荡器和解锁Flash编程控制器
FLASH_If_Init();
//擦除从USER_FLASH_FIRST_PAGE_ADDRESS开始的指定扇区
FLASH_If_Erase(USER_FLASH_FIRST_PAGE_ADDRESS);
//从Flash_Write_Address地址开始将数据写入扇区,数据为data_buffer,写入的长度为count
FLASH_If_Write(&Flash_Write_Address, data_buffer ,count)
2.2 用户程序
用户程序是一套完整的可以独立运行的程序,它除了实现特定的目标功能外,还要求能够接受升级指令并且跳转至装载程序[9]。从图2可以看出,在IAP过程结束后,Flash上存储了包括装载程序和用户程序在内的两张“中断向量表”,即有两个中断向量起始地址。在用户程序正常运行过程中,如果有中断请求,PC指针被强制跳转到地址0x80000004中断向量地址处,而不是用户程序的中断向量表,这就造成了中断向量表的起始地址和用户程序的中断处理程序之间出现了偏移量。因此,需要对用户程序的中断向量偏移量进行重定向,即配置向量表偏移量寄存器[10]。用户程序中可以通过以下代码对中断向量偏移量进行设置:
//VectTab 起始地址,Offset 偏移量
Void NVIC_SetVectorTable(u32_t VectTab, u32_t Offset)
用户程序在初始化过程中完成中断向量偏移量的重定向,然后执行相应的功能。在主函数运行过程中利用中断或者轮询接收远程升级指令,在接收到远程升级指令后,用户程序会根据自身工作状态选择是否进行升级,若状态允许,则改变升级标志位并写入存储器,同时进行软件复位,使系统开始执行装载程序。整个用户程序流程图如图3所示。
3 实际应用
在实际应用中,采用一种基于TFTP(简单文件传输协议)的IAP方案,它广泛应用于嵌入式应用当中并且通过以太网实现对充电桩的远程升级。这种升级方案运行在Lwip协议栈上,Lwip协议栈是瑞典计算机科学院开发的TCP/IP协议套件的一种轻量级实现,减少了内存使用率和代码大小,适合资源有限的嵌入式系统。
简单文件传输协议(TFTP)是工作在UDP传输层上的一种简单的文件传输协议。它基于客户端/服务器架构体系,文件传输是从TFTP客户端发起的,TFTP客户端向TFTP服务器发送读或写请求。当服务器确认请求以后,文件数据传输开始,数据按照固定大小的数据块发送,一般是512字节的数据块。必须在每个传输的数据块被接收端响应以后,发送端才能发送下一个数据块,这种回应机制是通过随每个数据块一起发送的数据块编号来实现的。当检测到接收的数据块大小小于固定数据块大小时,表示文件传输结束。TFTP包格式如图4所示。
TFTP操作码如表2所示。
在对充电桩的远程升级过程中,充电桩作为TFTP服务器,接受PC客户端发来的写请求。服务器将接收到的数据写入STM32的用户Flash区,当接收到的数据块小于512个字节时,可以判断文件传输结束,此时修改升级标志位并重启MCU完成升级过程。使用TFTP实现IAP操作的流程图如图5所示。
4 结语
本文设计并实现了基于STM32控制器的充电桩远程升级系统,介绍了STM32的存储原理、应用编程(IAP)原理以及IAP实现过程中的重要技术,实现了基于TFTP协议的远程升级。通过以太网进行远程升级与传统嵌入式设备的程序升级方式相比具有较大的优势,能有效节约时间,降低人员成本,提高系统的可扩展性和可维护性,具有较高的推广价值。
参考文献:
[1]Joseph Yiu.宋岩译.ARM Cortex-M3权威指南[M]. 北京:北京航空航天大学出版社,2009.
[2]意法半导体(中国)投资有限公司.STM32参考手册[EB/OL].www.stmcu.org,2009.
[3]黄智伟,王兵,朱卫华.STM32F32位ARM微控制器应用设计与实践[M].北京:北京航空航天大学出版社,2012:3-4.
[4]姜晓梅,李祥和,任朝荣,等.基于ARM的在线及远程升级技术[J].计算机应用,2008(2):519-521.
[5]阙凡博.基于stm32的程序远程升级设计[J].仪器仪表用户,2013(5):90-92.
[6]蒙博宇.STM32自学笔记[M].北京:北京航空航天大学出版社,2012:395-399.
[7]STM32F2x7 in application programming(IAP) over ethernet[Z].STMicroelectronics,2011.
[8]孙伟,郭宝亮,陈龙.便携式水听器测试仪的研究与实现[J].仪器仪表学报,2011,32(2):375-380.
[9]李興鹤,蔡亮,宋吉波,等.STM32用户基于IAP的程序更新技术[J].单片机与嵌入式系统应用,2012(1):74-75.
[10]张岩松,葛俊锋,叶林,等.基于STM32的程序远程升级设计与实现[J].电子设计工程,2016(1):131-134.