BinsMerge.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import os
  2. import argparse
  3. import shutil
  4. GIT_HASH = "e3e4e86fdf3bb66747436c485453fd07"
  5. GIT_HASH_BIN = bytes.fromhex(GIT_HASH)
  6. INITIAL_DIR = os.path.dirname(os.path.abspath(__file__))
  7. APP_VER_ADDRESS = 0x6D000
  8. GOLDEN_APP_VER_ADDRESS = 0xDE000
  9. GOLDEN_ADDRESS = 0x0071000
  10. GOLDEN_APP_VERSION_SHIFTED = GOLDEN_APP_VER_ADDRESS-GOLDEN_ADDRESS
  11. def get_git_hash():
  12. # Проверяем текущую директорию. Если не initial_dir, то переходим в нее
  13. print(f"Текущая директория: {os.getcwd()}")
  14. print(f"Исходная директория: {INITIAL_DIR}")
  15. if os.getcwd() != INITIAL_DIR:
  16. os.chdir(INITIAL_DIR)
  17. # Переходим в директорию с git репозиторием
  18. git_dir = find_git_repository()
  19. if git_dir is None:
  20. print("Не удалось найти git репозиторий.")
  21. return None
  22. os.chdir(git_dir)
  23. # Получаем git hash --short
  24. try:
  25. git_hash = os.popen('git rev-parse --short HEAD').read().strip()
  26. except Exception as e:
  27. print(f"Ошибка при получении git hash: {e}")
  28. git_hash = None
  29. # Возвращаемся в исходную директорию
  30. os.chdir(os.path.dirname(INITIAL_DIR))
  31. return git_hash
  32. def get_git_tag():
  33. # Проверяем текущую директорию. Если не initial_dir, то переходим в нее
  34. if os.getcwd() != INITIAL_DIR:
  35. os.chdir(INITIAL_DIR)
  36. # Переходим в директорию с git репозиторием
  37. git_dir = find_git_repository()
  38. if git_dir is None:
  39. print("Не удалось найти git репозиторий.")
  40. return None
  41. os.chdir(git_dir)
  42. # Получаем git tag
  43. try:
  44. git_tag = os.popen('git describe --tags').read().strip()
  45. except Exception as e:
  46. print(f"Ошибка при получении git tag: {e}")
  47. git_tag = None
  48. # Возвращаемся в исходную директорию
  49. os.chdir(os.path.dirname(INITIAL_DIR))
  50. return git_tag
  51. def find_git_repository():
  52. current_dir = INITIAL_DIR
  53. try:
  54. # Выходим выше по дереву каталогов, пока не найдем .git
  55. while True:
  56. if os.path.isdir(os.path.join(current_dir, '.git')):
  57. git_dir = os.path.abspath(os.path.join(current_dir, '.git'))
  58. print(f"Найден git репозиторий: {git_dir}")
  59. return git_dir
  60. parent_dir = os.path.dirname(current_dir)
  61. if parent_dir == current_dir: # Достигли корня файловой системы
  62. print("Не удалось найти git репозиторий.")
  63. return None
  64. current_dir = parent_dir
  65. print(f"Проверяем директорию: {current_dir}")
  66. except Exception as e:
  67. print(f"Ошибка при поиске git репозитория: {e}")
  68. return None
  69. finally:
  70. # Возвращаемся в исходную директорию
  71. os.chdir(INITIAL_DIR)
  72. def find_tag(tag_pattern):
  73. # Проверяем текущую директорию. Если не initial_dir, то переходим в нее
  74. if os.getcwd() != INITIAL_DIR:
  75. os.chdir(INITIAL_DIR)
  76. # Переходим в директорию с git репозиторием
  77. git_dir = find_git_repository()
  78. if git_dir is None:
  79. print("Не удалось найти git репозиторий.")
  80. return None
  81. os.chdir(git_dir)
  82. # Получаем все теги в git репозитории
  83. all_tags = os.popen('git tag').read().strip().split('\n')
  84. if not all_tags:
  85. print("Не найдено ни одного тега в git репозитории.")
  86. return None
  87. # Фильтруем теги по заданному шаблону
  88. matching_tags = [tag for tag in all_tags if tag_pattern in tag]
  89. if not matching_tags:
  90. print(f"Не найдено тегов, соответствующих шаблону: {tag_pattern}")
  91. return None
  92. # Получаем последний тег из списка совпадений
  93. latest_tag = matching_tags[-1]
  94. print(f"Найден тег: {latest_tag}")
  95. # Возвращаемся в исходную директорию
  96. os.chdir(os.path.dirname(INITIAL_DIR))
  97. return latest_tag
  98. def merge_bins ():
  99. # Пути к файлам
  100. os.chdir(INITIAL_DIR)
  101. pwd = os.getcwd()
  102. file_path_working = os.path.join(INITIAL_DIR, "SB_TMSG44V1_WORKING_FPGA.bin")
  103. file_path_golden = os.path.join(INITIAL_DIR, "SB_TMSG44V1_GOLD_FPGA.bin")
  104. file_path_output = os.path.join(INITIAL_DIR, "SB_TMSG44V1_TEST_MERGE_FPGA.bin")
  105. # Размеры файлов
  106. file_size_working = os.path.getsize(file_path_working)
  107. file_size_golden = os.path.getsize(file_path_golden)
  108. # Размер выходного файла - 8 Мбит
  109. file_size_output = 0x1000000
  110. # Записываем первый файл
  111. with open(file_path_output,'wb') as outfile:
  112. with open(file_path_working, 'rb') as f1:
  113. shutil.copyfileobj(f1, outfile)
  114. # Перемещаемся к адресу для второго файла
  115. outfile.seek(GOLDEN_ADDRESS)
  116. with open(file_path_golden, 'rb') as f2:
  117. shutil.copyfileobj(f2, outfile)
  118. # Перемещаемся к адресу для пользовательских данных
  119. outfile.seek(APP_VER_ADDRESS)
  120. current_git_tag=find_tag("_WORKING")
  121. print(f"Текущий git tag: {current_git_tag}")
  122. # Если полученный тег меньше 32 байт, то дополняем его до 32 байт
  123. encoded_git_tag = current_git_tag.encode('utf-8')
  124. if len(encoded_git_tag) < 32:
  125. encoded_git_tag = encoded_git_tag.ljust(32, b'\x00')
  126. # Записываем тег в файл
  127. outfile.write(encoded_git_tag)
  128. # Перемещаемся к адресу для GOLDEN данных
  129. outfile.seek(GOLDEN_APP_VER_ADDRESS)
  130. golden_tag = find_tag("_GOLDEN")
  131. print(f"Текущий golden git tag: {golden_tag}")
  132. # Если полученный тег меньше 32 байт, то дополняем его до 32 байт
  133. encoded_golden_tag = golden_tag.encode('utf-8')
  134. if len(encoded_golden_tag) < 32:
  135. encoded_golden_tag = encoded_golden_tag.ljust(32, b'\x00')
  136. outfile.write(encoded_golden_tag)
  137. final_size = os.path.getsize(file_path_output)
  138. # Проверка итогового размера
  139. if final_size > file_size_output:
  140. os.remove(file_path_output) # Удаляем некорректный файл
  141. raise ValueError(f"Итоговый размер файла ({final_size} байт) превысил максимально допустимый ({file_size_output} байт)")
  142. print(f"Размер файла 1: {file_size_working} байт")
  143. print(f"Размер файла 2: {file_size_golden} байт")
  144. print(f"Итоговый размер: {final_size} байт")
  145. return final_size
  146. def merge_working_only():
  147. # Пути к файлам
  148. os.chdir(INITIAL_DIR)
  149. pwd = os.getcwd()
  150. file_path_working = os.path.join(INITIAL_DIR, "SB_TMSG44V1_WORKING_FPGA.bin")
  151. file_path_output = os.path.join(INITIAL_DIR, "SB_TMSG44V1_TEST_WORKING_FPGA.bin")
  152. # Размеры файлов
  153. file_size_working = os.path.getsize(file_path_working)
  154. # Размер выходного файла - 8 Мбит
  155. file_size_output = 0x1000000
  156. # Записываем первый файл
  157. with open(file_path_output,'wb') as outfile:
  158. with open(file_path_working, 'rb') as f1:
  159. shutil.copyfileobj(f1, outfile)
  160. # Перемещаемся к адресу для пользовательских данных
  161. outfile.seek(APP_VER_ADDRESS)
  162. current_git_tag=find_tag("_WORKING")
  163. print(f"Текущий git tag: {current_git_tag}")
  164. # Если полученный тег меньше 32 байт, то дополняем его до 32 байт
  165. encoded_git_tag = current_git_tag.encode('utf-8')
  166. if len(encoded_git_tag) < 32:
  167. encoded_git_tag = encoded_git_tag.ljust(32, b'\x00')
  168. # Записываем тег в файл
  169. outfile.write(encoded_git_tag)
  170. final_size = os.path.getsize(file_path_output)
  171. # Проверка итогового размера
  172. if final_size > file_size_output:
  173. os.remove(file_path_output) # Удаляем некорректный файл
  174. raise ValueError(f"Итоговый размер файла ({final_size} байт) превысил максимально допустимый ({file_size_output} байт)")
  175. print(f"Размер файла: {file_size_working} байт")
  176. print(f"Итоговый размер: {final_size} байт")
  177. return final_size
  178. def merge_golden_only():
  179. # Пути к файлам
  180. os.chdir(INITIAL_DIR)
  181. pwd = os.getcwd()
  182. file_path_golden = os.path.join(INITIAL_DIR, "SB_TMSG44V1_GOLD_FPGA.bin")
  183. file_path_output = os.path.join(INITIAL_DIR, "SB_TMSG44V1_TEST_GOLDEN_FPGA.bin")
  184. # Размеры файлов
  185. file_size_golden = os.path.getsize(file_path_golden)
  186. # Размер выходного файла - 8 Мбит
  187. file_size_output = 0x1000000
  188. # Записываем первый файл
  189. with open(file_path_output,'wb') as outfile:
  190. with open(file_path_golden, 'rb') as f2:
  191. shutil.copyfileobj(f2, outfile)
  192. # Перемещаемся к адресу для пользовательских данных
  193. outfile.seek(GOLDEN_APP_VERSION_SHIFTED)
  194. golden_tag = find_tag("_GOLDEN")
  195. print(f"Текущий golden git tag: {golden_tag}")
  196. # Если полученный тег меньше 32 байт, то дополняем его до 32 байт
  197. encoded_golden_tag = golden_tag.encode('utf-8')
  198. if len(encoded_golden_tag) < 32:
  199. encoded_golden_tag = encoded_golden_tag.ljust(32, b'\x00')
  200. outfile.write(encoded_golden_tag)
  201. final_size = os.path.getsize(file_path_output)
  202. # Проверка итогового размера
  203. if final_size > file_size_output:
  204. os.remove(file_path_output) # Удаляем некорректный файл
  205. raise ValueError(f"Итоговый размер файла ({final_size} байт) превысил максимально допустимый ({file_size_output} байт)")
  206. print(f"Размер файла: {file_size_golden} байт")
  207. print(f"Итоговый размер: {final_size} байт")
  208. return final_size
  209. def main():
  210. parser = argparse.ArgumentParser(description='Скрипт для объединения бинарных файлов прошивок')
  211. parser.add_argument('--mode', choices=['merge', 'working', 'golden'],
  212. help='Режим работы: merge - объединить Working и Golden, working - только Working и Working версию, golden - только Golden и Golden версию',
  213. required=False)
  214. args = parser.parse_args()
  215. # Если режим не задан через аргумент, запрашиваем у пользователя
  216. if args.mode is None:
  217. print("Выберите режим работы:")
  218. print("1. merge - объединить Working и Golden прошивки")
  219. print("2. working - объединить только Working прошивку с её версией")
  220. print("3. golden - объединить только Golden прошивку с её версией")
  221. choice = ""
  222. while choice not in ["1", "2", "3", "merge", "working", "golden"]:
  223. choice = input("Введите номер (1-3) или название режима: ").strip().lower()
  224. if choice == "1":
  225. choice = "merge"
  226. elif choice == "2":
  227. choice = "working"
  228. elif choice == "3":
  229. choice = "golden"
  230. mode = choice
  231. else:
  232. mode = args.mode
  233. if mode == 'merge':
  234. print("Объединение Working и Golden прошивок...")
  235. merge_bins()
  236. elif mode == 'working':
  237. print("Объединение только Working прошивки с её версией...")
  238. merge_working_only()
  239. elif mode == 'golden':
  240. print("Объединение только Golden прошивки с её версией...")
  241. merge_golden_only()
  242. if __name__ == '__main__':
  243. main()