Files
Balsam_167/Bin/StartupWait3s/rebuild.py
Andrey 1e911e5250 Обновить логгер УМП и исправить запуск UART и EEPROM
Перейти на компактные 12-словные записи v4 и сохранять 10 процентов банка после отключения. Добавить трёхсекундное ожидание роста ЗПТ и настраиваемый лимит пусков. Явно инициализировать состояние UART и гарантировать публикацию параметров EEPROM перед запуском Timer2. Сохранить воспроизводимые сборки, регрессионные проверки, документацию и обновлённые результаты сборки; исключить временные артефакты.
2026-10-12 12:25:41 +03:00

42 lines
7.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from pathlib import Path # Формирует абсолютные пути сборки и установленных инструментов TI.
import subprocess # Выполняет компиляцию и проверку без shell-подстановок.
import json # Читает фактический идентификатор текущей сборки из её паспорта.
import sys # Использует текущий Python для подготовки паспорта и образа.
root = Path.cwd().resolve() # Фиксирует разрешённый корень проекта.
out = root / 'Bin/StartupWait3s' # Изолирует результаты исправленного пуска от прежних прошивок.
obj = out / 'obj' # Хранит объекты полной текущей пересборки.
gen = out / 'generated' # Хранит паспорт текущих исходников.
for directory in (out, obj, gen): # Создаёт только подкаталоги этой сборки.
directory.mkdir(parents=True, exist_ok=True) # Не удаляет старые файлы проекта.
ti = Path('C:/ti/ccs1230/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS') # Повторяет установленный компилятор CCS.
templates = root.parent / 'newProject/templates' # Использует штатную общую библиотеку проекта.
protocol = templates / 'c/set-protocol' # Задаёт интерфейсы и карту памяти УМП.
name = 'UKSSTMS320F28335_startup_3s' # Различает новую прошивку по смыслу исправления.
log = (out / 'build.log').open('w', encoding='utf-8') # Записывает диагностику в UTF-8.
def run(args): # Останавливает сборку при ошибке любого шага.
result = subprocess.run([str(arg) for arg in args], cwd=root, capture_output=True) # Передаёт параметры инструменту напрямую.
output = (result.stdout + result.stderr).decode('utf-8', errors='replace') # Декодирует диагностический вывод.
log.write(output); log.flush() # Сохраняет текущий результат до следующего шага.
if result.returncode: # Запрещает формирование готового BIN после ошибки.
print(output); raise SystemExit(result.returncode) # Показывает причину незавершённой сборки.
return output # Возвращает отчёт успешно выполненного шага.
run([sys.executable, root / 'UKSSTMS320F28335/prepare_identity.py', '--project', root / 'UKSSTMS320F28335', '--templates', templates, '--output', gen]) # Обновляет паспорт перед полной компиляцией.
includes = [root / 'UKSSTMS320F28335', root / 'Source/Internal/Include', root / 'Source/External/v120/DSP2833x_headers/include', root / 'Source/External/v120/DSP2833x_common/include', protocol, protocol / 'ports/tms320f28335', templates / 'c/firmware-info/include', gen, ti / 'include'] # Повторяет каталоги CCS с локальным паспортом сборки.
flags = ['-v28', '-ml', '-mt', '--float_support=fpu32', '-O2', '--opt_for_speed=0', '--define=_DEBUG', '--define=LARGE_MODEL', '-g', '--diag_warning=225', '--display_error_number', '--gen_func_subsections=on', '--abi=coffabi'] # Сохраняет ABI, FPU и существующую оптимизацию размера проекта.
flags += ['--include_path=' + str(path) for path in includes] # Передаёт каждый каталог отдельным аргументом.
common = root / 'Source/External/v120/DSP2833x_common/source' # Задаёт уже используемый комплект TI.
external = ['DSP2833x_ADC_cal.asm', 'DSP2833x_Adc.c', 'DSP2833x_CpuTimers.c', 'DSP2833x_PieCtrl.c', 'DSP2833x_SWPrioritizedDefaultIsr.c', 'DSP2833x_SWPrioritizedPieVect.c', 'DSP2833x_SysCtrl.c', 'DSP2833x_Xintf.c', 'DSP2833x_usDelay.asm'] # Повторяет штатный список внешних исходников.
sources = [common / item for item in external] + [root / 'Source/External/v120/DSP2833x_headers/source/DSP2833x_GlobalVariableDefs.c'] + sorted((root / 'Source/Internal').glob('*.c')) # Пересобирает все модули после окончательной правки.
for source in sources: # Последовательно компилирует каждый модуль.
run([ti / 'bin/cl2000.exe', *flags, '--obj_directory=' + str(obj), source]) # Проверяет настоящий C28x-код и создаёт новый объект.
objects = [obj / (source.stem + '.obj') for source in sources] # Использует только объекты завершённой текущей компиляции.
run([ti / 'bin/cl2000.exe', '-v28', '-ml', '-mt', '--float_support=fpu32', '--abi=coffabi', '-z', '--map_file=' + str(out / (name + '.map')), '--stack_size=0x3f0', '--warn_sections', '-i' + str(ti / 'lib'), '-i' + str(root), '-i' + str(protocol), '-i' + str(ti / 'include'), '--reread_libs', '--display_error_number', '--entry_point=_c_int00', '--rom_model', '--output_file=' + str(out / (name + '.out')), root / 'F28335.cmd', root / 'Source/External/v120/DSP2833x_headers/cmd/DSP2833x_Headers_nonBIOS.cmd', *objects, root / 'Libraries/rts2800_fpu32.lib', '-lrts2800_fpu32.lib', '-llibc.a']) # Линкует со штатной картой памяти и библиотеками времени выполнения.
run([ti / 'bin/hex2000.exe', '--diag_wrap=off', '--boot', '--sci8', '--binary', '-o', out / (name + '.candidate'), out / (name + '.out')]) # Создаёт кандидат загрузочного образа для обязательной проверки размера.
print(run([sys.executable, root / 'tests/gas167/check_image.py', out / (name + '.candidate'), '--eeprom', 'AT25256B']).strip()) # Проверяет EEPROM, RAM-блоки и точку входа до выдачи прошивки.
print(run([sys.executable, templates / 'c/firmware-info/tools/c2000_postbuild.py', '--compiler', ti, '--build-dir', out, '--artifact', name, '--metadata', gen / 'firmware_identity.json', '--output', out]).strip()) # Создаёт штатный BIN, манифест и SHA-256 без экспорта в другие проекты.
bin_path = out / (name + '_' + json.loads((gen / 'firmware_identity.json').read_text(encoding='utf-8'))['build_id'] + '.bin') # Выбирает именно текущую сборку, даже если в каталоге остаются прежние BIN.
print(run([sys.executable, root / 'tests/gas167/check_image.py', bin_path, '--eeprom', 'AT25256B']).strip()) # Повторяет проверку на самом выдаваемом BIN после штатной упаковки.
assert bin_path.read_bytes() == (out / (name + '.candidate')).read_bytes() # Подтверждает совпадение проверенного кандидата и итоговой прошивки.
log.close() # Завершает полный лог успешно проверенной сборки.
print('READY:', bin_path) # Указывает пользователю точный готовый результат.