Python Intelhex- HEX文件修改器工具
提示:文章写完后,目录可
以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
前言:在进行IAP升级开发时(基于CAN的UDS FOTA功能),往往需要对App的固件进行修改,增加响应的版本号相关信息,有时还需要将HEX文件转换成bin文件。故利用python + pyqt5 开发一款修改hex文件并生成bin文件的小工具,可视化界面,支持ASCII字符录入或者HEX数据录入修改。做下记录和分享。
提示:以下是本篇文章正文内容,下面案例可供参考
一、开发环境
-
python3
-
安装pyqt5,
-
安装 intelhex 库 , window cmd下使用pip安装 pip install intelhex
二、搭建窗口界面
利用designer 工具搭建窗口界面,并利用pyuic5 库将ui文件转换成对应的界面的py文件,
pyuic5 -o xxxxx.py yyyyyy.ui 。
界面的搭建,网上有很多资料,这里不是本文重点,这里就不再说了。
三、功能的实现和intelhex库的使用
1、利用窗口中的QFileDialog控件按钮,读取加载需要修改的HEX文件
关键语句: ORIG_HEX_FILE = IntelHex(ORIG_HEX_FILE_PATH_STR)
ORIG_HEX_FILE 为定义的全局变量
def openload_hexfile(self):
global ORIG_HEX_FILE
global ORIG_HEX_FILE_PATH_STR
file_path = QFileDialog.getOpenFileName(self, "打开文件", "/", "*.hex")
try:
ORIG_HEX_FILE_PATH_STR = str(file_path[0])
ORIG_HEX_FILE = IntelHex(ORIG_HEX_FILE_PATH_STR) #利用IntelHex库打开读取HEX文件
#显示文件路径文件名
self.le_hexfile_path.clear() #清空当前文本
self.le_hexfile_path.setText(ORIG_HEX_FILE_PATH_STR)
self.pb_start_edit.setEnabled(True) #功能键使能
except:
pass
2、使用Intelhex库对Hex文件进行修改
从窗体界面获取相关信息后,点击一键修改后,即可完成对hex文件的修改,并对修改后的hex文件进行重命名另存,并同时生成bin文件,保存到原hex文件所在的目录下。主要功能代码如下:
# 修改文件
def edit_hexfile(self):
global ORIG_HEX_FILE
global ORIG_HEX_FILE_PATH_STR
enable_saveas_edithex = False
hexfile_edit_setaddr = int(self.le_edit_addr.text(),base=16)
hexfile_edit_setsize = int(self.le_edit_size.text(),base=10)
hexfile_edit_padding = int(self.le_edit_padding.text(),base=16)
#--------------- HEX模式------------------------------------------------------------
if self.cb_hex_mode.isChecked():
#删除所有非十六进制的字符
input_s = ''
text_tmp = self.te_edit_text.toPlainText()
text_tmp = text_tmp.replace('0x','')
text_tmp = text_tmp.replace('0X','')
for char in text_tmp:
if isHexChar(char):
input_s += char
input_s_len = len(input_s)
if input_s_len % 2:
QMessageBox.critical(self, "输入内容长度错误", "长度为奇数,请输入正确长度的内容!")
elif input_s_len == 0:
origbinfile_path_str = ORIG_HEX_FILE_PATH_STR[:ORIG_HEX_FILE_PATH_STR.find(".")] + ".bin"
ORIG_HEX_FILE.tobinfile(origbinfile_path_str) #save as binfile
QMessageBox.information(self, "转换成功", "未修改HEX文件仅转换为bin文件!")
else:
hexbyte_list = []
len_index = 0
while len_index < input_s_len:
byte_temp = int(input_s[len_index:len_index+2],base=16)
hexbyte_list.append(byte_temp)
len_index = len_index + 2
hexbyte_list_len = len(hexbyte_list)
if hexbyte_list_len > hexfile_edit_setsize:
QMessageBox.critical(self, "输入内容长度错误", "长度过长,请输入正确长度的内容!")
else:
current_addr = hexfile_edit_setaddr
for i in range(hexbyte_list_len):
ORIG_HEX_FILE[current_addr+i] = hexbyte_list[i]
diff_size = hexfile_edit_setsize - hexbyte_list_len
if diff_size > 0:
current_addr = hexfile_edit_setaddr + hexbyte_list_len
for i in range(diff_size):
ORIG_HEX_FILE[current_addr+i] = hexfile_edit_padding
enable_saveas_edithex = True
# -------------ASCII码模式------------------------------------------------------------------
else:
hexfile_edit_context = self.te_edit_text.toPlainText()
hexfile_edit_context_len = len(hexfile_edit_context)
if hexfile_edit_context_len > hexfile_edit_setsize:
QMessageBox.critical(self, "输入内容长度错误", "长度过长,请输入正确长度的内容!")
elif hexfile_edit_context_len == 0:
origbinfile_path_str = ORIG_HEX_FILE_PATH_STR[:ORIG_HEX_FILE_PATH_STR.find(".")] + ".bin"
ORIG_HEX_FILE.tobinfile(origbinfile_path_str) #save as binfile
QMessageBox.information(self, "转换成功", "未修改HEX文件仅转换为bin文件!")
else:
ORIG_HEX_FILE.putsz(hexfile_edit_setaddr,hexfile_edit_context)
diff_size = hexfile_edit_setsize - hexfile_edit_context_len
if diff_size > 0:
current_addr = hexfile_edit_setaddr + hexfile_edit_context_len
for i in range(diff_size):
ORIG_HEX_FILE[current_addr+i] = hexfile_edit_padding
enable_saveas_edithex = True
#----------- 开始另存------------------------------------------------------------------
if enable_saveas_edithex:
# 获取当前时间
current_time = int(time.time())
# 转换为localtime
localtime = time.localtime(current_time)
# 利用strftime()函数重新格式化时间
time_str = time.strftime('%Y%m%d%H%M', localtime)
time_str = time_str[2:]
#save as new hexfile
newhexfile_path_str = ORIG_HEX_FILE_PATH_STR[:ORIG_HEX_FILE_PATH_STR.find(".")] + "_Fota_" + time_str + ".hex"
ORIG_HEX_FILE.tofile(newhexfile_path_str, format='hex')
#save as new binfile
newbinfile_path_str = newhexfile_path_str[:newhexfile_path_str.find(".")] + ".bin"
ORIG_HEX_FILE.tobinfile(newbinfile_path_str)
QMessageBox.information(self, "修改成功", "已成功修改HEX文件并另存,同时生成bin文件!")
四.最终成品效果
1、修改前的HEX文件
App的hex固件,偏移地址是0x8010000,
2、运行该脚本进行修改HEX文件
我们的需求是在该文件头插入32个字节的文件信息,其中16个字节为有效信息,后16个字节为无效填充信息,填充字节为0xFF.
在原文件目录下生成了修改后hex文件和对应的bin文件。
2、修改后内容
看出在该hex文件头部插入了我们需求的32个字节的信息。
总结
这里代码只是简单介绍了如何使用intelhex库修改hex文件。对于pyqt窗体的应用没有做过多的描述。同时也可以将该脚本打包成.exe可执行文件,网上也有很多教程。
完整工程和源码已上传,可供参考。
https://download.csdn.net/download/yinzimu/85100462