Files
Andrey 6ecf057a86 feat(c2000-linker): Добавить помощник настройки линкера C2000
Добавить генерацию карт COFF для TMS320F28335 и TMS320F2812, проверку CMD/MAP и русскую инструкцию.

Проверки: 14 тестов, включая четыре реальные линковки TI для RAM и Flash.
2026-10-19 16:33:40 +03:00
..

Помощник linker для TMS320F28335 и TMS320F2812

Переносимая утилита Python 3.10+ из стандартной библиотеки. Она создаёт стартовые карты COFF для RAM и внутренней Flash, объясняет память и проверяет поддерживаемую часть текстовых CMD/MAP. Работает офлайн без SDK, платы и программатора. EABI сейчас не поддерживается.

Все адреса, длины MEMORY, размеры секций и copy-symbols выражены в 16-битных словах C28x. Например, 0x1000 слов занимает 8192 физических октета. PAGE 0 и PAGE 1 — логические страницы линкера; одинаковые адреса RAM/Flash на них не означают независимую память. Высокое зеркало L0–L3 F28335 также не даёт дополнительную RAM. H0 F2812 — самостоятельный блок.

Быстрый запуск

Команды приведены относительно корня общего templates:

python tools/c2000-linker/c2000_linker.py profiles # Показывает поддерживаемые устройства, boot modes и ABI.
python tools/c2000-linker/c2000_linker.py explain --device 2812 # Объясняет адреса RAM, Flash, BEGIN, CSM и OTP в hex.
python tools/c2000-linker/c2000_linker.py generate --device 28335 --boot flash --output board_flash.cmd # Создаёт стартовый COFF CMD для внутренней Flash.
python tools/c2000-linker/c2000_linker.py generate --device 2812 --boot ram --output board_ram.cmd # Создаёт отдельную RAM-карту F2812 с входом в H0.
python tools/c2000-linker/c2000_linker.py inspect board_flash.cmd --device 28335 --boot flash # Показывает регионы и потенциальные назначения до линковки.
python tools/c2000-linker/c2000_linker.py validate board_flash.cmd --device 28335 --boot flash --map build/board.map --json # Сверяет фактические адреса и размеры MAP той же сборки.

generate атомарно отказывается заменять существующий файл. Для осознанной замены используйте --force. Утилита не создаёт родительские каталоги молча, не переписывает исходный CMD при проверке и не меняет проект CCS.

Подключение карты к проекту

  1. Выберите ровно нужный MCU, ram/flash и COFF. Сгенерируйте новый CMD и добавьте его в проект вместо прежней карты памяти. Периферийный DSP2833x_Headers_nonBIOS.cmd либо соответствующий F281x headers CMD подключается отдельно из TI SDK: генератор не копирует регистры периферии.
  2. Добавьте официальный CodeStartBranch.asm выбранного семейства, чтобы codestart содержал длинную ветвь к C runtime. Минимальная ASM-ветвь тестов проверяет только синтаксис/адреса линкера и не заменяет штатный стартовый код TI.
  3. Согласуйте ABI, RTS-библиотеку и параметры всех объектов. Общий проверенный минимум — --abi=coffabi -v28 --float_support=softlib. F2812 не имеет FPU32. Линковке обычно нужны --rom_model, --stack_size=0x100, --heap_size=0x40 и вывод --map_file=.... Размеры стека/heap подбираются для приложения; приведённые значения служат примером. Не превышайте 1024 слова M1 выделенного стеку шаблона.
  4. Для Flash скопируйте ramfuncs из LOAD во Flash в RUN в RAM до первого вызова функции из этой секции, в частности InitFlash. Проверьте порядок внутри своего InitSysCtrl. Генератор объединяет входные секции ramfuncs и .TI.ramfunc в один выходной блок и создаёт COFF-символы _RamfuncsLoadStart, _RamfuncsLoadEnd, _RamfuncsLoadSize, _RamfuncsRunStart.
  5. Выполните настоящую TI линковку и проверьте её MAP. После добавления реальных модулей места может не хватить даже при корректной начальной карте; утилита не выбирает автоматически split-секции, trampolines или overlay.

Пример использования linker-символов из C COFF:

#include <string.h> /* Объявляет memcpy; на C28x один char соответствует адресуемому 16-битному слову. */
extern unsigned int RamfuncsLoadStart, RamfuncsLoadSize, RamfuncsRunStart; /* C-имена соответствуют linker-именам с ведущим подчёркиванием COFF. */
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); /* Адрес символа LoadSize кодирует число копируемых слов; значение по этому адресу не читается. */

Эту операцию помещают в стартовую функцию, не в глобальную область C. Допустим и исторический контракт LOAD_END: размер вычисляется по разности адресов LoadEnd и LoadStart. Проверка принимает LOAD_SIZE или LOAD_END вместе с обоими начальными адресами.

