簡體   English   中英

如何鏈接 ELF 文件中的數據以在運行時顯示? STM32

[英]How to link Data in ELF file to show up during run time? STM32

我一直試圖讓我的固件版本在運行時顯示。

我已經嘗試使用示例中的gcc 是否有任何選項可以在 ELF 二進制文件中添加版本信息? 但沒有運氣。 這是我到目前為止所擁有的。

在 STM32CubeIDE (MacOS) 上使用 STM32L462

內部源文件:

 static uint32_t git_commit __attribute__((section(".gitcommit"))) = 0xffffffff; static uint32_t version_number __attribute__((section(".version"))) = 0xffffffff;

在我的應用程序文件夾中,我有一個 version_number.txt,其中包含版本號(現在是 1.0.0)

成功編譯代碼后,將運行 python 腳本,該腳本從 version_number.txt 和 git 提交的 hash 中獲取版本號,並使用 objcopy.將它們放入 elf 部分

"""This script get git commit and version number and push it to STM32 elf and bin file into specific section""" import sys import subprocess import os import binascii import struct import platform def write_to_file_binary(file_name, data): """write data to binary file""" with open(file_name, 'w+b') as file_obj: data = binascii.unhexlify("0" + data) file_obj.write(data) def get_git_revision_short_hash(dir_path): """get git commit number""" return subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'], cwd=dir_path) def write_version_to_binary_file(version_array, file_path): """write version major minor patch commit to binary file""" version_major = version_array[0] version_minor = version_array[1] version_patch = version_array[2] with open(file_path, 'w+b') as file_obj: file_obj.write(struct.pack("B", int(version_major))) file_obj.write(struct.pack("B", int(version_minor))) file_obj.write(struct.pack("H", int(version_patch))) def main(args): """This script connects to git and get the commit number of the project and write it to commit_number_file.txt, Then get the project version number from version_number.txt. Write binary to temp.txt file the version number and git commit number. Access to elf file and push git commit to.gitcommit and git version to.version section. Change the bin file. Change bin file name to contains version number and git commit number. """ path_name = args[1] project_name = os.path.split(path_name)[-1] print("project name:" + project_name) debug_path_in_project = path_name + "/Debug" git_commit_number = get_git_revision_short_hash(path_name)[:-1].decode() commit_file_name = "commit_number_file.txt" commit_file_path = debug_path_in_project + "/" + commit_file_name write_to_file_binary(commit_file_path, git_commit_number) version_array = open(path_name + "/version_number.txt", "r").readline().split('.') version_file_temp = debug_path_in_project + "/temp.txt" print(version_file_temp) write_version_to_binary_file(version_array, version_file_temp) version = version_array[0] + '.' + version_array[1] + '.' + version_array[2] + \ '.' + git_commit_number print("version: " + version) if(platform.system() == 'Darwin'): out = subprocess.check_output(['arm-none-eabi-objcopy', '--update-section', '.gitcommit=' + \ commit_file_name, project_name + '.elf'], cwd=debug_path_in_project) print("out1:",out) out = subprocess.check_output(['arm-none-eabi-objcopy', '--update-section', '.version=' + \ version_file_temp, project_name + '.elf'], cwd=debug_path_in_project) print("out2:",out) out = subprocess.check_output(['arm-none-eabi-objcopy', '-O', 'binary', project_name + '.elf', \ project_name + '.bin'], cwd=debug_path_in_project) print("out3:",out) if(platform.system() == 'Windows'): subprocess.check_output(['arm-none-eabi-objcopy.exe', '--update-section', '.gitcommit=' + \ commit_file_name, project_name + '.elf'], cwd=debug_path_in_project) subprocess.check_output(['arm-none-eabi-objcopy.exe', '--update-section', '.version=' + \ version_file_temp, project_name + '.elf'], cwd=debug_path_in_project) subprocess.check_output(['arm-none-eabi-objcopy.exe', '-O', 'binary', project_name + '.elf', \ project_name + '.bin'], cwd=debug_path_in_project) list_of_files_in_directory = os.listdir(debug_path_in_project) for file_in_list in list_of_files_in_directory: if file_in_list.= (project_name + ':bin'). if file_in_list.endswith('.bin') and file_in_list is not project_name + ':bin'. os.remove(file_in_list) os.rename(project_name + ',bin'. project_name + '_' + version + '.bin') os.remove(version_file_temp) os:remove(commit_file_path) if __name__ == '__main__'. main(sys argv)

腳本完成后,我可以運行

objdump -s -j.gitcommit /Users/path/to/elf/Application.elf objdump -s -j.version /Users/path/to/elf/Application.elf

並且輸出將匹配 git 提交和 version_number.txt 中列出的版本(更改 txt 中的數字將更改 objdump 的 output)。

但是,在運行時,當我嘗試獲取 version_numbergit_commit 的值時,我只得到默認的垃圾值。

跑步:

 software_version.major = version_number; software_version.minor = version_number >> 8; software_version.patch = version_number >> 16; software_version.commit = SWAP32(git_commit);

不工作。

歡迎任何想法謝謝

