0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

单片机固件中加入版本信息的方式有哪些?-2

汽车电子技术 来源:大橙子疯嵌入式 作者:大橙子疯 2023-02-15 15:36 次阅读

前言

上一篇介绍完如何在程序中添加版本信息后,这篇介绍一下如何在 MCU 程序中固定位置添加程序的版本信息等。

了解

首先了解一下__attribute__机制,它是个编译器指令,告诉编译器声明的特性,或者让编译器进行更多的错误检查和高级优化。

GUN C中可以使用__attribute__()给变量、函数和类型设置各种属性,而__attribute__的section选项可以改变段的特性;

其中__attribute__((section("section_name")))的作用是将该定义的函数或数据变量放入指定名为”section_name”段中。

无论是 GNU 还是 ARM 的编译器, 都支持__attribute__所指定的编译属性。

打开keil的options…,取消勾选下图所示,然后点击“Edit…”。

图片

自动弹出“*.sct”文件(先编译通过再操作),下面就是 Keil 中 STM32 的链接文件,编译器会根据链接文件和__attribute__的section选项(可以自己添加一个段,分配地址和大小)等分配函数和数据变量在程序固件中的地址。

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00010000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00010000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   .ANY (+XO)
  }
  RW_IRAM1 0x20000000 0x00005000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

这里不做过多介绍了,下面介绍的方式不需要自己修改“*.sct”文件,还是采用__attribute__的section选项,只不过在section选项中指定位置即可。

__attribute__ ((section(".ARM.__at_0x08000020")))

实现方式

1.同样的定义一个结构体,里面定义一些软件版本相关的信息

typedef struct
{
    char szVersion[32];    // 软件版本
    char szBuildDate[32];  // 程序编译日期
    char szBuildTime[32];  // 程序编译时间
}AppInfo_t;

2.通过__attribute__定义一个只读结构体变量(只读的目的:防止程序改变、节约RAM)并固定变量在程序固件中的位置,赋初值(其中__DATE___TIME__C语言中的内置宏,分别是当前的编译日期和编译时间)。

const AppInfo_t __attribute__ ((section(".ARM.__at_0x08002000"))) sg_tAppInfo =
{
    "STM32_V0.1.5",
    __DATE__,
    __TIME__,
};

注:STM32的代码起始地址是从0x08000000开始的,且存储中断向量表信息,因此在选择程序地址的时候一定要绕开,也不能太靠后,不然生成的bin文件超出了实际的代码固件大小,在实现bin文件升级的时候就会耗时太长。

3.编译成功后打开hex文件,查看一下0x08002000所在的内容,版本信息和编译时间(之后可以通过新增代码或者变量验证是不是位置变了)

图片

4.在主函数添加打印,将版本信息输出到终端上,打印结果就不演示了,有兴趣的朋友可以翻开上一章


映像工具实现固件打包

这里采用的映像工具是srec_cat,网上有源码(点击阅读原文下载srec_cat.exe),可以编译成 Windows 或 Linux 的可执行文件;这里用这个工具来打包固件信息,比如版本号,同时修改文件名,即文件名=版本号。

通过Bat脚本实现以下功能:

  1. 不需要修改代码即可修改程序版本信息
  2. 按照当前固件打包时间作为程序的版本信息,同时按照版本信息命名文件
  3. 版本命名格式为:STM32_T2206111526

根据目录结构树编写指定脚本

MDK_STM32
    ---- CORE
    ---- STM32F10x_FWLib
    ---- OBJ(编译生成的hex文件)
    ---- USER
tool
    ---- srec_cat.exe
    ---- pack.bat

实现 pack.bat:

:: 版本信息前缀和长度
set strPrefix=STM32_
set strPrefixlen=6

:: hex 文件路径和文件名
set hexFilePath=..\\MDK_STM32\\OBJ
set hexFileName=main.hex

:: 版本信息信息起始地址
set verStringAddr=0x08002000

if %time:~0,2% leq 9 (set hour=0%time:~1,1%) else (set hour=%time:~0,2%)
if %time:~0,2% leq 9 (set minute=%time:~2,2%) else (set minute=%time:~3,2%)

:: 打包时间格式为年月日时分 T2206111526
set strTime=T%date:~2,2%%date:~5,2%%date:~8,2%%hour%%minute%
set strVersion=%strPrefix%%strTime%

:: 版本信息的起始和结束位置
set /a InfoEnd=%verStringAddr%+%strPrefixlen%+11

:: 拷贝临时文件进行处理
copy %hexFilePath%\\%hexFileName% .\\

.\\srec_cat.exe -generate %verStringAddr% %InfoEnd% -repeat-string %strVersion% %hexFilePath%\\main.hex -intel -exclude %verStringAddr% %InfoEnd% -o .\\%strVersion%.hex -intel

:: 删除临时文件
del %hexFileName%

编译完成后,双击 pack.bat 生成添加版本信息后的固件,之后需要通过J-LINK工具包打开生成的固件进行烧录(通过Keil编译下载的没有用)。

图片

图片


扩展

如果实现了 bootloader 程序,那么一定会用到寄存器SCB->VTOR重新设置中断向量表的起始地址了,所以干脆可以将版本信息放在 APP 程序区中的最开始位置,后面紧跟中断向量表的起始地址。

这样做的好处是不用担心程序编译后版本信息的位置超出了APP可执行程序的实际大小,而且在实现升级的时候bootloader程序在一开始就可以直接对版本信息进行校验等。

