简体   繁体   English

如何链接 ELF 文件中的数据以在运行时显示? STM32

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

I am stuck trying to have my FW version show up at run-time.我一直试图让我的固件版本在运行时显示。

I have tried using the example from Does gcc have any options to add version info in ELF binary file?我已经尝试使用示例中的gcc 是否有任何选项可以在 ELF 二进制文件中添加版本信息? But with no luck.但没有运气。 Here is what i have so far.这是我到目前为止所拥有的。

Using STM32L462 on STM32CubeIDE (MacOS)在 STM32CubeIDE (MacOS) 上使用 STM32L462

Inside source file:内部源文件:

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

Inside my Application folder, I have a version_number.txt which contains the version number (for now 1.0.0)在我的应用程序文件夹中,我有一个 version_number.txt,其中包含版本号(现在是 1.0.0)

Once the code successfully compies, a python script runs which takes the version number from the version_number.txt and the hash of the git commit and places them inside the elf sections using objcopy.成功编译代码后,将运行 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)

Once the script finishes i can run脚本完成后,我可以运行

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

And the outputs will match the git commit and the version that is listed in the version_number.txt (changing the number in txt will change the output for objdump).并且输出将匹配 git 提交和 version_number.txt 中列出的版本(更改 txt 中的数字将更改 objdump 的 output)。

However, during run-time when I try to get the value of version_number or git_commit I get only default garbage values.但是,在运行时,当我尝试获取 version_numbergit_commit 的值时,我只得到默认的垃圾值。

Running:跑步:

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

Does not work.不工作。

Any ideas are welcome Thank you欢迎任何想法谢谢

For Anyone who is interested,对于任何有兴趣的人,
adding the following lines to the STM32L4< x >_FLASH.ld between the.rodata (~line 74) and the.ARM.extab (~line 82) links the.gitcommit and.version section properly.将以下行添加到 .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

Full Explanation - How to have version number and git commit saved on flash (STM32):完整说明 - 如何在 flash (STM32) 上保存版本号和 git 提交:

Inside the Application Folder:在应用程序文件夹内:

Keep the version number inside a version_number.txt Every version update, update the text file.将版本号保存在 version_number.txt 中每次版本更新,更新文本文件。

Within the source files:在源文件中:
Declare your variables for holding the git-commit and version number as follows (change section names as you wish but be sure to be consistent with the names)如下声明用于保存 git-commit 和版本号的变量(根据需要更改部分名称,但请确保与名称一致)

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

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

insert the following lines to link between the variables and the values they need to hold (as mentioned above - between the.rodata and.ARM.extab sections)插入以下行以链接变量和它们需要保存的值(如上所述 - 在.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

Finally, as post-build, run the python script to take the version_number and git commit and insert them into the proper sections最后,在构建后,运行 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)

That's it, when running the code you should have git commit hold the hash value and version_number hold the version number.就是这样,在运行代码时,您应该让 git 提交保存 hash 值和 version_number 保存版本号。

Good Luck祝你好运

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM