调整脚本结构, 清理冗余代码;

This commit is contained in:
何 泽隆
2024-08-29 16:53:28 +08:00
parent 5cb2a423c6
commit 7bbe0a08ef
8 changed files with 468 additions and 267 deletions

View File

@@ -2,7 +2,7 @@ import time
import socket
import random
from pathlib import Path
from utl import trans_list_to_str
from tools.ByteConv import trans_list_to_str
from func_frame import make_frame_modbus, check_frame_modbus
modbus_map = {

View File

@@ -1,7 +1,7 @@
import time
from pathlib import Path
from serial import Serial
from utl import trans_list_to_str
from tools.ByteConv import trans_list_to_str
from func_frame import make_frame_dlt645, check_frame_dlt645
modbus_map = {
@@ -92,7 +92,7 @@ modbus_map = {
0xA6: ["抖动频率下限", 2],
0xA7: ["电池电压判断限值", 2],
0xA8: ["MPPT追踪模式", 1],
0xA9: ["ADC参考电压", 1],
0xA9: ["ADC参考电压", 2],
0xAA: ["保留", 1],
0xAB: ["保留", 1],
0xAC: ["保留", 1],
@@ -346,11 +346,11 @@ if __name__=='__main__':
"Log": {'com_name': None,
# 'addr_645': [0x01, 0x00, 0x00, 0x00, 0x00, 0x40],
},
"Debug": {'com_name': 'COM8', 'baudrate': 115200, 'parity': 'N', 'bytesize': 8, 'stopbits': 1,
"Debug": {'com_name': 'COM11', 'baudrate': 115200, 'parity': 'N', 'bytesize': 8, 'stopbits': 1,
# 'addr_645': [0x01, 0x02, 0x03, 0x04, 0x05, 0x06],
'frame_print': True,
'time_out': 0.1, 'retry': 1, 'retry_sub': 10},
"HPLC": {'com_name': 'COM4', 'baudrate': 9600, 'parity': 'E', 'bytesize': 8, 'stopbits': 1,
"HPLC": {'com_name': 'COM10', 'baudrate': 9600, 'parity': 'E', 'bytesize': 8, 'stopbits': 1,
# 'addr_645': [0x01, 0x02, 0x03, 0x04, 0x05, 0x06],
'frame_print': True,
'time_out': 0.5, 'retry': 3, 'retry_sub': 10},
@@ -361,6 +361,22 @@ if __name__=='__main__':
dev_lamina.frame_read(0x0100, 0x20)
if 0:
dev_lamina.frame_read(0xA9, 1) # 读ADC参考电压
dev_lamina.frame_write_one(0xA9, 2000) # 写ADC参考电压:2.0V
dev_lamina.frame_write_one(0xA9, 3300) # 写ADC参考电压:3.3V
dev_lamina.frame_read(0x13, 1) # 读输入电压
dev_lamina.frame_read(0x16, 1) # 读输出电压
dev_lamina.frame_read(0x97, 4) # 读校准参数: Vin_a, Vin_b, Vout_a, Vout_b
dev_lamina.frame_write_one(0x97, 1000) # 写校准参数Vin_a: 1.000
dev_lamina.frame_write_one(0x97, 1500) # 写校准参数Vin_a: 1.500
dev_lamina.frame_write_one(0x98, 100) # 写校准参数Vin_b: 1.00
dev_lamina.frame_write_one(0x98, 150) # 写校准参数Vin_b: 1.50
dev_lamina.frame_write_one(0x99, 1000) # 写校准参数Vout_a: 1.000
dev_lamina.frame_write_one(0x99, 1500) # 写校准参数Vout_a: 1.500
dev_lamina.frame_write_one(0x9A, 1000) # 写校准参数Vout_a: 1.00
dev_lamina.frame_write_one(0x9A, 1500) # 写校准参数Vout_a: 1.50
if 0:
dev_lamina.frame_write_str(0x82, [0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA])
dev_lamina.frame_write_str(0x82, [0x00, 0x00, 0x00, 0x00, 0x00, 0x00])
@@ -434,7 +450,7 @@ if __name__=='__main__':
dev_lamina.frame_read(0x0170, 0x30)
if not hasattr(__builtins__,"__IPYTHON__"):
path_bin = Path(r"D:\WorkingProject\LightStackAdapter\software\lamina_adapter\tools\upgrade\SLCP001_240604_1200_V1.01a.bin")
path_bin = Path(r"D:\WorkSpace\UserTool\SelfTool\FrameParser\test\p460\result\lamina_adapter_t1.dat")
# path_bin = Path(r"D:\WorkingProject\LightStackAdapter\software\lamina_adapter\tools\upgrade\SLCP001_240520_0000_T1.11.bin")
# 生产镜像版本
# path_bin = Path(r"D:\WorkingProject\LightStackAdapter\software\lamina_adapter\tools\upgrade\SLCP001_240525_1800_V1.12.bin")

View File

@@ -1,8 +1,10 @@
import time
from pathlib import Path
from serial import Serial
from utl import trans_list_to_str
from tools.ByteConv import trans_list_to_str
from tools.IntelHex import file_Bin_to_IntelHex
from func_frame import make_frame_modbus, check_frame_modbus
from func_upgrade import GenerateImage_DLSP001_p280039, GeneratePackage_DLSP001_p280039
modbus_map = {
# 1 - Hex
@@ -329,15 +331,73 @@ def test_communication(time_out=2):
print(f"Success Rate: {log_success / (log_success + log_failed) * 100}%")
dev_lamina.flag_print = saveconfig_print
def make_Image():
""" 叠光控制器DSP镜像与升级包生成流程 """
root = Path(r"test\p280039")
result = Path(r"test\p280039\result")
# 正常启动镜像
hex_boot = root / r"DLSP001_240828_0900_BL1.01.hex"
hex_main = root / r"DLSP001_240828_0900_V1.01.hex"
hex_back = root / r"DLSP001_240828_0900_B1.01.hex"
hex_update = root / r"DLSP001_240828_0900_T1.01.hex"
file_image = result / f'{hex_main.stem}_ROM.hex'
file_main_header = result / 'header_main.bin'
file_back_header = result / 'header_back.bin'
file_package = result / f'{hex_update.stem}.dat'
file_update_bin = result / f'{hex_update.stem}.bin'
file_package_buffer = result / f'{hex_update.stem}.datbuffer'
data_bins = GenerateImage_DLSP001_p280039(hex_boot, hex_main, hex_back)
data_package, data_update_bin = GeneratePackage_DLSP001_p280039(hex_update)
data_buffer = bytearray(2 * len(data_package))
for i in range(len(data_package)):
data_buffer[2*i] = data_package[i]
file_package.write_bytes(data_package)
file_main_header.write_bytes(data_bins[1])
file_back_header.write_bytes(data_bins[2])
file_update_bin.write_bytes(data_update_bin)
file_package_buffer.write_bytes(data_buffer)
data_hex = file_Bin_to_IntelHex(data_bins[0], 0x80000, memory_width=2)
file_image.write_text(data_hex)
# 异常镜像-主分区md5错误
file_image1 = result / f'{file_image.stem}_b1.hex'
data_image = data_bins[0].copy()
data_image[2 * 0x006018: 2 * 0x00601A] = [0x00, 0x01, 0x00, 0x02]
data_hex = file_Bin_to_IntelHex(data_image, 0x80000, memory_width=2)
file_image1.write_text(data_hex)
# 异常镜像-备份分区md5错误
file_image2 = result / f'{file_image.stem}_b2.hex'
data_image = data_bins[0].copy()
data_image[2 * 0x007018: 2 * 0x00701A] = [0x00, 0x01, 0x00, 0x02]
data_hex = file_Bin_to_IntelHex(data_image, 0x80000, memory_width=2)
file_image2.write_text(data_hex)
# 异常镜像-双分区md5错误
file_image3 = result / f'{file_image.stem}_b3.hex'
data_image = data_bins[0].copy()
data_image[2 * 0x006018: 2 * 0x00601A] = [0x00, 0x01, 0x00, 0x02]
data_image[2 * 0x007018: 2 * 0x00701A] = [0x00, 0x01, 0x00, 0x02]
data_hex = file_Bin_to_IntelHex(data_image, 0x80000, memory_width=2)
file_image3.write_text(data_hex)
if __name__=='__main__':
mode_config = {
"Log": {'com_name': None,
# 'addr_645': [0x01, 0x00, 0x00, 0x00, 0x00, 0x40],
},
"Debug": {'com_name': 'COM8', 'baudrate': 250000, 'parity': 'E', 'bytesize': 8, 'stopbits': 1,
'addr_645': [0x01, 0x02, 0x03, 0x04, 0x05, 0x06],
"Debug": {'com_name': 'COM8', 'baudrate': 115200, 'parity': 'N', 'bytesize': 8, 'stopbits': 1,
# 'addr_645': [0x01, 0x02, 0x03, 0x04, 0x05, 0x06],
'frame_print': True,
'time_out': 0.2, 'retry': 1, 'retry_sub': 10},
'time_out': 0.2, 'retry': 3, 'retry_sub': 10},
}
@@ -418,7 +478,10 @@ if __name__=='__main__':
dev_lamina.frame_read(0x0170, 0x30)
if not hasattr(__builtins__,"__IPYTHON__"):
path_bin = Path(r"D:\WorkingProject\LightStackAdapter\software\lamina_adapter\tools\upgrade\SLCP001_240625_2030_V1.04.bin")
make_Image()
path_bin = Path(r"D:\WorkSpace\UserTool\SelfTool\FrameParser\test\p280039\result\DLSP001_240828_0900_T1.01.dat")
# path_bin = Path(r"D:\WorkingProject\LightStackAdapter\software\lamina_adapter\tools\upgrade\SLCP001_240520_0000_T1.11.bin")
# 生产镜像版本
# path_bin = Path(r"D:\WorkingProject\LightStackAdapter\software\lamina_adapter\tools\upgrade\SLCP001_240525_1800_V1.12.bin")

View File

@@ -1,6 +1,6 @@
import struct
from crc import Calculator, Crc16
from utl import display_hex, trans_list_to_str
from tools.ByteConv import trans_list_to_str, display_hex
modbus_map = {
# 1 - Hex

View File

@@ -4,7 +4,9 @@ from pathlib import Path
from datetime import datetime
from crc import Calculator, Crc16
from utl import conv_int_to_array, trans_list_to_str
from tools.ByteConv import trans_list_to_str, conv_int_to_array
from tools.IntelHex import file_IntelHex_to_Bin, file_Bin_to_IntelHex
Header_Tag = {
'file_type': [0x00, 2], # 0 - 文件类型; 2byte
@@ -22,68 +24,6 @@ Header_Tag = {
'hex_name': [0xFF, -1, 80], # 255 - Hex文件名; less than 80byte
}
def file_IntelHex_to_Bin(file_data, base_address=0, len_max=1, **kwargs):
"""
将Intel Hex格式文件转换为Bin格式;
"""
if base_address == 0:
if file_data[8] == '2':
base_address = int(file_data[9: 13], 16) * 16
offset_begin = 16
elif file_data[8] == '4':
base_address = int(file_data[9: 13], 16) * 2**16
offset_begin = 16
else:
base_address = 0
offset_begin = 0
base_address += int(file_data[offset_begin + 3: offset_begin + 7], 16)
base_address &= ~0x0FFF
len_space = len_max
result = bytearray(len_space).replace(b'\x00', b'\xff')
lines = file_data.split('\n')
offset = 0
max_address = 0
for line in lines:
if line[0] == ':':
checksum = sum([int(x, 16) * (15 * (~i & 0x01) + 1) for i, x in enumerate(line[1:])])
if (checksum & 0x00FF) != 0:
raise Exception('Hex file checksum error!')
if line[7:9] == '00':
len_line = int(line[1:3], 16)
address = offset + int(line[3:7], 16) - base_address
data = bytearray.fromhex(line[9:-2])
if 'conv_end' in kwargs.keys():
address *= 2
if kwargs['conv_end']:
for i in range(0, len_line, 2):
t = data[i]
data[i] = data[i+1]
data[i+1] = t
if (address + len_line) > max_address:
max_address = address + len_line
if max_address >= len_space:
if len_max == 1:
result += bytearray(max_address - len_space).replace(b'\x00', b'\xff')
len_space += max_address - len_space
else:
raise Exception("Bin file Oversize.")
result[address:address+len_line] = data
elif line[7:9] == '01':
break
elif line[7:9] == '02':
offset = int(line[9:-2], 16) * 16
elif line[7:9] == '03':
pass
elif line[7:9] == '04': # 拓展地址偏移
offset = int(line[9:-2], 16) * 2**16
elif line[7:9] == '05':
pass
return result[:max_address]
def file_encryption(buffer):
""" 文件加密算法 """
@@ -104,6 +44,7 @@ def file_encryption(buffer):
def build_header(config: dict, len_max=512):
"""
基于配置参数, 生成文件信息头;
V1版本, 依据字典生成tag标签组;
"""
# 定义文件头
m_file_header = bytearray(len_max)
@@ -112,7 +53,10 @@ def build_header(config: dict, len_max=512):
tag_num = 0
for tag, value in config.items():
if tag in Header_Tag.keys():
if Header_Tag[tag][1] == -1:
if tag == 'hex_name' and len_max < 256:
""" 当文件头长度不足时, 跳过文件名标签 """
continue
elif Header_Tag[tag][1] == -1:
tag_len = min(len(value), Header_Tag[tag][2])
else:
tag_len = Header_Tag[tag][1]
@@ -132,9 +76,11 @@ def build_header(config: dict, len_max=512):
else:
return m_file_header
def build_header_lite(config: dict):
"""
基于配置参数, 生成文件信息头;
V2版本, 仅提供必要信息;
"""
# 定义文件头
m_file_header = bytearray(64)
@@ -144,9 +90,11 @@ def build_header_lite(config: dict):
return m_file_header
def build_header_new(config: dict):
"""
基于配置参数, 生成新版文件信息头;
V3版本, 依据新版格式填充数据;
"""
# 定义文件头
m_file_header = [0xFF] * 184
@@ -207,7 +155,7 @@ def build_header_new(config: dict):
m_file_header[158: 160] = config['upgrade_type']
m_file_header[160: 182] = [0x00] * 22
else:
m_file_header[158: 182] = [0x00] * 24
m_file_header[158: 182] = [0x00] * 24
m_file_header = bytearray(m_file_header)
@@ -217,89 +165,25 @@ def build_header_new(config: dict):
return m_file_header
def make_datafile(file_path: str, config: dict, header_len=512):
""" 升级文件生成函数; 完整文件头, TI-hex转换 """
file_path = Path(file_path)
file_data = file_path.read_text()
data_bin = file_IntelHex_to_Bin(file_data, config['flash_addr'], len_max=config['flash_size'] * 2)
md5_ctx = hashlib.md5()
md5_ctx.update(data_bin)
config['file_length'] = conv_int_to_array(len(data_bin))
config["md5"] = list(md5_ctx.digest())
if header_len > 256:
config['hex_name'] = list(file_path.name.encode())[:80]
data_header = build_header(config, header_len)
if data_header is None:
raise ("header tag oversize! ")
data_encrypt = file_encryption(data_bin)
return data_header, data_bin, data_encrypt
def make_datafile1(file_path: str, config: dict, header_len=512):
""" 升级文件生成函数; 简易文件头, TI-Hex转换 """
file_path = Path(file_path)
file_data = file_path.read_text()
data_bin = file_IntelHex_to_Bin(file_data, config['flash_addr'], len_max=config['flash_size'] * 2)
md5_ctx = hashlib.md5()
md5_ctx.update(data_bin)
config['file_length'] = conv_int_to_array(len(data_bin), True)
config["md5"] = list(md5_ctx.digest())
if header_len > 256:
config['hex_name'] = list(file_path.name.encode())[:80]
data_header = build_header_lite(config)
data_encrypt = file_encryption(data_bin)
return data_header, data_bin, data_encrypt
def make_datafile2(file_path: str, config: dict, header_len=512):
""" 升级文件生成函数; 完整文件头 """
file_path = Path(file_path)
data_bin = file_path.read_bytes()
md5_ctx = hashlib.md5()
md5_ctx.update(data_bin)
config['file_length'] = conv_int_to_array(len(data_bin))
config["md5"] = list(md5_ctx.digest())
if header_len > 256:
config['hex_name'] = list(file_path.name.encode())[:80]
data_header = build_header(config, header_len)
if data_header is None:
raise Exception("Header tag oversize. ")
data_encrypt = file_encryption(data_bin)
return data_header, data_bin, data_encrypt
def make_datafile3(file_path: str, config: dict, header_len=184):
""" 升级文件生成函数; 完整文件头 """
file_path = Path(file_path)
file_data = file_path.read_text()
data_bin = file_IntelHex_to_Bin(file_data)
md5_ctx = hashlib.md5()
md5_ctx.update(data_bin)
config['file_length'] = conv_int_to_array(len(data_bin))
config["md5"] = list(md5_ctx.digest())
config['hex_name'] = list(file_path.name.encode())[:64]
config['hex_name'] += [0] * (64 - len(config['hex_name']))
data_header = build_header_new(config)
if data_header is None:
raise Exception("Header tag oversize. ")
data_encrypt = file_encryption(data_bin)
return data_header, data_bin, data_encrypt
def test1(fp):
def test1(fp: Path):
""" bin文件生成测试 """
file1 = Path(fp)
path1 = file1.parent / (file1.stem + ".bin")
data1 = file1.read_text()
data2 = file_IntelHex_to_Bin(data1, 0x3F0100)
path1.write_bytes(data2)
pass
# 测试Bin到IntelHex
bin = Path(fp).read_bytes()
result = file_Bin_to_IntelHex(bin, 0x80000, memory_width=2)
(fp.parent / (fp.stem + ".hex")).write_text(result)
def test2():
""" md5校验, 加密测试 """
bin_offcial = Path(r"D:\WorkingProject\LightStackAdapter\software\lamina_adapter\tools\uart_tool\江苏发货版本\SLCP001_240517_1800_V1.11.bin")
""" 校验, 加密测试 """
# Header - Crc16
bin_offcial = Path(r"D:\WorkSpace\UserTool\SelfTool\FrameParser\test\p460\result\lamina_adapter_t1.dat")
data_offcial = bin_offcial.read_bytes()
byte_data = data_offcial[:182]
crc = data_offcial[182:184]
@@ -310,17 +194,32 @@ def test2():
code_crc16 = calculator.checksum(bytearray(byte_data))
print(f"Result = {hex(code_crc16)}, Offcial Result = {crc}")
# File - md5
data_bin = '123456 123456 '.encode()
md5_ctx = hashlib.md5()
md5_ctx.update(data_bin)
hash = md5_ctx.hexdigest()
# File - encrypt
buffer1 = data_bin[:]
buffer1_en = file_encryption(buffer1)
buffer2 = buffer1_en[:6] + buffer1[6:]
buffer2_en = file_encryption(buffer2)
buffer2_de = file_encryption(buffer2)
pass
def test3(path_bin):
def task5():
""" 文件缓冲区对比测试 """
file_dat = Path(r"test\p280039\result\lamina_controller_dsp_t1.dat")
file_dat_buffer = Path(r"test\p280039\result\lamina_controller_dsp_buffer.bin")
file_dat_buffer.exists(), file_dat.exists()
data_dat = file_dat.read_bytes()
data_dat_buffer = file_dat_buffer.read_bytes()
for i in range(len(data_dat)):
if data_dat[i] != data_dat_buffer[2*i]:
print(f"Diff in {hex(i)}, Data: {data_dat[i]}!={data_dat_buffer[2*i]}")
def GeneratePackage_Demo_Xilinx(path_bin: Path):
""" 完整升级包生成测试 """
config = {
'file_type': [0x10, 0x01], # Xilinx-Demo 自机升级文件
@@ -342,19 +241,31 @@ def test3(path_bin):
# 'flash_size': 0x005FC0, # 程序空间大小
}
header, data_b, _ = make_datafile2(path_bin, config, header_len=128)
header_512, data_b_512, _ = make_datafile2(path_bin, config, header_len=512)
data_bin = path_bin.read_bytes()
md5_ctx = hashlib.md5()
md5_ctx.update(data_bin)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = conv_int_to_array(len(data_bin))
config['hex_name'] = list(path_bin.name.encode())[:80]
if (header:= build_header(config, 128)) is None:
raise Exception("Header tag oversize. ")
if (header_512:= build_header(config, 512)) is None:
raise Exception("Header tag oversize. ")
data_encrypt = file_encryption(data_bin)
print("Upgrade file generated successfully.")
print(f"\t header_length={len(header)}, bin_length={len(data_b)}[{hex(len(data_b))}]")
print(f"\t header_length={len(header)}, bin_length={len(data_bin)}[{hex(len(data_bin))}]")
print(f"\t file md5: {trans_list_to_str(config['md5'])}")
file1 = path_bin.parent / (path_bin.stem + '.dat')
file1.write_bytes(header + data_b)
file1.write_bytes(header + data_bin)
file2 = path_bin.parent / (path_bin.stem + '_h512.dat')
file2.write_bytes(header_512 + data_b)
file2.write_bytes(header_512 + data_bin)
def test4(path_boot, path_main, path_back):
""" 叠光适配器新版升级方案测试 """
def GenerateImage_SLCP001_p4a0(path_boot: Path, path_main: Path, path_back: Path):
""" 叠光适配器-4A0平台版本 镜像生成 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
@@ -362,81 +273,108 @@ def test4(path_boot, path_main, path_back):
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
file_path = Path(path_boot)
file_data = file_path.read_text()
boot_bin = file_IntelHex_to_Bin(file_data, len_max=0x010000)
main_header, main_data_b, main_data_e = make_datafile3(path_main, config)
back_header, back_data_b, back_data_e = make_datafile3(path_back, config)
bin_boot = file_IntelHex_to_Bin(path_boot.read_text(), len_max=0x010000)
bin_main = file_IntelHex_to_Bin(path_main.read_text(), len_max=0x0CC000)
bin_back = file_IntelHex_to_Bin(path_back.read_text(), len_max=0x040000)
encrypt_main = file_encryption(bin_main)
encrypt_back = file_encryption(bin_back)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = conv_int_to_array(len(bin_main))
config['hex_name'] = list(path_main.name.encode())[:64]
config['hex_name'] += [0] * (64 - len(config['hex_name']))
if (main_header:=build_header_new(config)) is None:
raise Exception("Header tag oversize. ")
md5_ctx = hashlib.md5()
md5_ctx.update(bin_back)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = conv_int_to_array(len(bin_back))
config['hex_name'] = list(path_back.name.encode())[:64]
config['hex_name'] += [0] * (64 - len(config['hex_name']))
if (back_header:=build_header_new(config)) is None:
raise Exception("Header tag oversize. ")
print("Merge Image generated successfully.")
print(f"Main File:")
print(f"\t header_length={len(main_header)}, bin_length={len(main_data_b)}[{hex(len(main_data_b))}]")
print(f"\t header_length={len(main_header)}, bin_length={len(bin_main)}[{hex(len(bin_main))}]")
print(f"Back File:")
print(f"\t header_length={len(back_header)}, bin_length={len(back_data_b)}[{hex(len(back_data_b))}]")
print(f"\t header_length={len(back_header)}, bin_length={len(bin_back)}[{hex(len(bin_back))}]")
# 组装镜像
Image = [0xFF] * 0x100000
offset_image = 0
Image[offset_image: offset_image + len(boot_bin)] = boot_bin
Image[offset_image: offset_image + len(bin_boot)] = bin_boot
offset_image = 0x010000
Image[offset_image: offset_image + len(main_data_b)] = main_data_b
Image[offset_image: offset_image + len(bin_main)] = bin_main
offset_image = 0x0BC000
Image[offset_image: offset_image + len(back_data_b)] = back_data_b
Image[offset_image: offset_image + len(bin_back)] = bin_back
offset_image = 0x0FC000
Image[offset_image: offset_image + len(main_header)] = main_header
offset_image = 0x0FE000
Image[offset_image: offset_image + len(back_header)] = back_header
return bytearray(Image), main_header, main_data_b, main_data_e, back_header, back_data_b, back_data_e
return bytearray(Image), main_header, back_header
def task5():
""" 文件缓冲区对比测试 """
file_dat = Path(r"test\p280039\result\lamina_controller_dsp_t1.dat")
file_dat_buffer = Path(r"test\p280039\result\lamina_controller_dsp_buffer.bin")
file_dat_buffer.exists(), file_dat.exists()
data_dat = file_dat.read_bytes()
data_dat_buffer = file_dat_buffer.read_bytes()
for i in range(len(data_dat)):
if data_dat[i] != data_dat_buffer[2*i]:
print(f"Diff in {hex(i)}, Data: {data_dat[i]}!={data_dat_buffer[2*i]}")
def GenerateImage_SLCP001_p460(path_boot, path_main, path_back):
def GenerateImage_SLCP001_p460(path_boot: Path, path_main: Path, path_back: Path):
""" 叠光适配器-460平台版本 镜像生成 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(b"SLCP001"), # 程序识别号
'prog_id': list(b"SLCP101"), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
file_path = Path(path_boot)
file_data = file_path.read_text()
boot_bin = file_IntelHex_to_Bin(file_data, len_max=0x00C000)
main_header, main_data_b, main_data_e = make_datafile3(path_main, config)
back_header, back_data_b, back_data_e = make_datafile3(path_back, config)
bin_boot = file_IntelHex_to_Bin(path_boot.read_text(), len_max=0x00C000)
bin_main = file_IntelHex_to_Bin(path_main.read_text(), len_max=0x024000)
bin_back = file_IntelHex_to_Bin(path_back.read_text(), len_max=0x024000)
encrypt_main = file_encryption(bin_main)
encrypt_back = file_encryption(bin_back)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = conv_int_to_array(len(bin_main))
config['hex_name'] = list(path_main.name.encode())[:64]
config['hex_name'] += [0] * (64 - len(config['hex_name']))
if (main_header:=build_header_new(config)) is None:
raise Exception("Header tag oversize. ")
md5_ctx = hashlib.md5()
md5_ctx.update(bin_back)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = conv_int_to_array(len(bin_back))
config['hex_name'] = list(path_back.name.encode())[:64]
config['hex_name'] += [0] * (64 - len(config['hex_name']))
if (back_header:=build_header_new(config)) is None:
raise Exception("Header tag oversize. ")
print("Merge Image generated successfully.")
print(f"Main File:")
print(f"\t header_length={len(main_header)}, bin_length={len(main_data_b)}[{hex(len(main_data_b))}]")
print(f"\t header_length={len(main_header)}, bin_length={len(bin_main)}[{hex(len(bin_main))}]")
print(f"Back File:")
print(f"\t header_length={len(back_header)}, bin_length={len(back_data_b)}[{hex(len(back_data_b))}]")
print(f"\t header_length={len(back_header)}, bin_length={len(bin_back)}[{hex(len(bin_back))}]")
# 组装镜像
Image = [0xFF] * 0x058000
offset_image = 0
Image[offset_image: offset_image + len(boot_bin)] = boot_bin
Image[offset_image: offset_image + len(bin_boot)] = bin_boot
offset_image = 0x00C000
Image[offset_image: offset_image + len(main_data_b)] = main_data_b
Image[offset_image: offset_image + len(bin_main)] = bin_main
offset_image = 0x030000
Image[offset_image: offset_image + len(back_data_b)] = back_data_b
Image[offset_image: offset_image + len(bin_back)] = bin_back
offset_image = 0x054000
Image[offset_image: offset_image + len(main_header)] = main_header
offset_image = 0x056000
Image[offset_image: offset_image + len(back_header)] = back_header
return bytearray(Image), main_header, main_data_b, main_data_e, back_header, back_data_b, back_data_e
return bytearray(Image), main_header, back_header
def GeneratePackage_SLCP001_p460(path_hex):
def GeneratePackage_SLCP001_p460(path_hex: Path):
""" 叠光适配器-460平台版本 生成升级包 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
@@ -445,61 +383,136 @@ def GeneratePackage_SLCP001_p460(path_hex):
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
main_header, main_data_b, main_data_e = make_datafile3(path_hex, config)
bin_main = file_IntelHex_to_Bin(path_hex.read_text(), len_max=0x024000)
encrypt_main = file_encryption(bin_main)
print("Merge Image generated successfully.")
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = conv_int_to_array(len(bin_main))
config['hex_name'] = list(path_hex.name.encode())[:64]
config['hex_name'] += [0] * (64 - len(config['hex_name']))
if (main_header:=build_header_new(config)) is None:
raise Exception("Header tag oversize. ")
print("Package generated successfully.")
print(f"File name: {path_hex.name}")
print(f"File Info:")
print(f"\t header_length={len(main_header)}, bin_length={len(main_data_b)}[{hex(len(main_data_b))}]")
print(f"\t header_length={len(main_header)}, bin_length={len(bin_main)}[{hex(len(bin_main))}]")
# 组装镜像
Image = [0xFF] * (len(main_header) + len(main_data_e))
Image = [0xFF] * (len(main_header) + len(encrypt_main))
offset_image = 0
Image[offset_image: offset_image + len(main_header)] = main_header
offset_image += len(main_header)
Image[offset_image: offset_image + len(main_data_e)] = main_data_e
Image[offset_image: offset_image + len(encrypt_main)] = encrypt_main
return bytearray(Image), main_data_b
return bytearray(Image), bin_main
def GeneratePackage_XXX001_p280039(path_hex):
""" 叠光控制器DSP-280039平台版本 生成升级包 """
def GenerateImage_DLSP001_p280039(path_boot: Path, path_main: Path, path_back: Path):
""" 叠光适配器-460平台版本 镜像生成 """
config = {
'prod_type': [0x46, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(b"SLCP001"), # 程序识别号
'prog_id': list(b"DLSP001"), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
'upgrade_type': [0x00, 0x00], # 升级方式(0-片外缓冲, 1-片内缓冲, 2-升级备份)
}
path_hex = Path(path_hex)
file_data = path_hex.read_text()
data_bin = file_IntelHex_to_Bin(file_data, conv_end = False)
bin_boot = file_IntelHex_to_Bin(path_boot.read_text(), len_max=2 * 0x004000, conv_end=False)
bin_main = file_IntelHex_to_Bin(path_main.read_text(), len_max=2 * 0x014000, conv_end=False)
bin_back = file_IntelHex_to_Bin(path_back.read_text(), len_max=2 * 0x014000, conv_end=False)
md5_ctx = hashlib.md5()
md5_ctx.update(data_bin)
config['file_length'] = conv_int_to_array(len(data_bin))
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['hex_name'] = list(path_hex.name.encode())[:64]
config['upgrade_type'] = [0x00, 0x00] # 主程序-片外缓冲
config['file_length'] = conv_int_to_array(len(bin_main))
config['hex_name'] = list(path_main.name.encode())[:64]
config['hex_name'] += [0] * (64 - len(config['hex_name']))
data_header = build_header_new(config)
if data_header is None:
if (main_header:=build_header_new(config)) is None:
raise Exception("Header tag oversize. ")
data_encrypt = file_encryption(data_bin)
main_header, main_data_b, main_data_e = data_header, data_bin, data_encrypt
md5_ctx = hashlib.md5()
md5_ctx.update(bin_back)
config["md5"] = list(md5_ctx.digest())
config['upgrade_type'] = [0x02, 0x00] # 备份程序
config['file_length'] = conv_int_to_array(len(bin_back))
config['hex_name'] = list(path_back.name.encode())[:64]
config['hex_name'] += [0] * (64 - len(config['hex_name']))
if (back_header:=build_header_new(config)) is None:
raise Exception("Header tag oversize. ")
main_header_buffer = bytearray()
for byte_org in main_header:
main_header_buffer.extend(bytearray([0x00, byte_org]))
back_header_buffer = bytearray()
for byte_org in back_header:
back_header_buffer.extend(bytearray([0x00, byte_org]))
main_encrypt = file_encryption(bin_main)
back_encrypt = file_encryption(bin_back)
print("Merge Image generated successfully.")
print(f"File Info:")
print(f"\t header_length={len(main_header)}, bin_length={len(main_data_b)}[{hex(len(main_data_b))}]")
print(f"Main File:")
print(f"\t header_length={len(main_header)}, bin_length={len(bin_main)}[{hex(len(bin_main))}]")
print(f"Back File:")
print(f"\t header_length={len(back_header)}, bin_length={len(bin_back)}[{hex(len(bin_back))}]")
# 组装镜像
Image = [0xFF] * (len(main_header) + len(main_data_e))
Image = [0xFF] * 2 * 0x030000
offset_image = 0
Image[offset_image: offset_image + len(bin_boot)] = bin_boot
offset_image = 2 * 0x006000
Image[offset_image: offset_image + len(main_header_buffer)] = main_header_buffer
offset_image = 2 * 0x007000
Image[offset_image: offset_image + len(back_header_buffer)] = back_header_buffer
offset_image = 2 * 0x008000
Image[offset_image: offset_image + len(bin_main)] = bin_main
offset_image = 2 * 0x01C000
Image[offset_image: offset_image + len(bin_back)] = bin_back
return bytearray(Image), main_header, back_header
def GeneratePackage_DLSP001_p280039(path_hex: Path):
""" 叠光控制器DSP-280039平台版本 生成升级包 """
config = {
'prod_type': [0x46, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(b"DLSP001"), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
'upgrade_type': [0x00, 0x00], # 升级方式(0-片外缓冲, 1-片内缓冲, 2-升级备份)
}
bin_main = file_IntelHex_to_Bin(path_hex.read_text(), len_max=2 * 0x014000, conv_end=False)
encrypt_main = file_encryption(bin_main)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = conv_int_to_array(len(bin_main))
config['hex_name'] = list(path_hex.name.encode())[:64]
config['hex_name'] += [0] * (64 - len(config['hex_name']))
if (main_header:=build_header_new(config)) is None:
raise Exception("Header tag oversize. ")
print("Package generated successfully.")
print(f"File name: {path_hex.name}")
print(f"File Info:")
print(f"\t header_length={len(main_header)}, bin_length={len(bin_main)}[{hex(len(bin_main))}]")
# 组装镜像
Image = [0xFF] * (len(main_header) + len(encrypt_main))
offset_image = 0
Image[offset_image: offset_image + len(main_header)] = main_header
offset_image += len(main_header)
Image[offset_image: offset_image + len(main_data_e)] = main_data_e
Image[offset_image: offset_image + len(encrypt_main)] = encrypt_main
return bytearray(Image), bin_main
return bytearray(Image), main_data_b
def Process1():
""" 镜像生成流程 """
@@ -509,15 +522,22 @@ def Process1():
hex_boot = root / r"bootloader.hex"
hex_main = root / r"lamina_adapter.hex"
hex_back = root / r"lamina_adapter_back.hex"
hex_update = root / r"lamina_adapter_t1.hex"
file_image = result / f'{hex_main.stem[:-6]}_ROM.bin'
file_main_header = result / 'SLCP001_header_main.bin'
file_back_header = result / 'SLCP001_header_back.bin'
file_package = result / f'{hex_update.stem}.dat'
file_bin = result / f'{hex_update.stem}.bin'
data_bins = GenerateImage_SLCP001_p460(hex_boot, hex_main, hex_back)
data_package, data_bins = GeneratePackage_SLCP001_p460(hex_update)
file_image.write_bytes(data_bins[0].copy())
file_main_header.write_bytes(data_bins[1].copy())
file_back_header.write_bytes(data_bins[4].copy())
file_back_header.write_bytes(data_bins[2].copy())
file_package.write_bytes(data_package)
file_bin.write_bytes(data_bins)
# 异常镜像-主分区md5错误
file_image1 = result / f'{file_image.stem}_b1.bin'
@@ -538,51 +558,10 @@ def Process1():
data_image[0x056018: 0x05601A] = [0x00, 0x01]
file_image3.write_bytes(data_image)
def Process2():
""" 升级包生成流程 """
root = Path(r"test\p460")
result = Path(r"test\p460\result")
hex_main = root / r"lamina_adapter_t1.hex"
file_package = result / f'{hex_main.stem}.dat'
file_bin = result / f'{hex_main.stem}.bin'
data_package, data_bins = GeneratePackage_SLCP001_p460(hex_main)
file_package.write_bytes(data_package)
file_bin.write_bytes(data_bins)
def Process3():
""" 叠光控制器DSP升级包生成流程 """
root = Path(r"test\p280039")
result = Path(r"test\p280039\result")
hex_main = root / r"lamina_controller_dsp_t1.hex"
file_package = result / f'{hex_main.stem}.dat'
file_bin = result / f'{hex_main.stem}.bin'
file_package_buffer = result / f'{hex_main.stem}.datbuffer'
data_package, data_bins = GeneratePackage_XXX001_p280039(hex_main)
file_package.write_bytes(data_package)
file_bin.write_bytes(data_bins)
data_buff = bytearray(2 * len(data_package))
for i in range(len(data_package)):
data_buff[2*i] = data_package[i]
file_package_buffer.write_bytes(data_buff)
if __name__ == "__main__":
# path_bin = Path("F:\\Work\\FPGA\\Test\\Vivado\\test_update\\test_update.vitis\\upgrade_system\\Debug\\sd_card\\BOOT.BIN")
# test3(path_bin)
# GeneratePackage_Demo_Xilinx(path_bin)
# test2()
if 0:
bin_back = Path(r"D:\WorkingProject\LightStackAdapter\software\lamina_adapter\tools\upgrade\lamina_adapter_back.bin")
bin_main = Path(r"D:\WorkingProject\LightStackAdapter\software\lamina_adapter\tools\upgrade\lamina_adapter_main.bin")
main_header1 = bin_main.read_bytes()[:184]
main_data_e1 = bin_main.read_bytes()[184:]
back_header1 = bin_back.read_bytes()[:184]
back_data_e1 = bin_back.read_bytes()[184:]
Process1()
pass

View File

@@ -1,14 +1,15 @@
def trans_list_to_str(data: list) -> str:
""" 标准串口字符串表示 """
func_trans = lambda x: ('00' + hex(x % 256)[2:])[-2:].upper()
return " ".join(map(func_trans, data))
def trans_str_to_list(data: str) -> list:
""" 标准串口字符串转换列表 """
func_trans = lambda x: int(x, 16)
return list(map(func_trans, data.strip().split(" ")))
def conv_int_to_array(num: int, big_end=False):
""" 数值转字节数组 """
result = [0, 0, 0, 0]
@@ -22,9 +23,9 @@ def conv_int_to_array(num: int, big_end=False):
num //= 0x100
return result
def display_hex(data, len) -> str:
""" Hex字符表示 """
data %= 2 ** (4 * len)
result = "0" * len + hex(data)[2:]
return "0x" + result[-len:].upper()
return "0x" + result[-len:].upper()

142
source/tools/IntelHex.py Normal file
View File

@@ -0,0 +1,142 @@
def calculate_checksum(data):
""" 计算校验域 """
checksum = 0
for i in range(0, len(data), 2):
checksum += int(data[i: i+2], 16)
return (0x100 - checksum) & 0xFF
def file_IntelHex_to_Bin(file_data, base_address=0, len_max=1, **kwargs):
"""
将Intel Hex格式文件转换为Bin格式;
"""
if base_address == 0:
if file_data[8] == '2':
base_address = int(file_data[9: 13], 16) * 0x100
offset_begin = 16
elif file_data[8] == '4':
base_address = int(file_data[9: 13], 16) * 0x10000
offset_begin = 16
else:
base_address = 0
offset_begin = 0
base_address += int(file_data[offset_begin + 3: offset_begin + 7], 16)
base_address &= ~0x0FFF
len_space = len_max
result = bytearray(len_space).replace(b'\x00', b'\xff')
lines = file_data.split('\n')
offset = 0
max_address = 0
for line in lines:
if line[0] == ':':
checksum = sum([int(x, 16) * (15 * (~i & 0x01) + 1) for i, x in enumerate(line[1:])])
if (checksum & 0x00FF) != 0:
raise Exception('Hex file checksum error!')
if line[7:9] == '00':
len_line = int(line[1:3], 16)
address = offset + int(line[3:7], 16) - base_address
data = bytearray.fromhex(line[9:-2])
if 'conv_end' in kwargs.keys():
address *= 2
if kwargs['conv_end']:
for i in range(0, len_line, 2):
t = data[i]
data[i] = data[i+1]
data[i+1] = t
if (address + len_line) > max_address:
max_address = address + len_line
if max_address >= len_space:
if len_max == 1:
result += bytearray(max_address - len_space).replace(b'\x00', b'\xff')
len_space += max_address - len_space
else:
raise Exception("Bin file Oversize.")
result[address:address+len_line] = data
elif line[7:9] == '01':
break
elif line[7:9] == '02':
offset = int(line[9:-2], 16) * 16
elif line[7:9] == '03':
pass
elif line[7:9] == '04': # 拓展地址偏移
offset = int(line[9:-2], 16) * 2**16
elif line[7:9] == '05':
pass
return result[:max_address]
def file_Bin_to_IntelHex(file_data: bytearray, base_address=0, **kwargs):
"""
将Bin格式文件转换为Intel Hex格式;
"""
chunk_size = 32
rom_width = 8
memory_width = 8
if 'chunk_size' in kwargs.keys():
""" 数据分块大小 """
chunk_size = kwargs['chunk_size']
if 'memory_width' in kwargs.keys():
""" 地址数据位宽 """
memory_width = kwargs['memory_width'] * 8
if 'rom_width' in kwargs.keys():
""" rom数据位宽 """
rom_width = kwargs['rom_width'] * 8
def record_extern_address(address, record_type):
""" 添加地址记录 """
if record_type == 4:
record_data = (address & 0xFFFF0000) >> 16
elif record_type == 2:
record_data = (address & 0xFFFF0) >> 4
else:
raise Exception("Unknow record tye.")
hex_record = f':020000{record_type:02X}{record_data:04X}'
hex_record += f'{calculate_checksum(hex_record[1:]):02X}\n'
return hex_record
result = str()
# 添加开始记录
extern_address = 0
if base_address >= 2 ** 32:
""" 超过最大可表示范围, 抛出异常 """
raise Exception("base_address oversize")
elif base_address >= 2 ** 16:
result += record_extern_address(base_address, 4)
extern_address = base_address & 0xFFFF0000
elif base_address >= 2 ** 4:
result += record_extern_address(base_address, 2)
extern_address = base_address & 0xFFFF0
record_type = 0
binary_offset = 0
while binary_offset < len(file_data):
""" 循环分块处理数据 """
data_chunk = file_data[binary_offset: binary_offset + chunk_size]
record_len = len(data_chunk)
record_data = data_chunk
record_addr = (base_address - extern_address + (binary_offset // (memory_width // 8)))
if record_addr >= 0x10000:
result += record_extern_address((base_address + (binary_offset // (memory_width // 8))), 4)
extern_address = (base_address + (binary_offset // (memory_width // 8))) & 0xFFFF0000
continue
# 构造记录
hex_record = f':{record_len:02X}{record_addr:04X}{record_type:02X}'
hex_record += ''.join(f'{byte:02X}' for byte in record_data)
hex_record += f'{calculate_checksum(hex_record[1:]):02X}\n'
result += hex_record
binary_offset += chunk_size
# 添加结束记录
hex_record = f':00000001FF\n'
result += hex_record
return result

0
source/tools/__init__.py Normal file
View File