mp.backend — 24 functions
All blocking operations return ok: bool, err: string.
local ok, err = mp.backend.connect()
if not ok then mp.log.error(err); return end
Standard operations
| Function | Returns | Description |
|---|---|---|
connect() | ok, err | Connect to target with current config |
read() | ok, err | Read target memory into buffer |
write() | ok, err | Write buffer to target (with blank check) |
verify() | ok, err | Verify target matches buffer |
erase() | ok, err | Erase target (mass erase when available) |
flash() | ok, err | Full cycle: connect → erase → write → verify |
connect_timeout(ms) | ok, err | connect() with explicit timeout in ms |
read_timeout(ms) | ok, err | read() with explicit timeout in ms |
write_timeout(ms) | ok, err | write() with explicit timeout in ms |
Extended operations (TGSN only as of writing)
| Function | Returns | Description |
|---|---|---|
write_no_blank() | ok, err | Write without blank check (relies on NOR semantics) |
blank_check() | ok, err | Standalone blank check; ok=false names the first non-blank block |
erase_blocks() | ok, err | Per-block erase, never mass erase |
read_checksums() | blocks|nil, err | Chip-side per-block / per-subblock checksums (see below) |
Backends that don't implement these return an explicit
"Not Supported: …" error instead of hanging.
write_no_blank()
Writes the buffer to the target, bypassing the host-side blank check.
Useful when you want several sequential writes into the same block
without erasing in between. Relies on NOR-flash semantics (bits can
only flip 1→0). Trying to flip a bit back from 0 to 1 will silently
fail at the cell — a subsequent verify() will reveal it.
blank_check()
Returns ok=true if every block in the region is 0xFF, otherwise
ok=false with err naming the first non-blank block.
erase_blocks()
Always performs block-level erase via the erase-area command,
never mass erase. For families where the standard erase() uses
mass erase for speed (e.g. NEC 78K0/Kx2), erase_blocks() guarantees
that only the current region's memory is erased and the rest of
the flash stays intact.
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, region is blank
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 contains "Block N not blanked"
mp.memory.write_at("Code Flash", 0x400, {0x00})
ok, err = mp.backend.write_no_blank() -- 0xFF → 0x00 is a valid 1→0 transition
write_no_blank() bypasses a safety check. Writing a 1 on top
of a 0 technically succeeds but the cell stays at 0 — a later
verify() or read() will expose the divergence. Don't use this
unless you understand NOR semantics.
read_checksums() — chip-side checksums
Returns checksums computed by the chip itself for every block
and sub-block of every region. Same data the Renesas Checksum
dialog shows, but as structured values for scripts. Unlike
mp.checksum.* (host-side buffer), these come from
the flash controller — and for ECC-enabled families they include
the contribution of hidden ECC bytes that are invisible to 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
Each entry is a table: {block_n, base_checksum, sub_checksums[]}.
Per-segment operations
A segment is an arbitrary aligned range [addr, addr+size) over the
target's absolute address space — not a region. On a multi-region
target (Flash + EEPROM/data) the backend resolves which region the range
lands in. All four return (ok, err).
Other backends (ST-Link/SWD, USBDM, TGSN) do not implement per-segment ops yet
and return a "Not Supported: …" error.
| Function | Returns | Description |
|---|---|---|
read_segment(addr, size) | ok, err | Read ONE absolute range DEVICE → buffer (non-destructive) |
verify_segment(addr, size) | ok, err | Compare ONE absolute range DEVICE vs buffer |
write_segment(addr, size) | ok, err | Write buffer slice for ONE absolute range → DEVICE |
erase_segment(addr, size) | ok, err | Erase the sectors covering ONE absolute range |
local ok, err = mp.backend.read_segment(0x100000, 0x1000) -- chip → buffer
mp.app.allow_hw_writes(true)
ok, err = mp.backend.write_segment(0x100000, 0x1000) -- buffer → chip
ok, err = mp.backend.verify_segment(0x100000, 0x1000) -- chip vs buffer
- Addresses are absolute — these take the device address, not a region offset; the backend validates bounds/alignment and resolves the region.
- Alignment contract (ESP):
read/verifyare word-aligned to 4;write/eraseare sector-aligned to 4096 — ESP flash write erases the sectors it touches, so a sub-sector write would clobber neighbours. A misaligned or out-of-map range returns(false, …)before any device IO. write_segment/erase_segmenttake their data from the live buffer slice (populate it viamp.file.load/mp.memory.*), honor themp.app.allow_hw_writesgate, anderase_segmentalso pops the GUI confirmation modal.- ESP UI-tab caveat: the ESP backend leaves the UI hex tab empty until a
device read —
mp.memory.get_regions()is{}right after connect. The segment ops still work (absolute-addressed), but callread_segmentfirst if you then wantmp.memory.*/get_region_info().
See the bundled scripts/examples/esp_segment_*.lua — start with
esp_segment_example.lua (annotated end-to-end), then read, write_verify,
roundtrip, validation, app_flash.
State and info
| Function | Returns | Description |
|---|---|---|
is_connected() | bool | Current connection status |
get_target_info() | table | {name, additional[]} |
get_programmer_info() | table | {name, serial, connected, type} for the currently selected programmer |
get_programmers() | table | Array of all programmers seen by a probe-scan. serial may be empty for devices that don't expose it over probe |
get_progress() | table | {progress, speed, title, msg} — last snapshot |
Power
| Function | Returns | Description |
|---|---|---|
power_on() | void | Set VDD = 3.3 V |
power_on_5v() | void | Set VDD = 5 V |
power_off() | void | VDD off |
power_toggle() | void | Toggle power output |
set_power(v) | void | "3v3" | "5v" | "off" |