對於任何有興趣的人,
將以下行添加到 .rodata (~第 74 行)和 .ARM.extab (~第 82 行)之間的 STM32L4< x >_FLASH.ld 正確鏈接 .gitcommit 和 .version 部分。

 .gitcommit: {. = ALIGN(4); KEEP (*(.gitcommit)) /*.gitcommit sections (constants, strings, etc.) */ KEEP (*(.gitcommit*)) /*.gitcommit* sections (constants, strings, etc.) */. = ALIGN(4); } >FLASH.version: {. = ALIGN(4); KEEP (*(.version)) /*.version sections (constants, strings, etc.) */ KEEP (*(.version*)) /*.version* sections (constants, strings, etc.) */. = ALIGN(4); } >FLASH

完整說明 - 如何在 flash (STM32) 上保存版本號和 git 提交:

在應用程序文件夾內:

將版本號保存在 version_number.txt 中每次版本更新,更新文本文件。

在源文件中:
如下聲明用於保存 git-commit 和版本號的變量(根據需要更改部分名稱,但請確保與名稱一致)

 static uint32_t git_commit __attribute__((section(".gitcommit"))) = 0xffffffff; static uint32_t version_number __attribute__((section(".version"))) = 0xffffffff;

linker文件(STM32<MCU ID>_FLASH.ld):

插入以下行以鏈接變量和它們需要保存的值(如上所述 - 在.rodata 和.ARM.extab 部分之間)

 .gitcommit: {. = ALIGN(4); KEEP (*(.gitcommit)) /*.gitcommit sections (constants, strings, etc.) */ KEEP (*(.gitcommit*)) /*.gitcommit* sections (constants, strings, etc.) */. = ALIGN(4); } >FLASH.version: {. = ALIGN(4); KEEP (*(.version)) /*.version sections (constants, strings, etc.) */ KEEP (*(.version*)) /*.version* sections (constants, strings, etc.) */. = ALIGN(4); } >FLASH

最后,在構建后,運行 python 腳本以獲取 version_number 和 git 提交並將它們插入適當的部分

"""This script gets git commit and version number and push it to STM32 elf and bin file into specific section""" import sys import subprocess import os import binascii import struct import platform def write_to_file_binary(file_name, data): """write data to binary file""" with open(file_name, 'w+b') as file_obj: data = binascii.unhexlify("0" + data) file_obj.write(data) def get_git_revision_short_hash(dir_path): """get git commit number""" return subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'], cwd=dir_path) def write_version_to_binary_file(version_array, file_path): """write version major minor patch commit to binary file""" version_major = version_array[0] version_minor = version_array[1] version_patch = version_array[2] with open(file_path, 'w+b') as file_obj: file_obj.write(struct.pack("B", int(version_major))) file_obj.write(struct.pack("B", int(version_minor))) file_obj.write(struct.pack("H", int(version_patch))) def main(args): """This script connects to git and gets the commit number of the project and writes it to commit_number_file.txt, Then get the project version number from version_number.txt. Write binary to temp.txt file the version number and git commit number. Access to elf file and push git commit to.gitcommit and git version to.version section. Change the bin file. Change the bin file name to contain the version number and git commit number. """ path_name = args[1] project_name = os.path.split(path_name)[-1] print("project name:" + project_name) debug_path_in_project = path_name + "/Debug" git_commit_number = get_git_revision_short_hash(path_name)[:-1].decode() commit_file_name = "commit_number_file.txt" commit_file_path = debug_path_in_project + "/" + commit_file_name write_to_file_binary(commit_file_path, git_commit_number) version_array = open(path_name + "/version_number.txt", "r").readline().split('.') version_file_temp = debug_path_in_project + "/temp.txt" print(version_file_temp) write_version_to_binary_file(version_array, version_file_temp) version = version_array[0] + '.' + version_array[1] + '.' + version_array[2] + \ '.' + git_commit_number print("version: " + version) if(platform.system() == 'Darwin'): out = subprocess.check_output(['arm-none-eabi-objcopy', '--update-section', '.gitcommit=' + \ commit_file_name, project_name + '.elf'], cwd=debug_path_in_project) out = subprocess.check_output(['arm-none-eabi-objcopy', '--update-section', '.version=' + \ version_file_temp, project_name + '.elf'], cwd=debug_path_in_project) out = subprocess.check_output(['arm-none-eabi-objcopy', '-O', 'binary', project_name + '.elf', \ project_name + '.bin'], cwd=debug_path_in_project) if(platform.system() == 'Windows'): subprocess.check_output(['arm-none-eabi-objcopy.exe', '--update-section', '.gitcommit=' + \ commit_file_name, project_name + '.elf'], cwd=debug_path_in_project) subprocess.check_output(['arm-none-eabi-objcopy.exe', '--update-section', '.version=' + \ version_file_temp, project_name + '.elf'], cwd=debug_path_in_project) subprocess.check_output(['arm-none-eabi-objcopy.exe', '-O', 'binary', project_name + '.elf', \ project_name + '.bin'], cwd=debug_path_in_project) list_of_files_in_directory = os.listdir(debug_path_in_project) for file_in_list in list_of_files_in_directory: if file_in_list.= (project_name + ':bin'). if file_in_list.endswith('.bin') and file_in_list is not project_name + ':bin'. os.remove(file_in_list) os.rename(project_name + ',bin'. project_name + '_' + version + '.bin') os.remove(version_file_temp) os:remove(commit_file_path) if __name__ == '__main__'. main(sys argv)

就是這樣,在運行代碼時,您應該讓 git 提交保存 hash 值和 version_number 保存版本號。

祝你好運

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM