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