日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁(yè) > > 大橙子瘋嵌入式


前言

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

了解

首先了解一下__attribute__機(jī)制,它是個(gè)編譯器指令,告訴編譯器聲明的特性,或者讓編譯器進(jìn)行更多的錯(cuò)誤檢查和高級(jí)優(yōu)化。
GUN C中可以使用__attribute__()給變量、函數(shù)和類(lèi)型設(shè)置各種屬性,而__attribute__的section選項(xiàng)可以改變段的特性;

其中__attribute__((section("section_name")))的作用是將該定義的函數(shù)或數(shù)據(jù)變量放入指定名為”section_name”段中。

無(wú)論是 GNU 還是 ARM 的編譯器, 都支持__attribute__所指定的編譯屬性。

打開(kāi)keil的options…,取消勾選下圖所示,然后點(diǎn)擊“Edit…”。

自動(dòng)彈出“*.sct”文件(先編譯通過(guò)再操作),下面就是 Keil 中 STM32 的鏈接文件,編譯器會(huì)根據(jù)鏈接文件和__attribute__的section選項(xiàng)(可以自己添加一個(gè)段,分配地址和大?。┑确峙浜瘮?shù)和數(shù)據(jù)變量在程序固件中的地址。

; *************************************************************
; *** 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)
 }
}

這里不做過(guò)多介紹了,下面介紹的方式不需要自己修改“*.sct”文件,還是采用__attribute__的section選項(xiàng),只不過(guò)在section選項(xiàng)中指定位置即可。

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

實(shí)現(xiàn)方式

1.同樣的定義一個(gè)結(jié)構(gòu)體,里面定義一些軟件版本相關(guān)的信息

typedef struct { char szVersion[32]; // 軟件版本 char szBuildDate[32]; // 程序編譯日期 char szBuildTime[32]; // 程序編譯時(shí)間 }AppInfo_t;

2.通過(guò)__attribute__定義一個(gè)只讀結(jié)構(gòu)體變量(只讀的目的:防止程序改變、節(jié)約RAM)并固定變量在程序固件中的位置,賦初值(其中__DATE_和__TIME__是C語(yǔ)言中的內(nèi)置宏,分別是當(dāng)前的編譯日期和編譯時(shí)間)。

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

注:STM32的代碼起始地址是從0x08000000開(kāi)始的,且存儲(chǔ)中斷向量表信息,因此在選擇程序地址的時(shí)候一定要繞開(kāi),也不能太靠后,不然生成的bin文件超出了實(shí)際的代碼固件大小,在實(shí)現(xiàn)bin文件升級(jí)的時(shí)候就會(huì)耗時(shí)太長(zhǎng)。

3.編譯成功后打開(kāi)hex文件,查看一下0x08002000所在的內(nèi)容,版本信息和編譯時(shí)間(之后可以通過(guò)新增代碼或者變量驗(yàn)證是不是位置變了)

4.在主函數(shù)添加打印,將版本信息輸出到終端上,打印結(jié)果就不演示了,有興趣的朋友可以翻開(kāi)上一章。


映像工具實(shí)現(xiàn)固件打包

這里采用的映像工具是srec_cat,網(wǎng)上有源碼(點(diǎn)擊閱讀原文下載srec_cat.exe),可以編譯成 Windows 或 Linux 的可執(zhí)行文件;這里用這個(gè)工具來(lái)打包固件信息,比如版本號(hào),同時(shí)修改文件名,即文件名=版本號(hào)。

通過(guò)Bat腳本實(shí)現(xiàn)以下功能:

  1. 不需要修改代碼即可修改程序版本信息

  2. 按照當(dāng)前固件打包時(shí)間作為程序的版本信息,同時(shí)按照版本信息命名文件

  3. 版本命名格式為:STM32_T2206111526

根據(jù)目錄結(jié)構(gòu)樹(shù)編寫(xiě)指定腳本

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

實(shí)現(xiàn) pack.bat:

:: 版本信息前綴和長(zhǎng)度
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%)

:: 打包時(shí)間格式為年月日時(shí)分 T2206111526
set strTime=T%date:~2,2%%date:~5,2%%date:~8,2%%hour%%minute%
set strVersion=%strPrefix%%strTime%

:: 版本信息的起始和結(jié)束位置
set /a InfoEnd=%verStringAddr%+%strPrefixlen%+11

:: 拷貝臨時(shí)文件進(jìn)行處理
copy %hexFilePath%\%hexFileName% .\

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

:: 刪除臨時(shí)文件
del %hexFileName%

編譯完成后,雙擊 pack.bat 生成添加版本信息后的固件,之后需要通過(guò)J-LINK工具包打開(kāi)生成的固件進(jìn)行燒錄(通過(guò)Keil編譯下載的沒(méi)有用)。


擴(kuò)展

如果實(shí)現(xiàn)了 bootloader 程序,那么一定會(huì)用到寄存器SCB->VTOR重新設(shè)置中斷向量表的起始地址了,所以干脆可以將版本信息放在 APP 程序區(qū)中的最開(kāi)始位置,后面緊跟中斷向量表的起始地址。

這樣做的好處是不用擔(dān)心程序編譯后版本信息的位置超出了APP可執(zhí)行程序的實(shí)際大小,而且在實(shí)現(xiàn)升級(jí)的時(shí)候bootloader程序在一開(kāi)始就可以直接對(duì)版本信息進(jìn)行校驗(yàn)等。

同時(shí)通過(guò)映像工具 srec_cat 將 bootloader 和 APP 程序固件進(jìn)行合并。
也能通過(guò) keil 在編譯后自動(dòng)執(zhí)行腳本。



本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專(zhuān)欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