-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathFW_Combin_Tool.py
128 lines (90 loc) · 4.27 KB
/
FW_Combin_Tool.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import argparse
import sys
import io
import os
import struct
import time
import zlib
import hashlib
from PyQt5.QtWidgets import QPushButton,QLineEdit,QWidget,QTextEdit,QVBoxLayout,QHBoxLayout,QFileDialog,QLabel
class FW_Tools(QWidget):
def __init__(self,parent=None):
super().__init__(parent)
self.layout=QVBoxLayout()
self.tbox_log=QTextEdit()
line_1=QHBoxLayout()
self.tbox_boot_file = QLineEdit()
label_boot=QLabel("Boot:")
btn_open_boot_file =QPushButton("···")
btn_open_boot_file.clicked.connect(lambda:self.open_file_fn('boot'))
line_1.addWidget(label_boot)
line_1.addWidget(self.tbox_boot_file)
line_1.addWidget(btn_open_boot_file)
line_1.setContentsMargins(0, 0, 0, 0)
line_2=QHBoxLayout()
self.tbox_app_file = QLineEdit()
label_app=QLabel("App: ")
btn_open_app_file =QPushButton("···")
btn_open_app_file.clicked.connect(lambda:self.open_file_fn('app'))
line_2.addWidget(label_app)
line_2.addWidget(self.tbox_app_file)
line_2.addWidget(btn_open_app_file)
line_2.setContentsMargins(0, 0, 0, 0)
line_3=QHBoxLayout()
btn_burn_triad=QPushButton("合并固件")
btn_burn_triad.clicked.connect(self.combin_fn)
line_3.addWidget(btn_burn_triad)
line_3.setContentsMargins(0, 0, 0, 0)
self.layout.addWidget(self.tbox_log)
self.layout.addLayout(line_1)
self.layout.addLayout(line_2)
self.layout.addLayout(line_3)
self.setLayout(self.layout)
def open_file_fn(self,action): #选择固件
directory = QFileDialog.getOpenFileName(self, "选择要烧录的固件",'',"固件 (*.bin)")
if len(str(directory[0])) > 5 :
if action == "boot":
self.tbox_boot_file.setText(str(directory[0]))
self.tbox_boot_file.setStyleSheet("background-color:LightGreen;")
else:
self.tbox_app_file.setText(str(directory[0]))
self.tbox_app_file.setStyleSheet("background-color:LightGreen;")
def combin_fn(self):#合并固件
if not os.path.exists(self.tbox_boot_file.text()) or os.path.getsize(self.tbox_boot_file.text()) > 0x4000:
self.tbox_boot_file.setStyleSheet("background-color:red;")
self.log_string("Boot固件不存在或大小错误")
return
if not os.path.exists(self.tbox_app_file.text()) or os.path.getsize(self.tbox_app_file.text()) > 0x2C000:
self.tbox_app_file.setStyleSheet("background-color:red;")
self.log_string("APP固件不存在或大小错误")
return
if not os.path.exists("combine/") : os.makedirs("combine/")
boot = open(self.tbox_boot_file.text(), "rb")
app = open(self.tbox_app_file.text(), "rb")
boot_app_file_name= self.tbox_app_file.text().replace('.bin','_with_boot.bin')
boot_app = open(boot_app_file_name, "w+b")
boot_app.write(boot.read()) # 将Boot固件放在合并后固件的前16K
boot.close()
boot_app.seek(0x4000,0)
app.seek(0x4000,0)
boot_app.write(app.read()) # APP 固件的 16K 之后的部分 位置不变
boot_app.seek(0x2c000,0)
app.seek(0x00000,0)
boot_app.write(app.read(0x4000)) # 将APP固件的前16K放在合并后固件的0x2C000的位置
app.close()
boot_app.seek(0, 0)
file_content = boot_app.read()
crc32_result = zlib.crc32(file_content) & 0xffffffff # 计算整个文件的CRC
boot_app.seek(176 * 1024 - 4, 0)
boot_app.write(struct.pack('>I', crc32_result)) #RAM Code 前4个字节也放置CRC校验
boot_app.seek(0, 2)
boot_app.write(struct.pack('>I', crc32_result)) #文件的最末尾处,放置CRC校验
boot_app.seek(0, 0)
file_content = boot_app.read()
md5_result = hashlib.md5(file_content).hexdigest()
boot_app.close()
self.log_string("Combine OK!\r\nFirmware CRC32: " + hex(crc32_result) +"\r\nFirmware MD5: " + md5_result + "\r\n合并好的固件为:" + boot_app_file_name)
def log_string(self, s): #Log窗口日志输出
self.tbox_log.append(s)