# 升级包生成脚本 import hashlib from pathlib import Path from datetime import datetime from crc import Calculator, Crc16 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 'file_version': [0x01, 2], # 1 - 文件版本; 2byte 'file_length': [0x02, 4], # 2 - 文件长度; 4byte 'md5': [0x03, 16], # 3 - 文件MD5; 16byte 'encrypt': [0x04, 1], # 4 - 加密算法; 1byte 'update_type': [0x05, 1], # 5 - 升级文件类别; 1byte 'update_spec': [0x06, 4], # 6 - 升级特征字; 4byte 'update_verison': [0x07, 4], # 7 - 升级版本号; 4byte 'update_date': [0x08, 3], # 8 - 升级版本日期; 3byte 'area_code': [0x09, 4], # 9 - 省份特征; 4byte 'uptate_str': [0x0A, -1, 64], # 10 - 升级段描述; less than 64byte 'device_str': [0x0D, -1, 64], # 13 - 设备特征描述; less than 64byte 'hex_name': [0xFF, -1, 80], # 255 - Hex文件名; less than 80byte } def file_encryption(buffer): """ 文件加密算法 """ pwd_idx = 0 pwd = b'moc.mmocspot.www' pwd = list(map(lambda x: (x - 0x30 + 0x100) % 0x100, pwd)) result = bytearray(len(buffer)) for i in range(len(buffer)): k = i k |= i >> 8 k |= i >> 16 k |= i >> 24 result[i] = buffer[i] ^ pwd[pwd_idx] ^ (k & 0xFF) pwd_idx = (pwd_idx + 1) % len(pwd) return result def build_header(config: dict, len_max=512): """ 基于配置参数, 生成文件信息头; V1版本, 依据字典生成tag标签组; """ # 定义文件头 m_file_header = bytearray(len_max) header_len = 11 tag_num = 0 for tag, value in config.items(): if tag in Header_Tag.keys(): 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] tag_date = [Header_Tag[tag][0], tag_len] + value[:tag_len] m_file_header[header_len: header_len + tag_len + 2] = bytearray(tag_date) tag_num += 1 header_len += 2 + tag_len m_file_header[0:8] = b"TOPSCOMM" m_file_header[8] = ((header_len - 10) % 0x100) m_file_header[9] = ((header_len - 10) // 0x100) m_file_header[10] = tag_num m_file_header[header_len] = sum(m_file_header[:header_len]) % 0x100 m_file_header[header_len+1] = sum(m_file_header[:header_len]) // 0x100 if header_len+2 > len_max: return None else: return m_file_header def build_header_lite(config: dict): """ 基于配置参数, 生成文件信息头; V2版本, 仅提供必要信息; """ # 定义文件头 m_file_header = bytearray(64) m_file_header[0:4] = bytearray(config["update_verison"]) m_file_header[4:8] = bytearray(config["file_length"]) m_file_header[8:24] = bytearray(config["md5"]) return m_file_header def build_header_new(config: dict): """ 基于配置参数, 生成新版文件信息头; V3版本, 依据新版格式填充数据; """ # 定义文件头 m_file_header = [0xFF] * 184 m_file_header[0:8] = list(b"TOPSCOMM") m_file_header[8:10] = config['prod_type'] m_file_header[10:22] = config['prog_id'] + [0] * (12 - len(config['prog_id'])) if config['method_compress'] == True: m_file_header[23] = 0x01 else: m_file_header[23] = 0x00 if 'crc32' in config.keys(): m_file_header[22] = 0x00 m_file_header[24: 40] = config['crc32'] + [0x00] * 12 elif 'md5' in config.keys(): m_file_header[22] = 0x01 m_file_header[24: 40] = config['md5'] else: raise Exception("Error, Unknown method verify.") # 时间戳生成 time_now = datetime.now() time_stamp = list(map(lambda x: int(x), time_now.strftime("%Y-%m-%d-%H-%M").split('-'))) time_stamp.insert(1, time_stamp[0] // 0x100) time_stamp[0] = time_stamp[0] % 0x100 m_file_header[40: 46] = time_stamp m_file_header[46: 50] = config['file_length'] # Cpu1 m_file_header[50: 54] = [0x00] * 4 m_file_header[54: 70] = [0x00] * 16 # Cpu2 m_file_header[70: 74] = [0x00] * 4 m_file_header[74: 90] = [0x00] * 16 if config['prog_type'] == 'app': m_file_header[90: 92] = [0x00, 0x00] elif config['prog_type'] == 'boot': m_file_header[90: 92] = [0x01, 0x00] elif config['prog_type'] == 'diff': m_file_header[90: 92] = [0x02, 0x00] elif config['prog_type'] == 'font': m_file_header[90: 92] = [0x03, 0x00] elif config['prog_type'] == 'config': m_file_header[90: 92] = [0x04, 0x00] elif config['prog_type'] == 'data': m_file_header[90: 92] = [0x05, 0x00] elif config['prog_type'] == 'test': m_file_header[90: 92] = [0x06, 0x00] else: raise Exception("Error, Unknown Program Type.") m_file_header[92: 94] = config['area_code'] m_file_header[94: 158] = config['hex_name'] if 'upgrade_type' in config.keys(): 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 = bytearray(m_file_header) calculator = Calculator(Crc16.MODBUS) code_crc16 = calculator.checksum(m_file_header[:-2]) m_file_header[182: 184] = [code_crc16 // 0x100, code_crc16 % 0x100] return m_file_header def parser_version_info(file_bin: bytearray, base_addr:int): """ 解析Bin文件内的版本信息结构体 """ address_block = (file_bin[6] << 24) + (file_bin[7] << 16) + (file_bin[4] << 8) + file_bin[5] address_block -= base_addr address_block *= 2 offset = address_block block_version = {} block_version['name'] = file_bin[offset + 1 : offset + 64 : 2] offset += 64 block_version['device'] = file_bin[offset + 1 : offset + 64 : 2] offset += 64 block_version['factory'] = file_bin[offset + 1 : offset + 32 : 2] offset += 32 block_version['hardware'] = file_bin[offset + 1 : offset + 64 : 2] offset += 64 return block_version 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) # 测试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(): """ 校验, 加密测试 """ # 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] # data = "54 4F 50 53 43 4F 4D 4D 45 00 53 4C 43 50 30 30 31 00 00 00 00 00 01 00 B6 61 A8 73 BF 82 9E A7 4C 79 F6 BB 94 E2 A5 18 E8 07 05 18 0B 17 18 4C 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 6C 61 6D 69 6E 61 5F 61 64 61 70 74 65 72 5F 6D 61 69 6E 02 00 00 00 00 20 10 53 06 00 00 00 00 80 A5 8F 02 00 00 00 00 EC 1F 40 00 00 00 00 00 00 00 00 00 00 00 00 00 7A CA 61 0A FD 7F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" # byte_data = list(map(lambda x: int(x, 16), data.split(' '))) # crc = "99 CB" calculator = Calculator(Crc16.MODBUS) 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_de = file_encryption(buffer2) pass 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 自机升级文件 'file_version': [0x00, 0x00], # 文件版本-00 用于兼容文件格式升级 # 'file_length': [], # 文件长度(自动生成) # 'md5': [], # 文件MD5(自动生成) 'encrypt': [0x01], # 默认加密算法 'update_type': [0x01], # APP升级 'update_spec': [0x00, 0x00, 0x00, 0x00], # 升级特征字 'update_verison': [0x02, 0x00, 0x00, 0x01], # 升级版本号 'update_date': [0x22, 0x04, 0x24], # 升级版本日期 # 'area_code': [], # 省份特征 # 'uptate_str': [], # 升级段描述 # 'device_str': [], # 设备特征描述 # 'hex_name': [], # Hex文件名(自动读取) # 文件Hex结构信息 # 'flash_addr': 0x3E8020, # 程序起始地址 # 'flash_size': 0x005FC0, # 程序空间大小 } 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_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_bin) file2 = path_bin.parent / (path_bin.stem + '_h512.dat') file2.write_bytes(header_512 + data_bin) 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 = 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(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 = 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(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_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 = file_IntelHex_to_Bin(path_hex.read_text(), len_max=0x024000) 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(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 = 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(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 = file_IntelHex_to_Bin(path_hex.read_text(), len_max=0x024000) 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(encrypt_main)] = encrypt_main return bytearray(Image), bin_main 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"DLSP001"), # 程序识别号 'prog_type': 'app', # 程序类型 'area_code': [0x00, 0x00], # 地区 'upgrade_type': [0x00, 0x00], # 升级方式(0-片外缓冲, 1-片内缓冲, 2-升级备份) } 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(bin_main) config["md5"] = list(md5_ctx.digest()) 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'])) 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['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"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] * 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) info_version = parser_version_info(bin_main, 0x88000) 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(info_version['name'])[: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(encrypt_main)] = encrypt_main return bytearray(Image), bin_main def Process1(): """ 镜像生成流程 """ root = Path(r"test\p460") result = Path(r"test\p460\result") # 正常启动镜像 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 / 'SLCP101_header_main.bin' file_back_header = result / 'SLCP101_header_back.bin' file_package = result / f'{hex_update.stem}.dat' file_bin = result / f'{hex_update.stem}.bin' data_bins = GenerateImage_SLCP101_p460(hex_boot, hex_main, hex_back) data_package, data_bins = GeneratePackage_SLCP101_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[2].copy()) file_package.write_bytes(data_package) file_bin.write_bytes(data_bins) # 异常镜像-主分区md5错误 file_image1 = result / f'{file_image.stem}_b1.bin' data_image = data_bins[0].copy() data_image[0x054018: 0x05401A] = [0x00, 0x01] file_image1.write_bytes(data_image) # 异常镜像-备份分区md5错误 file_image2 = result / f'{file_image.stem}_b2.bin' data_image = data_bins[0].copy() data_image[0x056018: 0x05601A] = [0x00, 0x01] file_image2.write_bytes(data_image) # 异常镜像-双分区md5错误 file_image3 = result / f'{file_image.stem}_b3.bin' data_image = data_bins[0].copy() data_image[0x054018: 0x05401A] = [0x00, 0x01] data_image[0x056018: 0x05601A] = [0x00, 0x01] file_image3.write_bytes(data_image) def Process2(): """ 镜像生成流程 """ root = Path(r"D:\WorkingProject\LightStackOptimizer\software\lamina_optimizer\lamina_optimizer\Debug") # result = Path(r"test\p460_o1\result") result = root # 正常启动镜像 hex_boot = Path(r"test\p460_o1\bootloader.hex") hex_main = root / r"lamina_optimizer.hex" hex_back = root / r"lamina_optimizer.hex" hex_update = root / r"lamina_optimizer.hex" file_image = result / f'{hex_main.stem}_ROM.bin' file_main_header = result / 'DLSY001_header_main.bin' file_back_header = result / 'DLSY001_header_back.bin' file_package = result / f'{hex_update.stem}.dat' file_bin = result / f'{hex_update.stem}.bin' data_bins = GenerateImage_DLSY001_p460(hex_boot, hex_main, hex_back) data_package, data_bin = GeneratePackage_DLSY001_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[2].copy()) file_package.write_bytes(data_package) file_bin.write_bytes(data_bin) # 异常镜像-主分区md5错误 file_image1 = result / f'{file_image.stem}_b1.bin' data_image = data_bins[0].copy() data_image[0x054018: 0x05401A] = [0x00, 0x01] file_image1.write_bytes(data_image) # 异常镜像-备份分区md5错误 file_image2 = result / f'{file_image.stem}_b2.bin' data_image = data_bins[0].copy() data_image[0x056018: 0x05601A] = [0x00, 0x01] file_image2.write_bytes(data_image) # 异常镜像-双分区md5错误 file_image3 = result / f'{file_image.stem}_b3.bin' data_image = data_bins[0].copy() data_image[0x054018: 0x05401A] = [0x00, 0x01] data_image[0x056018: 0x05601A] = [0x00, 0x01] file_image3.write_bytes(data_image) if __name__ == "__main__": # path_bin = Path("F:\\Work\\FPGA\\Test\\Vivado\\test_update\\test_update.vitis\\upgrade_system\\Debug\\sd_card\\BOOT.BIN") # GeneratePackage_Demo_Xilinx(path_bin) Process2() pass