Files
DebugTool/source/device/LaminaAdapter.py
2024-11-23 17:39:54 +08:00

764 lines
34 KiB
Python

import time
import hashlib
from math import ceil
from tqdm import tqdm
from pathlib import Path
from . import tools
from .tools import ByteConv, IntelHex
from .function import protocols, file_upgrade
from .DeviceSerial import DeviceSerial
ParamMap_LaminaAdapter = {
# 1 - Hex
# 2 - Int16
# 3 - lnt32
# 4 - str
# 5 - addr
# 6 - float
0x00: ["硬件版本识别电压", 2, 1000],
0x01: ["输出电容电电压", 2, 10],
0x02: ["参考电压", 2, 10],
0x0E: ["故障字1", 1],
0x0F: ["故障字2", 1],
0x10: ["MPPT工作状态", 1],
0x11: ["系统工作状态", 1],
0x12: ["系统工作模式", 1],
0x13: ["输入电压", 2, 10],
0x14: ["电感电流", 2, 100],
0x15: ["12V电压", 2, 10],
0x16: ["输出电压", 2, 10],
0x17: ["输入电流", 2, 100],
0x18: ["温度1", 2, 10],
0x19: ["温度2", 2, 10],
0x1A: ["输入功率", 3, 1000],
0x1C: ["设备温度", 2, 10],
0x1D: ["开关机状态", 1],
0x1E: ["电池电压", 2, 10],
0x1F: ["并机功率限值", 3, 1000],
0x21: ["输出限功率电压阈值", 2, 10],
0x50: ["启停控制命令" , 2],
0x51: ["故障清除命令" , 2],
0x52: ["参数还原命令" , 2],
0x53: ["设备复位命令" , 2],
0x54: ["主动故障命令" , 2],
0x55: ["短时停机命令" , 2],
0x60: ["光伏通道使能", 1],
0x61: ["最小启动输入电压", 2, 10],
0x62: ["最大启动输入电压", 2, 10],
0x63: ["最小停止输入电压", 2, 10],
0x64: ["最大停止输入电压", 2, 10],
0x65: ["最小MPPT电压", 2, 10],
0x66: ["最大MPPT电压", 2, 10],
0x67: ["最小启动输出电压", 2, 10],
0x68: ["最大启动输出电压", 2, 10],
0x69: ["最小停止输出电压", 2, 10],
0x6A: ["最大停止输出电压", 2, 10],
0x6B: ["输入过压保护值", 2, 10],
0x6C: ["输出过压保护值", 2, 10],
0x6D: ["输出欠压保护值", 2, 10],
0x6E: ["电感过流保护值", 2, 100],
0x6F: ["输入过流保护值", 2, 100],
0x70: ["最小电感电流限值", 2, 100],
0x71: ["最大电感电流限值", 2, 100],
0x72: ["浮充电压阈值", 2, 10],
0x73: ["三点法中间阈值", 2, 10],
0x74: ["恒压充电电压", 2, 10],
0x75: ["过温故障值", 2, 10],
0x76: ["过温告警值", 2, 10],
0x77: ["温度恢复值", 2, 10],
0x78: ["最低满载电压", 2, 10],
0x79: ["最高满载电压", 2, 10],
0x7A: ["输入过载保护值", 3, 1000],
0x7C: ["最小功率限值", 3, 1000],
0x7E: ["最大功率限值", 3, 1000],
0x80: ["最大功率限值存储值", 3, 1000],
0x82: ["载波通信地址", 5, 3],
0x85: ["电压环out_max", 2, 100],
0x86: ["电压环out_min", 2, 100],
0x87: ["电流环out_max", 2, 100],
0x88: ["电流环out_min", 2, 100],
0x89: ["MPPT扰动系数k_d_vin", 2, 100],
0x8A: ["dmin", 2, 1000],
0x8B: ["dmax", 2, 1000],
0x8C: ["扫描电压偏移scanvolt_offset", 2, 10],
0x8D: ["电压环Kp", 3, 100000],
0x8F: ["电压环Ki", 3, 100000],
0x91: ["电流环Kp", 3, 100000],
0x93: ["电流环Ki", 3, 100000],
0x95: ["日志级别", 1],
0x96: ["日志输出方式", 1],
0x97: ["采样校准volt_in_a", 2, 1000],
0x98: ["采样校准volt_in_b", 2, 100],
0x99: ["采样校准volt_out_a", 2, 1000],
0x9A: ["采样校准volt_out_b", 2, 100],
0x9B: ["采样校准curr_in_a", 2, 1000],
0x9C: ["采样校准curr_in_b", 2, 100],
0x9D: ["采样校准curr_induc_a", 2, 1000],
0x9E: ["采样校准curr_induc_b", 2, 100],
0x9F: ["采样校准volt_12V_a", 2, 1000],
0xA0: ["采样校准volt_12V_b", 2, 100],
0xA1: ["温度补偿temp1_b", 2, 10],
0xA2: ["温度补偿temp2_b", 2, 10],
0xA3: ["系统工作模式", 2],
0xA4: ["电感电流给定值curr_set", 2, 100],
0xA5: ["抖动频率上限", 2, 100],
0xA6: ["抖动频率下限", 2, 100],
0xA7: ["电池电压判断限值", 2, 10],
0xA8: ["MPPT追踪模式", 1],
0xA9: ["ADC参考电压", 2, 1000],
0xAA: ["保留", 1],
0xAB: ["保留", 1],
0xAC: ["保留", 1],
0xAD: ["保留", 1],
0xAE: ["保留", 1],
0xAF: ["保留", 1],
0xB0: ["版本", 4, 16],
0x100: ["版本(ODM)", 4, 16],
0x110: ["型号", 4, 16],
0x120: ["载波芯片地址", 4, 16],
0x130: ["厂商", 4, 8],
0x138: ["保留", 4, 8],
0x140: ["保留", 4, 16],
0x150: ["保留", 4, 16],
0x160: ["硬件", 4, 16],
0x170: ["SN", 4, 16],
0x180: ["MES", 4, 16],
0x190: ["Datetime", 4, 16],
}
MemoryMap_SLCP001 = {
'image_size': 0x100000, # 镜像文件大小
'app_size': 0x040000, # 应用程序大小
'boot_size': 0x010000, # Boot程序大小
'boot_addr': 0x000000, # Boot程序地址
'main_addr': 0x010000, # main程序地址
'back_addr': 0x0BC000, # back程序地址
'main_header': 0x0FC000, # main信息地址
'back_header': 0x0FE000, # back信息地址
}
MemoryMap_460 = {
'image_size': 0x058000, # 镜像文件大小
'app_size': 0x024000, # 应用程序大小
'boot_size': 0x010000, # Boot程序大小
'boot_addr': 0x000000, # Boot程序地址
'main_addr': 0x00C000, # main程序地址
'back_addr': 0x030000, # back程序地址
'main_header': 0x054000, # main信息地址
'back_header': 0x056000, # back信息地址
}
class LaminaAdapter(DeviceSerial):
""" 叠光适配器\优化器
使用继承方式实现功能
"""
def __init__(self, com_name,
addr_645=[0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA],
addr_modbus=0x01, type_dev='SLCP101', **kwargs):
""" 调用超类实现函数初始化 """
super().__init__(com_name,
callbacks=(lambda : protocols.make_frame_dlt645(self.block),
lambda frame: protocols.check_frame_dlt645(frame, self.block)),
**kwargs)
self.device = type_dev
match type_dev:
case 'SLCP001':
self.make_package = lambda *args, **kwargs: GeneratePackage('SLCP001', *args, **kwargs)
self.make_image = lambda *args, **kwargs: GenerateImage('SLCP001', *args, **kwargs)
case 'SLCP101':
self.make_package = lambda *args, **kwargs: GeneratePackage('SLCP101', *args, **kwargs)
self.make_image = lambda *args, **kwargs: GenerateImage('SLCP101', *args, **kwargs)
case 'SLCP102':
self.make_package = lambda *args, **kwargs: GeneratePackage('SLCP102', *args, **kwargs)
self.make_image = lambda *args, **kwargs: GenerateImage('SLCP102', *args, **kwargs)
case 'DLSY001':
self.make_package = lambda *args, **kwargs: GeneratePackage('DLSY001', *args, **kwargs)
self.make_image = lambda *args, **kwargs: GenerateImage('DLSY001', *args, **kwargs)
case _:
self.make_package = None
self.make_image = None
self.block = {
'addr' : addr_645,
'type' : 'modbus',
'data' : {
'addr_dev' : addr_modbus,
'data_define': ParamMap_LaminaAdapter,
},
}
def frame_read(self, daddr=0x60, dlen=0x50) -> bool:
self.block['data']['type'] = 'read'
self.block['data']['data_addr'] = daddr
self.block['data']['data_len'] = dlen
return self._transfer_data()
def frame_write_one(self, daddr=0x85, dval=-900) -> bool:
self.block['data']['type'] = 'write_one'
self.block['data']['data_addr'] = daddr
self.block['data']['data_val'] = dval
item_coff = self.block['data']['data_define'][daddr][2] if len(self.block['data']['data_define'][daddr]) > 2 else 1
self.block['data_val'] = int(dval * item_coff)
return self._transfer_data()
def frame_write_dual(self, daddr=0x91, dval=600) -> bool:
self.block['data']['type'] = 'write_dual'
self.block['data']['data_addr'] = daddr
self.block['data']['data_val'] = dval
item_coff = self.block['data']['data_define'][daddr][2] if len(self.block['data']['data_define'][daddr]) > 2 else 1
self.block['data_val'] = int(dval * item_coff)
return self._transfer_data()
def frame_write_str(self, daddr=0x82, dval=[0x06, 0x05, 0x04, 0x03, 0x02, 0x01]) -> bool:
self.block['data']['type'] = 'write_str'
self.block['data']['data_addr'] = daddr
self.block['data']['data_val'] = dval
return self._transfer_data()
def frame_update(self, path_file: Path, makefile: bool = False) -> bool:
""" 程序升级
注意: 在使用单板升级测试时, 需要关闭低电压检测功能, 否则无法启动升级流程;
"""
param_saved = self.flag_print, self.retry, self.time_out
self.flag_print = False
try:
status = 'init' # 初始化
if not path_file.exists():
raise Exception("工程编译目标文件不存在.")
if makefile and self.make_package is not None:
self.block['data']['file'] = self.make_package(path_file)
else:
self.block['data']['file'] = path_file.read_bytes()
self.block['data']['type'] = 'update'
self.block['data']['header_offset'] = 184
status = 'start' # 启动帧
self.block['data']['step'] = 'start'
self.block['data']['index'] = 0
assert self._transfer_data()
self.block["data"]['file_block_size'] = self.output['upgrade']['length']
# 避免接收到延迟返回报文
time.sleep(self.time_out)
status = 'trans' # 文件传输
self.retry = 3
self.time_out = 1.5
self.block["data"]['step'] = 'trans'
self.block['data']['index'] = 0
frame_total = ceil((len(self.block["data"]['file']) - self.block['data']['header_offset']) / self.block["data"]['file_block_size'])
for idx in tqdm(range(frame_total), desc="File Transmitting"):
self.block["data"]['index'] = idx
assert self._transfer_data()
status = 'end' # 结束升级
self.time_out = 1
self.block["data"]['step'] = 'end'
self.block["data"]['index'] += 1
assert self._transfer_data()
except Exception as ex:
""" 通用异常处理 """
self.flag_print, self.retry, self.time_out = param_saved
report = f'Upgrade Fail: {status}'
report += f', Frame in {self.block["data"]["index"]}' if status == 'trans' else ''
report += f'\n Error by {ex}' if not isinstance(ex, AssertionError) else ''
print(report)
return False
self.flag_print, self.retry, self.time_out = param_saved
return True
def GeneratePackage(type_dev: str, path_hex: Path, **kwargs) -> bytearray:
""" 生成升级包 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(type_dev.encode('ascii')), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
match type_dev:
case 'SLCP001':
MemoryMap = MemoryMap_SLCP001
case 'SLCP101':
MemoryMap = MemoryMap_460
case 'SLCP102':
MemoryMap = MemoryMap_460
case 'DLSY001':
MemoryMap = MemoryMap_460
case _:
raise Exception("Unknow device.")
bin_main = IntelHex.file_IntelHex_to_Bin(path_hex.read_text(), len_max=MemoryMap['app_size'])
encrypt_main = file_upgrade.file_encryption(bin_main)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = ByteConv.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:=file_upgrade.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(encrypt_main)] = encrypt_main
# 额外处理
if 'output_bin' in kwargs.keys() and kwargs['output_bin']:
(path_hex / (path_hex.stem + '.bin')).write_bytes(bin_main)
return bytearray(Image)
def GenerateImage(type_dev: str, path_boot: Path, path_main: Path, path_back: Path, **kwargs) ->bytearray:
""" 镜像生成 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(type_dev.encode('ascii')), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
match type_dev:
case 'SLCP001':
MemoryMap = MemoryMap_SLCP001
case 'SLCP101':
MemoryMap = MemoryMap_460
case 'SLCP102':
MemoryMap = MemoryMap_460
case 'DLSY001':
MemoryMap = MemoryMap_460
case _:
raise Exception("Unknow device.")
bin_boot = IntelHex.file_IntelHex_to_Bin(path_boot.read_text(), len_max=MemoryMap['boot_size'])
bin_main = IntelHex.file_IntelHex_to_Bin(path_main.read_text(), len_max=MemoryMap['app_size'])
bin_back = IntelHex.file_IntelHex_to_Bin(path_back.read_text(), len_max=MemoryMap['app_size'])
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = ByteConv.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:=file_upgrade.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'] = ByteConv.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:=file_upgrade.build_header_new(config)) is None:
raise Exception("Header tag oversize. ")
# 组装镜像
Image = [0xFF] * MemoryMap['image_size']
Image[MemoryMap['boot_addr']: MemoryMap['boot_addr'] + len(bin_boot)] = bin_boot
Image[MemoryMap['main_addr']: MemoryMap['main_addr'] + len(bin_main)] = bin_main
Image[MemoryMap['back_addr']: MemoryMap['back_addr'] + len(bin_back)] = bin_back
Image[MemoryMap['main_header']: MemoryMap['main_header'] + len(main_header)] = main_header
Image[MemoryMap['back_header']: MemoryMap['back_header'] + len(back_header)] = back_header
# Log打印
print("Merge Image generated successfully.")
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))}]")
# 额外文件
if 'output_header' in kwargs.keys() and kwargs['output_header']:
(path_main.parent / (path_main.stem + '.header')).write_bytes(main_header)
(path_back.parent / (path_back.stem + '.header')).write_bytes(back_header)
if 'output_bin' in kwargs.keys() and kwargs['output_bin']:
(path_main.parent / (path_main.stem + '.bin')).write_bytes(bin_main)
(path_back.parent / (path_back.stem + '.bin')).write_bytes(bin_back)
if 'output_encrypt' in kwargs.keys() and kwargs['output_encrypt']:
encrypt_main = file_upgrade.file_encryption(bin_main)
encrypt_back = file_upgrade.file_encryption(bin_back)
(path_main.parent / (path_main.stem + '.encrypt')).write_bytes(encrypt_main)
(path_back.parent / (path_back.stem + '.encrypt')).write_bytes(encrypt_back)
return bytearray(Image)
def GeneratePackage_SLCP001_p4a0(path_hex: Path):
""" 叠光适配器-460平台版本 生成升级包 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(b"SLCP001"), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
bin_main = IntelHex.file_IntelHex_to_Bin(path_hex.read_text(), len_max=0x040000)
encrypt_main = file_upgrade.file_encryption(bin_main)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = ByteConv.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:=file_upgrade.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(encrypt_main)] = encrypt_main
return bytearray(Image), bin_main
def GeneratePackage_SLCP101_p460(path_hex: Path):
""" 叠光适配器-460平台版本 生成升级包 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(b"SLCP101"), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
bin_main = IntelHex.file_IntelHex_to_Bin(path_hex.read_text(), len_max=0x024000)
encrypt_main = file_upgrade.file_encryption(bin_main)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = ByteConv.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:=file_upgrade.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(encrypt_main)] = encrypt_main
return bytearray(Image), bin_main
def GeneratePackage_SLCP102_p460(path_hex: Path):
""" 叠光适配器-460平台版本 生成升级包 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(b"SLCP102"), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
bin_main = IntelHex.file_IntelHex_to_Bin(path_hex.read_text(), len_max=0x024000)
encrypt_main = file_upgrade.file_encryption(bin_main)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = ByteConv.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:=file_upgrade.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(encrypt_main)] = encrypt_main
return bytearray(Image), bin_main
def GenerateImage_SLCP001_p4a0(path_boot: Path, path_main: Path, path_back: Path):
""" 叠光适配器-4A0平台版本 镜像生成 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(b"SLCP001"), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
bin_boot = IntelHex.file_IntelHex_to_Bin(path_boot.read_text(), len_max=0x010000)
bin_main = IntelHex.file_IntelHex_to_Bin(path_main.read_text(), len_max=0x0CC000)
bin_back = IntelHex.file_IntelHex_to_Bin(path_back.read_text(), len_max=0x040000)
encrypt_main = file_upgrade.file_encryption(bin_main)
encrypt_back = file_upgrade.file_encryption(bin_back)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = ByteConv.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:=file_upgrade.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'] = ByteConv.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:=file_upgrade.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(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] * 0x100000
offset_image = 0
Image[offset_image: offset_image + len(bin_boot)] = bin_boot
offset_image = 0x010000
Image[offset_image: offset_image + len(bin_main)] = bin_main
offset_image = 0x0BC000
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, back_header
def GenerateImage_SLCP101_p460(path_boot: Path, path_main: Path, path_back: Path):
""" 叠光适配器-460平台版本 镜像生成 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(b"SLCP101"), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
bin_boot = IntelHex.file_IntelHex_to_Bin(path_boot.read_text(), len_max=0x00C000)
bin_main = IntelHex.file_IntelHex_to_Bin(path_main.read_text(), len_max=0x024000)
bin_back = IntelHex.file_IntelHex_to_Bin(path_back.read_text(), len_max=0x024000)
encrypt_main = file_upgrade.file_encryption(bin_main)
encrypt_back = file_upgrade.file_encryption(bin_back)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = ByteConv.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:=file_upgrade.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'] = ByteConv.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:=file_upgrade.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(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] * 0x058000
offset_image = 0
Image[offset_image: offset_image + len(bin_boot)] = bin_boot
offset_image = 0x00C000
Image[offset_image: offset_image + len(bin_main)] = bin_main
offset_image = 0x030000
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, back_header
def GenerateImage_SLCP102_p460(path_boot: Path, path_main: Path, path_back: Path):
""" 叠光适配器-460平台版本 镜像生成 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(b"SLCP102"), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
bin_boot = IntelHex.file_IntelHex_to_Bin(path_boot.read_text(), len_max=0x00C000)
bin_main = IntelHex.file_IntelHex_to_Bin(path_main.read_text(), len_max=0x024000)
bin_back = IntelHex.file_IntelHex_to_Bin(path_back.read_text(), len_max=0x024000)
encrypt_main = file_upgrade.file_encryption(bin_main)
encrypt_back = file_upgrade.file_encryption(bin_back)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = ByteConv.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:=file_upgrade.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'] = ByteConv.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:=file_upgrade.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(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] * 0x058000
offset_image = 0
Image[offset_image: offset_image + len(bin_boot)] = bin_boot
offset_image = 0x00C000
Image[offset_image: offset_image + len(bin_main)] = bin_main
offset_image = 0x030000
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, back_header
def GeneratePackage_DLSY001_p460(path_hex: Path):
""" 叠光优化器-460平台版本 生成升级包 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(b"DLSY001"), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
bin_main = IntelHex.file_IntelHex_to_Bin(path_hex.read_text(), len_max=0x024000)
encrypt_main = file_upgrade.file_encryption(bin_main)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = ByteConv.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:=file_upgrade.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(encrypt_main)] = encrypt_main
return bytearray(Image), bin_main
def GenerateImage_DLSY001_p460(path_boot: Path, path_main: Path, path_back: Path):
""" 叠光优化器-460平台版本 镜像生成 """
config = {
'prod_type': [0x45, 0x00], # 产品类型
'method_compress': False, # 文件压缩
'prog_id': list(b"DLSY001"), # 程序识别号
'prog_type': 'app', # 程序类型
'area_code': [0x00, 0x00], # 地区
}
bin_boot = IntelHex.file_IntelHex_to_Bin(path_boot.read_text(), len_max=0x00C000)
bin_main = IntelHex.file_IntelHex_to_Bin(path_main.read_text(), len_max=0x024000)
bin_back = IntelHex.file_IntelHex_to_Bin(path_back.read_text(), len_max=0x024000)
encrypt_main = file_upgrade.file_encryption(bin_main)
encrypt_back = file_upgrade.file_encryption(bin_back)
md5_ctx = hashlib.md5()
md5_ctx.update(bin_main)
config["md5"] = list(md5_ctx.digest())
config['file_length'] = ByteConv.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:=file_upgrade.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'] = ByteConv.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:=file_upgrade.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(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] * 0x058000
offset_image = 0
Image[offset_image: offset_image + len(bin_boot)] = bin_boot
offset_image = 0x00C000
Image[offset_image: offset_image + len(bin_main)] = bin_main
offset_image = 0x030000
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, back_header