Skip to content

Safety Configuration

mcjtag is designed for use alongside safety-critical firmware — avionics, medical devices, automotive. It ships with conservative defaults that prevent accidental damage to your target. Every safety mechanism is configurable, because the right level of protection depends on what you are doing.

By default, write_memory() only allows writes to SRAM (0x20000000-0x20100000). Writes to any other address are rejected with an error before reaching the target.

This prevents:

  • Accidental flash corruption — writing to 0x08000000+ would brick the device
  • Unexpected peripheral behavior — writing to 0x40000000+ could reconfigure hardware (toggle GPIOs, change clock trees, disable interrupts)
  • System register writes — writing to 0xE0000000+ could lock out the debugger or alter the MPU/NVIC configuration

Configure with the MCJTAG_SAFE_WRITE_RANGES environment variable:

Terminal window
# Default: SRAM only
MCJTAG_SAFE_WRITE_RANGES="0x20000000-0x20100000"
# Add CCM RAM (STM32F4 has core-coupled memory at 0x10000000)
MCJTAG_SAFE_WRITE_RANGES="0x20000000-0x20020000,0x10000000-0x10010000"
# Allow peripheral writes too (for register configuration)
MCJTAG_SAFE_WRITE_RANGES="0x20000000-0x20020000,0x40000000-0x50000000"
# Unrestricted — you know what you are doing
MCJTAG_SAFE_WRITE_RANGES="none"

The format is start-end pairs in hex, comma-separated. Each range is inclusive of start and exclusive of end. The write must fall entirely within at least one range.

Setting the value to none (case-insensitive) disables the check entirely.

raw_command() provides direct access to OpenOCD’s TCL interface, but blocks commands that have dedicated, safer tools:

Blocked patternReasonUse instead
flash write_image, flash erase, flash protect, flash fillFlash modificationflash_program() — validates files before writing
mww, mwh, mwb, write_memoryMemory writeswrite_memory() — checks safe write ranges
resetTarget resettarget_control("reset_halt") or target_control("reset_run")
shutdown, exitTerminates OpenOCDdisconnect() — cleanly closes the session
regRegister writeswrite_register()
eval, subst, uplevelTCL metaprogrammingBlocks patterns that could bypass the deny-list

Override with:

Terminal window
MCJTAG_ALLOW_RAW=true

This disables the entire deny-list. All OpenOCD TCL commands are passed through without filtering.

Important caveat: The deny-list is best-effort pattern matching against the command string. It is not a sandbox. TCL metaprogramming (string concatenation, variable expansion) could theoretically construct a blocked command at runtime. The deny-list is a safety net for accidental invocations, not a security boundary.

flash_program() validates the firmware image before writing:

CheckBehavior
File existenceRejects if the path does not exist
File extensionAccepts .bin, .hex, .elf, .ihex, .srec, .s19 only
File sizeMust be non-zero and under 16 MB
Empty fileRejects zero-byte files

Progress is reported through three phases — erase, write, and verify — so the LLM (and you) can track what is happening.

There is no environment variable to disable these checks. If you need to program a file that does not meet these criteria, use raw_command() with MCJTAG_ALLOW_RAW=true.

All tool inputs are validated before reaching OpenOCD:

InputValidation
Hex addressesMust parse as valid hex. Negative values rejected. Accepts with or without 0x prefix.
AlignmentWarns on unaligned reads (may fault on Cortex-M0). Rejects unaligned writes.
Value rangesValues must fit in the specified width (8-bit max 0xFF, 16-bit max 0xFFFF, 32-bit max 0xFFFFFFFF).
Read countMaximum 4096 elements per read_memory() call.
Search rangeMaximum 1 MB per search_memory() call (configurable via MCJTAG_MAX_SEARCH_RANGE).
SVD filesMust have .svd extension and be under 50 MB.
Resume/step addressesMust be 2-byte aligned (ARM Thumb requirement).
Use caseWrite rangesRaw commandNotes
Learning / exploringDefault (SRAM)Deny-list onSafest. Cannot accidentally damage the target.
Firmware developmentSRAM + your chip’s RAMDeny-list onNormal daily use. Expand the SRAM range to match your chip.
Peripheral bring-upSRAM + peripheral regionDeny-list onAllows writing to GPIO, UART, SPI registers. Be careful with clock and power config.
Automated testingChip-specific rangesDeny-list onTailor ranges to exactly what your test suite needs.
Power user / automationnoneMCJTAG_ALLOW_RAW=trueFull access. No guardrails. You own the consequences.
VariableDefaultDescription
MCJTAG_SAFE_WRITE_RANGES0x20000000-0x20100000Comma-separated hex ranges for write_memory(). Set to none for unrestricted.
MCJTAG_ALLOW_RAWfalseSet to true, 1, or yes to disable the raw command deny-list.
MCJTAG_MAX_SEARCH_RANGE1048576 (1 MB)Maximum byte range for search_memory(). Integer.
OPENOCD_CONFIG(none)OpenOCD config file path. If set, mcjtag auto-spawns OpenOCD on startup.
OPENOCD_HOSTlocalhostOpenOCD TCL RPC hostname (when not auto-spawning).
OPENOCD_PORT6666OpenOCD TCL RPC port.
OPENOCD_SVD(none)SVD file path. Auto-loaded on startup if a connection is established.