import sys import os import re import subprocess, shlex ################################################## download ################################################## def get_sdk_root_path_by_project_path(ProjectPath): Pattern = r'(.*)/boards/' SearchResult = re.search(Pattern, ProjectPath, re.S) if SearchResult != None: return SearchResult.group(1) else: print("Error: correct ssdk root path was not found") sys.exit(1) def add_double_quotes(Strings): return '"' + Strings + '"' def jlink_exe_file(FilePathName): JlinkCmd = JlinkExe + add_double_quotes(FilePathName) args = shlex.split(JlinkCmd) # subprocess.run(args, check=True, stdout=subprocess.DEVNULL) subprocess.run(args, check=True) def download_file(File, Addr): print("loadfile: %s %s" %(File, Addr)) CmdFilePathName = ProjectPath + "/cmd.txt" LoadFileString = "LoadFile " + add_double_quotes(File) + " " + Addr + " noreset" ExitString = "q" with open(CmdFilePathName, "w") as f: f.write("h" + "\n") f.write(LoadFileString + "\n") f.write(ExitString) try: jlink_exe_file(CmdFilePathName) os.remove(CmdFilePathName) except Exception as e: os.remove(CmdFilePathName) raise Exception("download error:\n %s" %e) def get_download_info_by_project_file(ProjectPathName, FlashType): with open(ProjectPathName, "r", encoding="utf-8") as f: Content = f.read() Pattern = r'()'.format(FlashType) SearchResult = re.search(Pattern, Content, re.S) if SearchResult != None: return SearchResult.group(1) else: print("Error: no download info find") sys.exit(1) def get_multicore_download_info_by_project_file(ProjectPathName, FlashType, Part): with open(ProjectPathName, "r", encoding="utf-8") as f: Content = f.read() Pattern = r'()'.format(FlashType, Part) SearchResultMulticore = re.search(Pattern, Content, re.S) if SearchResultMulticore != None: return SearchResultMulticore.group(1) else: return None def get_str_from_download_info(DownloadInfo, FindString): Pattern = FindString + r'="(.*?)"' SearchResult = re.search(Pattern, DownloadInfo, re.S) if SearchResult != None: return SearchResult.group(1) else: return None def is_sfs_file(FileName): Pattern = r'sfs_.*' SearchResult = re.search(Pattern, FileName, re.S) if SearchResult != None: return True else: return False def is_need_sign(FileName): if is_sfs_file(FileName) == True: return False elif FileName == "sf_signed.bin" or FileName == "sp0_signed.bin" or FileName == "sp1_signed.bin" or FileName == "sx0_signed.bin" or FileName == "sx1_signed.bin": return True elif FileName == "sf.bin" or FileName == "sp0.bin" or FileName == "sp1.bin" or FileName == "sx0.bin" or FileName == "sx1.bin": return False else: print("Error: %s is error file name" %FileName) sys.exit(1) def is_need_download(FileName): if is_sfs_file(FileName) == True: return True elif FileName == "sf_signed.bin" or FileName == "sf.bin" or FileName == "sp0.bin" or FileName == "sp1.bin" or FileName == "sx0.bin" or FileName == "sx1.bin": return True elif FileName == "sp0_signed.bin" or FileName == "sp1_signed.bin" or FileName == "sx0_signed.bin" or FileName == "sx1_signed.bin": return False else: print("Error: %s is error file name" %FileName) sys.exit(1) def get_unsigned_bin_name(FileName): DictTmp = {'sf_signed.bin':'sf.bin', 'sp0_signed.bin':'sp0.bin', 'sp1_signed.bin':'sp1.bin', 'sx0_signed.bin':'sx0.bin', 'sx1_signed.bin':'sx1.bin'} return DictTmp.get(FileName) def gen_info_from_download_info(DownloadInfo, FileString, AddrString): if DownloadInfo == None: return FilePathName = get_str_from_download_info(DownloadInfo, FileString) if FilePathName != None and FilePathName != "": FilePathName = os.path.abspath(FilePathName.replace("$(ProjectDir)", ProjectPath)).replace('\\', '/') FilePath = os.path.dirname(FilePathName) FileName = os.path.basename(FilePathName) if is_need_sign(FileName): # 签名 UnsignedBinPathName = FilePath + "/" + get_unsigned_bin_name(FileName) Addr = get_str_from_download_info(DownloadInfo, AddrString) if Addr != None and Addr != "": UnsignedBinAddr = Addr SignInfoDict.update({UnsignedBinPathName:UnsignedBinAddr}) if is_need_download(FileName): Addr = get_str_from_download_info(DownloadInfo, AddrString) if Addr != None and Addr != "": DownloadInfoDict.update({FilePathName:Addr}) def get_sign_and_download_info_by_project_file(ProjectPathName, FlashType, Part): DownloadInfo = get_download_info_by_project_file(ProjectPathName, FlashType) MulticoreDownloadInfo = get_multicore_download_info_by_project_file(ProjectPathName, FlashType, Part) FileString = "debug_additional_load_file" AddrStr = "debug_additional_load_file_address" gen_info_from_download_info(DownloadInfo, FileString, AddrStr) gen_info_from_download_info(MulticoreDownloadInfo, FileString, AddrStr) FileString = "debug_additional_load_file1" AddrStr = "debug_additional_load_file_address1" gen_info_from_download_info(DownloadInfo, FileString, AddrStr) gen_info_from_download_info(MulticoreDownloadInfo, FileString, AddrStr) FileString = "debug_additional_load_file2" AddrStr = "debug_additional_load_file_address2" gen_info_from_download_info(DownloadInfo, FileString, AddrStr) gen_info_from_download_info(MulticoreDownloadInfo, FileString, AddrStr) FileString = "debug_additional_load_file3" AddrStr = "debug_additional_load_file_address3" gen_info_from_download_info(DownloadInfo, FileString, AddrStr) gen_info_from_download_info(MulticoreDownloadInfo, FileString, AddrStr) FileString = "external_build_file_name" AddrStr = "external_load_address" gen_info_from_download_info(DownloadInfo, FileString, AddrStr) gen_info_from_download_info(MulticoreDownloadInfo, FileString, AddrStr) def download_file_by_download_info(**DownloadInfoDict): for key, value in DownloadInfoDict.items(): if not os.path.exists(key): print("Error: %s does not exist" %key) sys.exit(1) download_file(key, value) ################################################## sign ################################################## def get_core_by_pathname(FilePathName): FileName = os.path.basename(FilePathName) DictTmp = {'sf.bin':'0', 'sp0.bin':'2', 'sp1.bin':'3', 'sx0.bin':'4', 'sx1.bin':'5'} return DictTmp.get(FileName) def get_entry_by_pathname(FilePathName, PartId): FileName = os.path.basename(FilePathName) if PartId == "E3104" or PartId == "E3106" or PartId == "E3205" or PartId == "E3206": DictTmp = {'sf.bin':'0x504000'} elif PartId == "E3110" or PartId == "E3210" or PartId == "E3340" or PartId == "D3246" or PartId == "D3248": DictTmp = {'sf.bin':'0x404000'} elif PartId == "E3420": DictTmp = {'sf.bin':'0x404000', 'sx0.bin':'0x500000', 'sx1.bin':'0x580000'} elif PartId == "E3430": DictTmp = {'sf.bin':'0x404000', 'sx0.bin':'0x600000', 'sx1.bin':'0x680000'} elif PartId == "E3640" or PartId == "E3648": DictTmp = {'sf.bin':'0x404000', 'sp0.bin':'0x700000', 'sp1.bin':'0x780000', 'sx0.bin':'0x600000', 'sx1.bin':'0x680000'} else: print("Error: %s does not exist" %PartId) sys.exit(1) if DictTmp.get(FileName) == None: print("Error: %s does not exist" %FileName) sys.exit(1) return DictTmp.get(FileName) def get_bpt_base_by_part(FlashType): if FlashType == "HYPERFLASH": return 0x100C0000 elif FlashType == "NORFLASH": return 0x10007000 else: print("Error: FlashType error") sys.exit(1) def get_dlp_by_addr(Addr, FlashType): return int((int(Addr, 16) - get_bpt_base_by_part(FlashType)) / 512) def get_iib_info_by_sign_info(**SignInfoDict): global SignedBinPathName IIBInfo = "" for key, value in SignInfoDict.items(): if not os.path.exists(key): print("Error: %s does not exist" %key) sys.exit(1) if os.path.basename(key) == "sf.bin": SignedBinPathName = add_double_quotes(os.path.dirname(key) + "/sf_signed.bin") IIBInfo += "--iib core=%s type=0x0 image=%s dlp=0x%x to=%s entry=%s\n" % (get_core_by_pathname(key), add_double_quotes(key), get_dlp_by_addr(value, FlashType), get_entry_by_pathname(key, Part), get_entry_by_pathname(key, Part)) return IIBInfo def sign_file_by_sign_info(**SignInfoDict): SecVer = 0 KeyName = "TestRSA2048_ossl.pem" PSN = "0x100" IIBInfo = get_iib_info_by_sign_info(**SignInfoDict) ATB_SIGNER = "./sign_tool/windows/atb_signer.exe" os.chdir(os.path.join(SdkRootPath, "tools", "sdtools")) SignCmd = ATB_SIGNER + " sign --v 2 --sec_ver %s --dgst sha256 --rcp key=sign_tool/keys/%s\n%s--psn %s --of %s" %(SecVer, KeyName, IIBInfo, PSN, SignedBinPathName) print("SignCmd: %s" %SignCmd) print("sign file: %s" %SignedBinPathName) try: args = shlex.split(SignCmd) # subprocess.run(args, check=True, stdout=subprocess.DEVNULL) subprocess.run(args, check=True) except Exception as e: raise Exception("sign error:\n %s" %e) ################################################## main ################################################## if __name__ == "__main__": # 处理入参 JlinkPath = os.path.abspath(sys.argv[1]).replace('\\', '/') ProjectPathName = os.path.abspath(sys.argv[2]).replace('\\', '/') Part = sys.argv[3] FlashType = sys.argv[4] OperationType = sys.argv[5] # 生成需要的变量 ProjectPath = os.path.dirname(ProjectPathName) SdkRootPath = get_sdk_root_path_by_project_path(ProjectPath) # 如果是ide,进行签名后退出;如果是cmd,签名后继续下载 if OperationType == "$(OPS)": OnlySignBin = True elif OperationType == "download": OnlySignBin = False else: print("Error: %s is unsupport operation type" %OperationType) sys.exit(1) SignInfoDict = {} DownloadInfoDict = {} get_sign_and_download_info_by_project_file(ProjectPathName, FlashType, Part) print(SignInfoDict) print(DownloadInfoDict) if not SignInfoDict: print("Error: no signed files info found") sys.exit(1) sign_file_by_sign_info(**SignInfoDict) # 初始化TCM,擦除Flash if OnlySignBin == False: if not DownloadInfoDict: print("Error: no download files info found") sys.exit(1) DeviceName = Part + "_" + FlashType JlinkPathName = add_double_quotes(JlinkPath + '/JLink.exe') JlinkExe = JlinkPathName + " -device " + DeviceName + " -if SWD -speed 4000 -autoconnect 1 -CommandFile " if FlashType == "HYPERFLASH": InitFilePathName = os.path.join(SdkRootPath, "devices", Part, "flashloader", "init_before_download_hyperflash.txt").replace('\\', '/') elif FlashType == "NORFLASH": InitFilePathName = os.path.join(SdkRootPath, "devices", Part, "flashloader", "init_before_download_norflash.txt").replace('\\', '/') else: print("Error: %s is not right type" %FlashType) sys.exit(1) print("init tcm and erase flash: %s" %InitFilePathName) try: jlink_exe_file(InitFilePathName) except Exception as e: raise Exception("download error:\n %s" %e) download_file_by_download_info(**DownloadInfoDict)