mp.backend — 24 функции
Все блокирующие операции возвращают ok: bool, err: string.
local ok, err = mp.backend.connect()
if not ok then mp.log.error(err); return end
Стандартные операции
| Функция | Возврат | Описание |
|---|---|---|
connect() | ok, err | Подключение к таргету с текущим конфигом |
read() | ok, err | Чтение памяти таргета в буфер |
write() | ok, err | Запись буфера в таргет (с blank check) |
verify() | ok, err | Верификация таргета против буфера |
erase() | ok, err | Стирание таргета (mass erase где доступно) |
flash() | ok, err | Полный цикл: connect → erase → write → verify |
connect_timeout(ms) | ok, err | connect() с явным таймаутом |
read_timeout(ms) | ok, err | read() с явным таймаутом |
write_timeout(ms) | ok, err | write() с явным таймаутом |
Расширенные операции (на момент написания — только TGSN)
| Функция | Возврат | Описание |
|---|---|---|
write_no_blank() | ok, err | Запись без blank check (опирается на NOR-семантику) |
blank_check() | ok, err | Отдельный blank check; ok=false называет первый не-пустой блок |
erase_blocks() | ok, err | Поблочное стирание, никогда не mass |
read_checksums() | blocks|nil, err | Чип-чексуммы по блокам / субблокам (см. ниже) |
Бэкенды без поддержки этих операций возвращают явную ошибку
"Not Supported: …", не зависают.
write_no_blank()
Пишет буфер в таргет минуя хостовый blank check. Полезно когда
нужно несколько последовательных записей в один блок без erase
между ними. Опирается на NOR-семантику: биты можно менять только
1→0. Попытка вернуть бит 0→1 на ячейке провалится молча — последующий
verify() это покажет.
blank_check()
Возвращает ok=true если все блоки региона пусты (0xFF),
иначе ok=false, err называет первый не-пустой блок.
erase_blocks()
Всегда поблочное стирание через команду стирания области, никогда
не mass erase. Для семейств где стандартный erase() использует
mass erase для скорости (например NEC 78K0/Kx2), erase_blocks()
гарантирует, что стирается только память текущего региона —
остальной flash остаётся нетронутым.
local ok, err = mp.backend.connect() if not ok then mp.log.error(err); return end
ok, err = mp.backend.erase_blocks() if not ok then mp.log.error(err); return end
ok, err = mp.backend.blank_check() -- ok=true, регион пуст
ok, err = mp.backend.write_no_blank() if not ok then mp.log.error(err); return end
ok, err = mp.backend.blank_check() -- ok=false, err: "Block N not blanked"
mp.memory.write_at("Code Flash", 0x400, {0x00})
ok, err = mp.backend.write_no_blank() -- 0xFF → 0x00 — валидный 1→0 переход
write_no_blank() обходит защитную проверку. Запись 1 поверх 0
технически выполнится, но реальное состояние flash останется 0 —
последующий verify() или read() это покажет. Не используйте,
если не уверены в семантике NOR.
read_checksums() — чип-чексуммы
Возвращает чексуммы, рассчитанные самим чипом для каждого блока
и субблока всех регионов. Те же значения, что показывает диалог
Renesas Checksum, но в виде структурированных данных. В отличие
от mp.checksum.* (хост-сторона буфера), здесь данные
приходят прямо от flash-контроллера — и для семейств с ECC включают
вклад скрытых ECC-байт, недоступных через read().
local blocks, err = mp.backend.read_checksums()
if not blocks then mp.log.error(err); return end
for _, b in ipairs(blocks) do
mp.log.infof("block %d base=0x%04X subs=%04X %04X %04X %04X",
b.block_n, b.base_checksum,
b.sub_checksums[1], b.sub_checksums[2],
b.sub_checksums[3], b.sub_checksums[4])
end
Каждый элемент — таблица {block_n, base_checksum, sub_checksums[]}.
Операции над сегментом
Сегмент — произвольный выровненный диапазон [addr, addr+size) в
абсолютном адресном пространстве таргета, не регион. На таргете с
несколькими регионами (Flash + EEPROM/data) бэкенд сам определяет, в какой
регион попадает диапазон. Все четыре возвращают (ok, err).
Остальные бэкенды (ST-Link/SWD, USBDM, TGSN) пока не реализуют посегментные
операции и возвращают ошибку "Not Supported: …".
| Функция | Возврат | Описание |
|---|---|---|
read_segment(addr, size) | ok, err | Чтение ОДНОГО абс. диапазона ТАРГЕТ → буфер (не разрушающая) |
verify_segment(addr, size) | ok, err | Сравнение ОДНОГО абс. диапазона ТАРГЕТ против буфера |
write_segment(addr, size) | ok, err | Запись среза буфера для ОДНОГО абс. диапазона → ТАРГЕТ |
erase_segment(addr, size) | ok, err | Стирание секторов, покрывающих ОДИН абс. диапазон |
local ok, err = mp.backend.read_segment(0x100000, 0x1000) -- чип → буфер
mp.app.allow_hw_writes(true)
ok, err = mp.backend.write_segment(0x100000, 0x1000) -- буфер → чип
ok, err = mp.backend.verify_segment(0x100000, 0x1000) -- чип против буфера
- Адреса абсолютные — принимается адрес устройства, а не смещение в регионе; бэкенд проверяет границы/выравнивание и резолвит регион.
- Контракт выравнивания (ESP):
read/verify— по слову (4);write/erase— по сектору (4096): запись flash на ESP стирает затрагиваемые секторы, поэтому запись меньше сектор а затёрла бы соседние байты. Невыровненный или выходящий за карту диапазон возвращает(false, …)до любого обмена с устройством. write_segment/erase_segmentберут данные из живого среза буфера (заполните черезmp.file.load/mp.memory.*), учитывают гейтmp.app.allow_hw_writes, аerase_segmentещё и вызывает модальное GUI-подтверждение.- Особенность ESP: ESP-бэкенд оставляет UI-вкладку пустой до чтения с
устройства — сразу после connect
mp.memory.get_regions()возвращает{}. Операции над сегментом всё равно работают (адреса абсолютные), но вызовитеread_segmentпервым, если затем нужныmp.memory.*/get_region_info().
См. примеры scripts/examples/esp_segment_*.lua — начните с
esp_segment_example.lua (аннотированный сквозной), затем read,
write_verify, roundtrip, validation, app_flash.