import os import argparse import shutil GIT_HASH = "e3e4e86fdf3bb66747436c485453fd07" GIT_HASH_BIN = bytes.fromhex(GIT_HASH) INITIAL_DIR = os.path.dirname(os.path.abspath(__file__)) APP_VER_ADDRESS = 0x6D000 GOLDEN_APP_VER_ADDRESS = 0xDE000 GOLDEN_ADDRESS = 0x0071000 GOLDEN_APP_VERSION_SHIFTED = GOLDEN_APP_VER_ADDRESS-GOLDEN_ADDRESS def get_git_hash(): # Проверяем текущую директорию. Если не initial_dir, то переходим в нее print(f"Текущая директория: {os.getcwd()}") print(f"Исходная директория: {INITIAL_DIR}") if os.getcwd() != INITIAL_DIR: os.chdir(INITIAL_DIR) # Переходим в директорию с git репозиторием git_dir = find_git_repository() if git_dir is None: print("Не удалось найти git репозиторий.") return None os.chdir(git_dir) # Получаем git hash --short try: git_hash = os.popen('git rev-parse --short HEAD').read().strip() except Exception as e: print(f"Ошибка при получении git hash: {e}") git_hash = None # Возвращаемся в исходную директорию os.chdir(os.path.dirname(INITIAL_DIR)) return git_hash def get_git_tag(): # Проверяем текущую директорию. Если не initial_dir, то переходим в нее if os.getcwd() != INITIAL_DIR: os.chdir(INITIAL_DIR) # Переходим в директорию с git репозиторием git_dir = find_git_repository() if git_dir is None: print("Не удалось найти git репозиторий.") return None os.chdir(git_dir) # Получаем git tag try: git_tag = os.popen('git describe --tags').read().strip() except Exception as e: print(f"Ошибка при получении git tag: {e}") git_tag = None # Возвращаемся в исходную директорию os.chdir(os.path.dirname(INITIAL_DIR)) return git_tag def find_git_repository(): current_dir = INITIAL_DIR try: # Выходим выше по дереву каталогов, пока не найдем .git while True: if os.path.isdir(os.path.join(current_dir, '.git')): git_dir = os.path.abspath(os.path.join(current_dir, '.git')) print(f"Найден git репозиторий: {git_dir}") return git_dir parent_dir = os.path.dirname(current_dir) if parent_dir == current_dir: # Достигли корня файловой системы print("Не удалось найти git репозиторий.") return None current_dir = parent_dir print(f"Проверяем директорию: {current_dir}") except Exception as e: print(f"Ошибка при поиске git репозитория: {e}") return None finally: # Возвращаемся в исходную директорию os.chdir(INITIAL_DIR) def find_tag(tag_pattern): # Проверяем текущую директорию. Если не initial_dir, то переходим в нее if os.getcwd() != INITIAL_DIR: os.chdir(INITIAL_DIR) # Переходим в директорию с git репозиторием git_dir = find_git_repository() if git_dir is None: print("Не удалось найти git репозиторий.") return None os.chdir(git_dir) # Получаем все теги в git репозитории all_tags = os.popen('git tag').read().strip().split('\n') if not all_tags: print("Не найдено ни одного тега в git репозитории.") return None # Фильтруем теги по заданному шаблону matching_tags = [tag for tag in all_tags if tag_pattern in tag] if not matching_tags: print(f"Не найдено тегов, соответствующих шаблону: {tag_pattern}") return None # Получаем последний тег из списка совпадений latest_tag = matching_tags[-1] print(f"Найден тег: {latest_tag}") # Возвращаемся в исходную директорию os.chdir(os.path.dirname(INITIAL_DIR)) return latest_tag def merge_bins (): # Пути к файлам os.chdir(INITIAL_DIR) pwd = os.getcwd() file_path_working = os.path.join(INITIAL_DIR, "SB_TMSG44V1_WORKING_FPGA.bin") file_path_golden = os.path.join(INITIAL_DIR, "SB_TMSG44V1_GOLD_FPGA.bin") file_path_output = os.path.join(INITIAL_DIR, "SB_TMSG44V1_TEST_MERGE_FPGA.bin") # Размеры файлов file_size_working = os.path.getsize(file_path_working) file_size_golden = os.path.getsize(file_path_golden) # Размер выходного файла - 8 Мбит file_size_output = 0x1000000 # Записываем первый файл with open(file_path_output,'wb') as outfile: with open(file_path_working, 'rb') as f1: shutil.copyfileobj(f1, outfile) # Перемещаемся к адресу для второго файла outfile.seek(GOLDEN_ADDRESS) with open(file_path_golden, 'rb') as f2: shutil.copyfileobj(f2, outfile) # Перемещаемся к адресу для пользовательских данных outfile.seek(APP_VER_ADDRESS) current_git_tag=find_tag("_WORKING") print(f"Текущий git tag: {current_git_tag}") # Если полученный тег меньше 32 байт, то дополняем его до 32 байт encoded_git_tag = current_git_tag.encode('utf-8') if len(encoded_git_tag) < 32: encoded_git_tag = encoded_git_tag.ljust(32, b'\x00') # Записываем тег в файл outfile.write(encoded_git_tag) # Перемещаемся к адресу для GOLDEN данных outfile.seek(GOLDEN_APP_VER_ADDRESS) golden_tag = find_tag("_GOLDEN") print(f"Текущий golden git tag: {golden_tag}") # Если полученный тег меньше 32 байт, то дополняем его до 32 байт encoded_golden_tag = golden_tag.encode('utf-8') if len(encoded_golden_tag) < 32: encoded_golden_tag = encoded_golden_tag.ljust(32, b'\x00') outfile.write(encoded_golden_tag) final_size = os.path.getsize(file_path_output) # Проверка итогового размера if final_size > file_size_output: os.remove(file_path_output) # Удаляем некорректный файл raise ValueError(f"Итоговый размер файла ({final_size} байт) превысил максимально допустимый ({file_size_output} байт)") print(f"Размер файла 1: {file_size_working} байт") print(f"Размер файла 2: {file_size_golden} байт") print(f"Итоговый размер: {final_size} байт") return final_size def merge_working_only(): # Пути к файлам os.chdir(INITIAL_DIR) pwd = os.getcwd() file_path_working = os.path.join(INITIAL_DIR, "SB_TMSG44V1_WORKING_FPGA.bin") file_path_output = os.path.join(INITIAL_DIR, "SB_TMSG44V1_TEST_WORKING_FPGA.bin") # Размеры файлов file_size_working = os.path.getsize(file_path_working) # Размер выходного файла - 8 Мбит file_size_output = 0x1000000 # Записываем первый файл with open(file_path_output,'wb') as outfile: with open(file_path_working, 'rb') as f1: shutil.copyfileobj(f1, outfile) # Перемещаемся к адресу для пользовательских данных outfile.seek(APP_VER_ADDRESS) current_git_tag=find_tag("_WORKING") print(f"Текущий git tag: {current_git_tag}") # Если полученный тег меньше 32 байт, то дополняем его до 32 байт encoded_git_tag = current_git_tag.encode('utf-8') if len(encoded_git_tag) < 32: encoded_git_tag = encoded_git_tag.ljust(32, b'\x00') # Записываем тег в файл outfile.write(encoded_git_tag) final_size = os.path.getsize(file_path_output) # Проверка итогового размера if final_size > file_size_output: os.remove(file_path_output) # Удаляем некорректный файл raise ValueError(f"Итоговый размер файла ({final_size} байт) превысил максимально допустимый ({file_size_output} байт)") print(f"Размер файла: {file_size_working} байт") print(f"Итоговый размер: {final_size} байт") return final_size def merge_golden_only(): # Пути к файлам os.chdir(INITIAL_DIR) pwd = os.getcwd() file_path_golden = os.path.join(INITIAL_DIR, "SB_TMSG44V1_GOLD_FPGA.bin") file_path_output = os.path.join(INITIAL_DIR, "SB_TMSG44V1_TEST_GOLDEN_FPGA.bin") # Размеры файлов file_size_golden = os.path.getsize(file_path_golden) # Размер выходного файла - 8 Мбит file_size_output = 0x1000000 # Записываем первый файл with open(file_path_output,'wb') as outfile: with open(file_path_golden, 'rb') as f2: shutil.copyfileobj(f2, outfile) # Перемещаемся к адресу для пользовательских данных outfile.seek(GOLDEN_APP_VERSION_SHIFTED) golden_tag = find_tag("_GOLDEN") print(f"Текущий golden git tag: {golden_tag}") # Если полученный тег меньше 32 байт, то дополняем его до 32 байт encoded_golden_tag = golden_tag.encode('utf-8') if len(encoded_golden_tag) < 32: encoded_golden_tag = encoded_golden_tag.ljust(32, b'\x00') outfile.write(encoded_golden_tag) final_size = os.path.getsize(file_path_output) # Проверка итогового размера if final_size > file_size_output: os.remove(file_path_output) # Удаляем некорректный файл raise ValueError(f"Итоговый размер файла ({final_size} байт) превысил максимально допустимый ({file_size_output} байт)") print(f"Размер файла: {file_size_golden} байт") print(f"Итоговый размер: {final_size} байт") return final_size def main(): parser = argparse.ArgumentParser(description='Скрипт для объединения бинарных файлов прошивок') parser.add_argument('--mode', choices=['merge', 'working', 'golden'], help='Режим работы: merge - объединить Working и Golden, working - только Working и Working версию, golden - только Golden и Golden версию', required=False) args = parser.parse_args() # Если режим не задан через аргумент, запрашиваем у пользователя if args.mode is None: print("Выберите режим работы:") print("1. merge - объединить Working и Golden прошивки") print("2. working - объединить только Working прошивку с её версией") print("3. golden - объединить только Golden прошивку с её версией") choice = "" while choice not in ["1", "2", "3", "merge", "working", "golden"]: choice = input("Введите номер (1-3) или название режима: ").strip().lower() if choice == "1": choice = "merge" elif choice == "2": choice = "working" elif choice == "3": choice = "golden" mode = choice else: mode = args.mode if mode == 'merge': print("Объединение Working и Golden прошивок...") merge_bins() elif mode == 'working': print("Объединение только Working прошивки с её версией...") merge_working_only() elif mode == 'golden': print("Объединение только Golden прошивки с её версией...") merge_golden_only() if __name__ == '__main__': main()