同时通过映像工具 srec_cat 将 bootloader 和 APP 程序固件进行合并。

也能通过 keil 在编译后自动执行脚本。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • mcu
    mcu
    +关注

    关注

    146

    文章

    16023

    浏览量

    343710
  • 程序
    +关注

    关注

    114

    文章

    3631

    浏览量

    79555
  • 版本
    +关注

    关注

    0

    文章

    15

    浏览量

    9381
收藏 人收藏

    评论

    相关推荐

    单片机固件问题

    使用一个压力传感器与C8051F单片机相连进行数据传输。编一个单片机固件,通过固件将读取到的电压信号转换成对应的压力信号。本人新手一枚,有些都不懂这其中的意思?电压信号转换成压力信号不
    发表于 06-02 22:32

    华大单片机是如何向MDK中加入头文件和库文件的

    华大单片机如何向MDK中加入头文件和库文件关键文件介绍加入头文件大多数习惯于8位单片机开发的工程师,都会使用操作寄存器的方式来使用
    发表于 07-13 08:43

    请问单片机如何向MDK中加入头文件和库文件?

    请问单片机如何向MDK中加入头文件和库文件?
    发表于 09-27 08:32

    如何在XHTML网页中加入CSS详细的五种方式说明

    本文档的主要内容详细介绍的是如何在XHTML网页中加入CSS详细的五种方式说明资料免费下载。
    发表于 06-13 16:58 5次下载

    如何使用MDK编译器让STM32程序HEX文件中加入固件版本信息

    本文介绍一个小技巧: 使用MDK编译器,让STM32程序HEX文件中加入固件版本信息。 代码 代码如下
    的头像 发表于 06-23 15:14 3591次阅读
    如何使用MDK编译器让STM32程序HEX文件<b class='flag-5'>中加入</b><b class='flag-5'>固件</b><b class='flag-5'>版本</b><b class='flag-5'>信息</b>

    华大单片机如何向MDK中加入头文件和库文件

    华大单片机如何向MDK中加入头文件和库文件关键文件介绍加入头文件大多数习惯于8位单片机开发的工程师,都会使用操作寄存器的方式来使用
    发表于 11-23 18:07 15次下载
    华大<b class='flag-5'>单片机</b>如何向MDK<b class='flag-5'>中加入</b>头文件和库文件

    SMT32的HEX文件里加入固件版本的方法

    本文介绍一个小技巧:使用MDK编译器,让STM32程序HEX文件中加入固件版本信息
    发表于 02-08 15:28 0次下载
    SMT32的HEX文件里<b class='flag-5'>加入</b><b class='flag-5'>固件</b><b class='flag-5'>版本</b>的方法

    单片机固件中加入版本信息的方法

    平时我们写程序,通常都会备注软件版本,那么,怎么在单片机中保存版本信息呢?方法其实有很多,但基本原理都是在指定存储区域(Flash)中写入软件版本
    的头像 发表于 04-18 14:50 922次阅读

    STM32程序HEX文件中加入固件版本信息

    使用MDK编译器,让STM32程序HEX文件中加入固件版本信息
    的头像 发表于 08-14 16:13 3944次阅读

    SMT32的HEX文件里加入固件版本的方法

    使用MDK编译器,让STM32程序HEX文件中加入固件版本信息
    的头像 发表于 02-01 09:37 3528次阅读

    单片机固件中加入版本信息方式有哪些?-1

    开发完MCU软件后,通常都会生成hex文件或者bin文件,用来做固件烧录或者升级,如果用来做产品开发,就涉及到固件版本的问题,初学者通常采用固件文件重命名来区分
    的头像 发表于 02-15 15:13 992次阅读
    <b class='flag-5'>单片机</b><b class='flag-5'>固件</b><b class='flag-5'>中加入</b><b class='flag-5'>版本</b><b class='flag-5'>信息</b>的<b class='flag-5'>方式</b>有哪些?-1

    单片机固件中加入版本信息方式有哪些?-3

    这篇主要介绍一下通过 Git 工具管理的程序如何在 MCU 程序版本信息中增加 Git commot 提交的 id 。
    的头像 发表于 02-15 15:38 432次阅读
    <b class='flag-5'>单片机</b><b class='flag-5'>固件</b><b class='flag-5'>中加入</b><b class='flag-5'>版本</b><b class='flag-5'>信息</b>的<b class='flag-5'>方式</b>有哪些?-3

    怎么在单片机中保存版本信息呢?

    平时我们写程序,通常都会备注软件版本,那么,怎么在单片机中保存版本信息呢?
    的头像 发表于 04-18 15:12 616次阅读

    单片机固件如何加入版本信息

    时我们写程序,通常都会备注软件版本,那么,怎么在单片机中保存版本信息呢? 方法其实有很多,但基本原理都是在指定存储区域(Flash)中写入软件版本
    发表于 08-22 09:16 197次阅读
    <b class='flag-5'>单片机</b><b class='flag-5'>固件</b>如何<b class='flag-5'>加入</b><b class='flag-5'>版本</b><b class='flag-5'>信息</b>

    SMT32的HEX文件里加入固件版本的方法

    SMT32的HEX文件里加入固件版本的方法
    的头像 发表于 09-18 15:34 405次阅读
    SMT32的HEX文件里<b class='flag-5'>加入</b><b class='flag-5'>固件</b><b class='flag-5'>版本</b>的方法