Flash API, обработчики во время erase/program, частоты/тайминги Flash и внешняя SRAM зависят от приложения и платы. Генератор их не добавляет и не запускает erase/program. Области CSM/OTP не получают загружаемых секций и паролей.

Что именно проверяется

Поддерживаются буквальные десятичные/hex origin/length (org/len), один регион на строку, PAGE 0/1 и обычные SECTIONS: > REGION, LOAD = REGION, RUN = REGION, PAGE, TYPE, LOAD_START/END/SIZE, RUN_START/END/SIZE, выбор входных *(ramfuncs)/*(.TI.ramfunc).

Находятся физические пересечения RAM/Flash между PAGE и зеркалами F28335, выход за известную встроенную память, поглощение BEGIN/CSM/OTP/reset/ADC_cal общим регионом, загрузка обычных секций в резервы/BootROM, ошибочный Flash codestart, потеря постоянной Flash LOAD-копии обычных инициализированных секций и отсутствие контракта копирования RAM-функций. Первые 0x50 слов M0 консервативно оставлены загрузчику; при RAM boot F28335 первые два слова выделены BEGIN.

С --map проверяются текстовые таблицы TI MEMORY CONFIGURATION/SECTION ALLOCATION MAP, соответствие MEMORY текущему CMD, непустые фактические LOAD/RUN, размещение секций внутри регионов, пересечения и значения copy-symbols. Поддержан перенос имени секции и отметка * в MAP TI CGT 22.6. Загружаемый Flash codestart должен реально занимать два слова. Без MAP анализируются потенциальные назначения, а фактические размеры неизвестны.

Коды завершения:

Код Значение
0 В поддерживаемой части не найдено нарушений. Это не проверка стартового C/ASM-кода или аппаратуры.
1 Найдено нарушение карты либо не удалось прочитать/создать файл.
2 Проверка неполная: неподдерживаемый синтаксис/память/MAP; также обычная ошибка CLI argparse.

При наличии и ошибок, и неполных частей возвращается 1; все причины остаются в отчёте. JSON содержит scope, issues, regions, sections и фактические allocations.

#include, #if, макросы, выражения в MEMORY, GROUP/UNION, отдельные LOAD_PAGE/RUN_PAGE, split >>, внешние регионы и чужие MAP-форматы явно дают неполную проверку. TI linker с препроцессором остаётся окончательным инструментом. Передавайте предварительно обработанный числовой CMD, если нужно убрать влияние include/условных ветвей; помощник не исполняет их сам.

Исходный CMD проекта может перечислять внутреннюю Flash, CSM и codestart, хотя RAM COFF/SCI8 загружает только RAM, а перечисленные выходные секции пусты. Поэтому без MAP предупреждение о потенциальной загрузке в CSM не доказывает запись этих слов. С MAP пустые CSM/codestart-секции не считаются фактической записью. RAM COFF может запускаться JTAG или boot-таблицей по её entry point без аппаратного Boot-to-SARAM codestart; отсутствие такой секции не считается ошибкой RAM-профиля. Сгенерированный RAM-шаблон всё же предоставляет стандартный BEGIN, подтверждённый тестом TI.

Внешняя SPI EEPROM хранит SCI8 boot-таблицу и не расширяет RAM процессора. Переход с AT25256B на M95M02 увеличивает ёмкость носителя, но не устраняет переполнение RAM при укладке .text, .cinit, .ebss. Она не является CPU-addressable MEMORY-регионом.

Проверки

python tools/c2000-linker/tests/run_tests.py -v # Выполняет переносимые stdlib-регрессии без установленного SDK.
python tools/c2000-linker/tests/run_tests.py --ti C:/ti/ccs1230/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS -v # Дополнительно компилирует и линкует4 настоящих COFF-профиля, без платы.

Тесты проверяют обе модели и оба режима, пересечения разных PAGE и зеркала, резерв CSM/OTP, copy-symbols и альтернативный LOAD_END, отказ перезаписи и явную неполноту неподдерживаемого входа. TI smoke создаёт .text, .econst, .ebss, обе входные RAM-секции и codestart, затем анализирует настоящий MAP TI. Временные C/ASM/OBJ/OUT/MAP удаляются вместе с собственным временным каталогом. Сохранённый результат выполненной проверки — TEST_RESULTS.md.

Первичные источники и происхождение адресов

Числа дополнительно сопоставлены с локальными официальными TI примерами C2000Ware_5_03_00_00/device_support/f2833x/common/cmd/F28335.cmd, 28335_RAM_lnk.cmd и controlSUITE/libs/math/IQmath/v160/examples/cmd/2812_IQmath_lnk.cmd. Генератор содержит собственную компактную карту на основе документированных аппаратных фактов; не копирует целиком распространяемые TI linker-файлы и не требует этих абсолютных путей у пользователя.