如何把版本信息固化在固件中

版本是为了方便区分管理软件迭代,通过版本号能够快速地识别软件的区别。偷懒版的嵌入式固件,工程师可能就用const类型的全局变量存放一下就结了。假设现场返回了一块故障板,通讯部分损坏或者不知道什么原因无法正常运行,那么我们如何知道当前MCU中烧录的是哪一版本的软件?什么时候编译的?假设如果能把版本信息固化在固件中一起烧录在MCU指定区域,那就可以通过获取指定区域信息快速的得知当前MCU的固件信息了。当前市面上最常用的平台是ARM系列芯片和C2000系列DSP芯片,所以本篇将会介绍两个平台的固化固件信息的方法本。

编译原理

所有平台的编译器都是存在有编译链接脚本的,在KEIL中叫SCT文件(Scatter分散加载文件),在IAR中为ICF(IAR Configuration File),在CodeComposerStudio中为CMD文件。它们的作用就是告诉编译器要把生成的固件资源放置在哪个芯片物理地址区域上。大多数编译器都默认有写好的链接脚本,不过如果有特殊需求的话,类似于本设计中的制定区域存放软件版本号这个需求,则可以通过修改链接脚本划分制定区域以及搭配特殊的C语言写法实现。

为了实现获取编译时的时间以及日期,需要借助两个个ANIS C标准宏定义,如下所示

DATE:在源文件中插入当前编译日期

TIME:在源文件中插入当前编译时间

图片

ARM平台编译操作

通过attribute((at(Target Address)))的写法,编译器会将该数组生成在制定的区域内。其中attribute是GCC(GNU C Compiler)的特性,其中keil平台使用的编译器ARM Compiler也支持这一特性,所以也称为ARMGCC编译器。

如下代码所示,以为将数组按照4字节对齐生成在指定地址区域

const uint8_t cu8RteBspVerName[]__attribute__((at(0x8059000)))__attribute__((aligned (4))) = "EU_ECU_STM32H743_A1.4.1.1"; /*在flash地址0x8059000以4字节对齐的形式存放定义的字符床*/

const uint8_t cu8RteCompileDate[]__attribute__((at(0x8059030)))__attribute__((aligned (4))) = __DATE__; /*在flash地址0x8059030以4字节对齐存放编译时的日期*/

const uint8_t cu8RteCompileTime[]__attribute__((at(0x8059040)))__attribute__((aligned (4))) = __TIME__;/*在flash地址0x8059040以4字节对齐存放编译时的时间*/

DSP平台编译操作

TI C2000系列的DSP芯片开发平台为CCS(CodeComposerStudio),使用的为C2000编译器,该编译器不支持attribute操作,故需要额外的操作。

步骤1:定义区域

首先需要在cmd文件中为用于存放软件版本信息划分指定flash区域。一个cmd文件中由memory和sections构成,其中memory是用来声明存储空间,sections是用作空间分配的

MEMORY

{

PAGE 0:

...

SoftVersion : origin = 0x33Fa00, length = 0x000100   /* 划分一块区域名称SoftVersion ,起始地址为0x33fa00,长度为0x100区域*/

...

}

SECTIONS

{

...

BSP_INFO:>  FLASHA_SoftVersion ,PAGE 0  /声明标签BSP_INFO,调用该标签能把数据存放在PAGE0的FLASHA_SoftVersion区域中/

...

}

随后通过#prama DATA_SECTION(数组名,”标签名”)的形式则可以把数据放置在指定区域内、

#pragma DATA_SECTION(cu8RteBspVerName,"BSP_INFO")/*cu8RteBspVerName数组编译的时候存放在CMD中声明的BSP_INFO区域*/
const u8 cu8RteBspVerName[] = "EU_AC_F28377D_A1.2.1.0";

#pragma DATA_SECTION(cu8RteBspVer,"BSP_INFO")
const u8 cu8RteBspVer[] = {1,4,1,1};

#pragma DATA_SECTION(cu8RteCompileDate,"BSP_INFO")
const u8 cu8RteCompileDate[] = __DATE__;

#pragma DATA_SECTION(cu8RteCompileTime,"BSP_INFO")
const u8 cu8RteCompileTime[] = __TIME__;

该方法的缺点是虽然数据是放置该区域内,但是数据的顺序是有随机性的,所以如果需要严格放置在指定地址,则需要细化声明一下各个数据,将一个大的memory划分成若干个小的memory,然后用各个section去对应。

效果验证

按照上述的操作后分别使用KEIL和CSS对编辑好的工程进行编译,得出如下所示的效果,可见成功实现了将固件生成在了指定FLASH区域。ARM生成在0x8059000起始的地址;DSP生成在0x33Fa00起始的地址。

图片

图片

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值