Files
templates/c/parallel-nand/docs/MEMORY_GAS.md

9.9 KiB
Raw Blame History

Работа с parallel NAND через GAS

Архитектура

Внешняя NAND значительно больше общего адресного пространства GAS. Например, MT29F1G08ABADA содержит 128 МиБ main area, а GAS имеет только 65536 16-битных регистров. Поэтому NAND представлена не линейным диапазоном, а банковым окном одной физической страницы.

SETGUI
  │ GUI protocol v1: READ_REGISTERS / WRITE_REGISTERS
  ▼
карта GAS 0x0000..0xFFFF
  │ 0xE000: управление, 0xE100: main, 0xE500: OOB
  ▼
parallel_nand_gas
  ▼
общее ядро parallel_nand
  ├─ TMS320F2812: XINTF
  ├─ STM32F407VE: FSMC
  └─ STM32G474CE: GPIO

GUI работает одинаково со всеми МК. Тип процессора влияет только на выбранный файл из ports/.

Встроенный проект должен направлять весь диапазон 0xE000..0xE51F в parallel_nand_gas_read() и parallel_nand_gas_write(). Их аргументы имеют тип unsigned int: на C28x это нативное 16-битное слово, а на ARM функции явно оставляют только младшие 16 бит. Так карта и wire-формат совпадают без предположения, что C char всегда восьмибитный.

Для STM32, использующего карту pcan_gas, готов адаптер:

#include "parallel_nand_pcan_gas.h"

static pcan_gas_region_t nand_region;
parallel_nand_pcan_gas_region_init(&nand_region, &nand_gas);

Для TMS320F2812 переносимый обработчик вызывается прямо из существующего GAS диспетчера:

if (address >= nand_gas.base &&
    address < nand_gas.base + PNAND_GAS_REGION_REGS) {
    return parallel_nand_gas_read(&nand_gas, address, value);
}

Если тип результата диспетчера отличается, статусы PNAND_GAS_OK, PNAND_GAS_NO_REG, PNAND_GAS_READ_ONLY и PNAND_GAS_REJECTED преобразуются в его локальные статусы так же, как это сделано в parallel_nand_pcan_gas.c.

Транспорт до GUI

Карта GAS не привязана к физическому каналу. Рекомендуемый путь для полного дампа — используемые SETGUI сообщения WRITE_REGISTERS (0x0A) и READ_REGISTERS (0x09): они позволяют передавать крупные блоки поверх USB, UART, RS-485 или Ethernet. Адаптер pcan_gas нужен, когда теми же регистрами обмениваются по classic CAN; там один кадр несёт только четыре регистра, и полный 128-MiB дамп будет значительно медленнее.

Устройство не должно собирать весь дамп в RAM. Буферизуется только одна страница. Из-за переносимости на C28x каждый octet хранится в unsigned short, поэтому статические буферы GAS занимают примерно 4,2 KiB RAM и на TMS, и на ARM.

Карта GAS

Базовый адрес по умолчанию — 0xE000. Его можно изменить при вызове parallel_nand_gas_init(); все смещения ниже останутся прежними.

Адрес Доступ Название Значение
E000 R SIGNATURE 0x4E44 (ND)
E001 R VERSION версия окна, сейчас 1
E002 R STATUS состояние операции
E003 R ERROR код PNAND_*, 0 = нет ошибки
E004 W COMMAND команда окна
E005 R/W PAGE_LO младшие 16 бит физической страницы
E006 R/W PAGE_HI старшие 16 бит физической страницы
E007 R PAGE_MAIN main bytes, для MT29 = 2048
E008 R PAGE_OOB OOB bytes, для MT29 = 64
E009 R PAGES_PER_BLOCK для MT29 = 64
E00A R BLOCKS для MT29 = 1024
E00B R MANUFACTURER_ID ожидается 0x2C
E00C R DEVICE_ID ожидается 0xF1
E00D R BAD_BLOCK 1 для физически плохого блока
E00E R GENERATION_LO счётчик загруженных страниц, low
E00F R GENERATION_HI счётчик загруженных страниц, high
E100..E4FF R PAGE_DATA 1024 регистра main, два байта LE
E500..E51F R PAGE_OOB 32 регистра OOB, два байта LE

Между управляющими регистрами и окнами данных есть зарезервированные адреса. Чтение блока через них не выполняется: каждый запрос должен начинаться внутри существующего участка.

STATUS

Бит Маска Смысл
0 0x0001 READY
1 0x0002 BUSY
2 0x0004 PAGE_VALID
3 0x0008 BAD_BLOCK
15 0x8000 ERROR, подробность в E003

GUI читает окно данных только при READY=1, PAGE_VALID=1, ERROR=0.

COMMAND

Значение Команда Результат
1 RESET сброс NAND и ожидание Ready
2 READ_ID обновляет E00B/E00C
3 READ_PAGE загружает main/OOB выбранной страницы

Запись номера страницы и запуск — две отдельные операции. Сначала GUI пишет PAGE_LO/PAGE_HI, затем записывает READ_PAGE в COMMAND. Нельзя отправлять один блок, начинающийся с COMMAND: команда выполнилась бы до обновления номера страницы.

Последовательность полного дампа

  1. Прочитать E000..E00F, проверить подпись, версию и геометрию.
  2. Выполнить READ_ID; для микросхемы с фотографии проверить 2C F1.
  3. Рассчитать page_count = PAGES_PER_BLOCK * BLOCKS.
  4. Для каждой физической страницы от 0 до page_count - 1:
    • записать номер страницы в E005/E006;
    • записать 3 в E004;
    • опрашивать E002, пока не установлен READY;
    • проверить ERROR, BAD_BLOCK и изменение GENERATION;
    • прочитать E100..E4FF;
    • прочитать E500..E51F;
    • сразу дописать данные и метаданные в файлы.
  5. Не пропускать bad-блоки: иначе файл потеряет соответствие физическим страницам микросхемы.

GUI protocol v1 допускает payload до 512 байт. Ответ READ_REGISTERS содержит четырёхбайтовый заголовок диапазона, поэтому за один запрос следует читать не более 254 GAS-регистров. Страница main читается пятью запросами: четыре раза по 254 регистра и последний раз 8 регистров. OOB читается одним запросом на 32 регистра.

Возобновление

GUI хранит номер последней полностью записанной страницы. После разрыва связи он повторно проверяет подпись/ID/геометрию и продолжает со следующей страницы. Страница считается готовой только после записи main, OOB и записи её статуса в метаданные.

Рекомендуемые выходные файлы:

  • dump.bin — 2048 байт main каждой физической страницы;
  • dump.oob — 64 байта OOB каждой физической страницы;
  • dump.json — ID, геометрия, bad-блоки, ошибки и последняя готовая страница.

Для MT29F1G08ABADA размеры завершённого дампа: dump.bin = 134217728 байт, dump.oob = 4194304 байта.

ECC

Текущая версия шаблона отдаёт raw main/OOB и не заявляет исправление ошибок. Статус bad-блока определяется по первому байту OOB первых двух страниц блока. Перед использованием дампа как рабочего образа нужно добавить ECC-политику для точного чипа и формата OOB. Само окно GAS при этом менять не требуется: можно добавить новые флаги состояния в свободные биты STATUS.

PROGRAM/ERASE

Запись и стирание не включены намеренно. Они требуют отдельного разрешения, проверки ECC, защиты загрузочных блоков и двухфазного подтверждения через GAS. До добавления этих функций WP# удерживается активным аппаратным портом.