前言
开发完MCU软件后,通常都会生成hex文件或者bin文件,用来做固件烧录或者升级,如果用来做产品开发,就涉及到固件版本的问题,初学者通常采用固件文件重命名来区分版本。
如果需要每次上电开机通过串口或者OLED等显示版本信息,那么这种方式就无法实现
下面介绍如何在程序中加入版本信息,以MDK为例介绍。
实现方式
1.定义一个结构体,里面定义一些软件版本相关的信息
typedef struct
{
char szVersion[32]; // 软件版本
char szBuildDate[32]; // 程序编译日期
char szBuildTime[32]; // 程序编译时间
}AppInfo_t;
2.定义一个只读结构体变量(只读的目的:防止程序改变、节约RAM),赋初值(其中__DATE_ 和__TIME__是C语言中的内置宏,分别是当前的编译日期和编译时间)。
const AppInfo_t sg_tAppInfo =
{
"STM32_V0.1.5",
__DATE__,
__TIME__,
};
3.在主函数添加打印,将版本信息输出到终端上。
int main(void)
{
SystemInit();
printf("Version : %srn", sg_tAppInfo.szVersion);
printf("buildTime: %srn", sg_tAppInfo.szBuildDate);
printf("buildTime: %srn", sg_tAppInfo.szBuildTime);
while (1)
{
}
}
4.在 Keil MDK 中,默认情况下,源文件不修改,只会编译一次。
如果定于sg_tAppInfo
变量的源文件没有修改而其它文件修改时,编译日期和编译时间还是之前的
为了编译版本、日期和时间正确,需要进行设置:总是编译
5.下载程序后,通过串口工具在MCU上电就能收到版本信息的打印。
扩展
从上述的实现方式可知,sg_tAppInfo
只读变量在程序中的位置不固定,有一定的局限性。
如果结构体有其他的信息,无法在编译时初始化,而是需要在程序编译后的hex文件中添加或者修改信息,但由于只读变量在程序中的位置不固定,不能保证每次编译后在固定的位置添加或者修改信息。
下一篇介绍通过__attribute__
机制固定sg_tAppInfo
只读变量在程序中的地址,同时采用映像文件工具对hex固件文件进行操作,自动将固件中的版本信息和固件文件名称关联起来。