關(guān)注+星標(biāo)公眾號(hào),不錯(cuò)過(guò)精彩內(nèi)容
作者 | strongerHuang
微信公眾號(hào) | strongerHuang
最近有粉絲在問(wèn):單片機(jī)項(xiàng)目如何添加軟件的版本信息?
軟件的版本信息我們都知道,比如:V1.0.0
針對(duì)單片機(jī)項(xiàng)目,我們需要管理軟件版本,包括源代碼,以及單片機(jī)固件(hex、bin等)。
源代碼軟件版本
你們平時(shí)怎么管理軟件的源代碼版本?
壓縮打包?不會(huì)是這樣吧?
壓縮打包這種方法不是不行,后續(xù)查閱變更有點(diǎn)麻煩。
對(duì)于有一定管理能力的公司,最好還是上軟件版本工具,比如:SVN、Git等。
早期我們用SVN比較多,后面用Git,這兩個(gè)常用的工具不難,網(wǎng)上教程很多。
固件版本
單片機(jī)固件,通常指的是hex、bin這種可執(zhí)行文件。
1、固件名稱版本
固件(hex、bin)的名稱,可以通過(guò)自動(dòng)配置自動(dòng)編譯生成。
這里可以參看我之前分享的文章:Keil定制Hex文件名實(shí)現(xiàn)的方法
2、固件中添加版本信息
我們要在單片機(jī)產(chǎn)品中讀取軟件版本的信息,就需要在固件中加入版本信息。(量產(chǎn)發(fā)貨的設(shè)備比較多,全國(guó)各地、不同版本的情況下,很有必要加入版本信息。不然,某臺(tái)設(shè)備出現(xiàn)bug,都不知道是哪個(gè)版本的軟件)
下面就分享一個(gè)最常用,也是最基礎(chǔ)的小技巧:在Keil MDK環(huán)境下,通過(guò)軟件代碼,直接映射到并存儲(chǔ)到Flash指定地址。
包含:軟件版本、編譯日期、編譯時(shí)間,代碼如下:
#define VERINFO_ADDR_BASE ? (0x0800FF00) //存放FLASH的地址
constchar?Software_Ver[] __attribute__((at(VERINFO_ADDR_BASE +?0x00))) ?=?"Software: 1.0.0";
constchar?Compiler_Date[] __attribute__((at(VERINFO_ADDR_BASE +?0x40))) =?"Date: "__DATE__;
constchar?Compiler_Time[] __attribute__((at(VERINFO_ADDR_BASE +?0x60))) =?"Time: "__TIME__;
這個(gè)代碼大家能看懂么? 其實(shí)就是把這串信息(編譯時(shí)自動(dòng)生成日期和時(shí)間)寫(xiě)入Flash。
寫(xiě)成功之后,我們讀取對(duì)應(yīng)地址,即可看見(jiàn)該版本信息,比如:
原理很簡(jiǎn)單,也有類似其他寫(xiě)入Flash地址的方法(這里暫不講述)。
這里面包含幾個(gè)重要知識(shí)點(diǎn),下面給大家描述一下。
a.__attribute__ 語(yǔ)法
attribute,翻譯為“屬性”,在C語(yǔ)言中,是一個(gè)關(guān)鍵字,語(yǔ)法格式為:
__attribute__ ((attribute-list))
__attribute__ 可以設(shè)置函數(shù)屬性(Function Attribute )、變量屬性(Variable Attribute )和類型屬性(Type Attribute )。
這部分內(nèi)容,大家可以不用深入理解,知道這么用即可。要深入理解,網(wǎng)上也有很多學(xué)習(xí)資源。
b.C語(yǔ)言標(biāo)準(zhǔn)定義
在代碼中:
constchar?Compiler_Date[] __attribute__((at(VERINFO_ADDR_BASE +?0x40))) =?"Date: "__DATE__;
constchar?Compiler_Time[] __attribute__((at(VERINFO_ADDR_BASE +?0x60))) =?"Time: "__TIME__;
你會(huì)看到__DATE__ 和?__TIME__表示的日期和時(shí)間。
其實(shí),這兩個(gè)是C語(yǔ)言特殊的標(biāo)準(zhǔn)定義。
__DATE__:編譯時(shí)刻的日期字符串 如“Apr 13 2021”__TIME__:編譯時(shí)刻的時(shí)間字符串 ?如”20:00:00“
除了這兩個(gè),其實(shí)還有很多類似的標(biāo)準(zhǔn)定義,比如:
__FILE__?:正在編譯文件的文件名__LINE__?:正在編譯文件的行號(hào)__STDC__:判斷該文件是不是標(biāo)準(zhǔn)C程序
這部分內(nèi)容,可以參看我的文章:C語(yǔ)言幾種特殊標(biāo)準(zhǔn)定義和用法
c.總是編譯版本文件
在Keil MDK中,默認(rèn)情況下,源文件不修改,只編譯一次。
因此,為了編譯版本、日期和時(shí)間正確,需要進(jìn)行設(shè)置:總是編譯。
如下設(shè)置: