Перейти к основному содержимому

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, errconnect() с явным таймаутом
read_timeout(ms)ok, errread() с явным таймаутом
write_timeout(ms)ok, errwrite() с явным таймаутом

Расширенные операции (на момент написания — только 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).

В текущей версии — только бэкенд ESP

Остальные бэкенды (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.

Состояние и информация

ФункцияВозвратОписание
is_connected()boolТекущий статус подключения
get_target_info()table{name, additional[]}
get_programmer_info()table{name, serial, connected, type} для текущего выбранного программатора
get_programmers()tableМассив всех программаторов из probe-scan. serial может быть пуст для устройств, не отдающих SN на этапе probe
get_progress()table{progress, speed, title, msg} — последний снимок прогресса

Питание

ФункцияВозвратОписание
power_on()voidУстановить VDD = 3.3 В
power_on_5v()voidУстановить VDD = 5 В
power_off()voidVDD выкл
power_toggle()voidПереключить
set_power(v)void"3v3" | "5v" | "off"