Change Note 2026-03-31

lib/v3.1, debugging, testing, more tools.

lib/v3.1

  • Systematic support for Secure/Non-secure (S/NS) programs:
    • start-up, initialisation and configuration of programs and their resources;
    • securing and/or releasing of peripheral devices;
  • Objective: unified approach for “normal single-image” programs, as well as S/NS segregated ones.
  • This is very much work in progress, of which some has been made for the STM32U585, which serves a test-bed for concepts, testing, and revising and refining concepts.
  • However, the library structure for the other MCUs is yet unchanged from lib/v3.0, apart from the RP2350, for which first proof-of-concept changes have been made (always good to know if things work with two cores).
  • Related doc: S/NS Program Design.

Modules (lib/3.1, STM32U585)

Start-up

  • Check out Main.mod and directory startup to get an idea.
  • Check out test program Secure5 for how the concept is used for a S/NS two-image program.

Definitions, Module S/NS and Core Neutrality

  • Modules should be usable, without run-time testing for context to get and use the correct configurations, independently if used by S or NS programs, or one different cores.
  • For example, if an MCU uses address aliases for S and NS programs, the correct address should be “picked up” automatically. In the same vein, Secure VTOR or MSP registers should be used for S programs, or their Non-secure equivalents in NS programs. Programs on different cores should automatically use “their” registers on the Private Peripheral Bus.
  • lib/v3.1 has been restructured accordingly, for example:
    • m33/PPB.mod: definitions from the architecture reference manual, valid for all Cortex-M33 processors;
    • cfg-s/MCU.mod, cfg-ns/MCU.mod: for MCUs that use Secure and Non-secure address aliases;
    • cfg/DEV0.mod, cfg/DEV2.mod etc: MCU-specific configuration definitions for devices
  • Modules such as RuntimeErrors are revised as well: compare RuntimeError.Install in lib/v3.1 vs. lib/v3.0 vs. lib/v2.1.
  • However, I am not yet fully satisfied – things work, but I’d prefer a some more systematic approach, in particular regarding the cfg/DEVx modules, which are somewhat arbitrary for now. Ideally, we would have exactly one such configuration definition module per peripheral device, but this would result in an “explosion” of number of modules per program.
  • As said, work in progress. :)

Runtime Errors, Stacktraces

  • Runtime error/fault handling and stacktraces work for both S and NS programs (run Secure5 with some injected errors to test).
  • Stacktraces are now deterministic, based on a new tracing algorithm that calculates the size of the stack frames encountered, hence in lieu of scanning the whole stack we can walk the stack as if we had a frame pointer.
  • No more false positives.

GPIO

  • GPIO ports are now handled as devices, just like UARTs or timers.

Test and Example Programs

  • Secure5 uses the current concepts and state of lib/v3.1 to get a simple S/NS program set up, and rolling. Also used to test run-time error handling and deterministic stacktraces.
  • The other v3.1 programs for the STM32U585 are ported to make use the new lib/v3.1 structure.

Debugging

  • Debugging has been extended to support S/NS programs, including switching between Secure and Non-secure state, and stepping through the NSC veneers on the S/NS boundary.
  • The corresponding tools have been extended, among them:
    • gen-secure: now reads the linker .map file, processes multiple modules, walks type and constant dependencies, and generates a combined NSC.bin wth the veneer segments, NSC.alst (for veneer-level debugging), and all NS interface modules including dependency modules. Supports configuration files.
    • gen-rdb: new –rdb-dir path handling: the output directory is now relative to the current working directory (was relative to the .map file). New –nsc-dir option copies NSC.alst (from gen-secure) into the rdb directory for inclusion in the ELF debug data. Supports the S/NS build workflow where Secure and Non-secure rdb directories are separate.
    • make-elf: new –sym-prefix option prefixes all symbol names for S/NS dual-image debugging (e.g. S_Module_Proc, NS_Module_Proc). DWARF compilation directory (DW_AT_comp_dir) now derived from the –rdb-dir path, enabling source-level debugging of both S and NS images from a common parent directory. New symbol startup at the entry address (together with main, a C-thing which many debuggers expect).
  • Docs: Debugging Overview, Debugging How-to.
  • Support for SEGGER J-Link server has been dropped, in order to focus on the non-proprietary OpenOCD (scripts, manuals, guides). The J-Link probe can still be used with the OpenOCD GDB server.

Testing

  • Working with GDB for debugging had brought up the idea if GDB with OpenOCD could not be used for scripted testing of programs, with the basic concept of checking values at defined breakpoints.
  • As described in Testing Overview and Testing How-to, there is now such a basic testing facility available, which can be used interactively or in batch-mode.
  • Test Spec Grammar describes the test specification language.
  • See test program SignalSync in the v3.1 examples for examples of test specs and reports.

New Tools

  • gen-asm – simple in-line assembler which translates a small subset of Cortex-M instructions into SYSTEM.EMIT (and friends) calls, so we don’t have do the encoding manually anymore. It can translate (or update existing translations) whole directories of modules, including recursively. It is a simple line-by-line translator, hence intended for simple assembly instruction sequences used in Oberon RTK (no loops, no sub-routines). The current uses of SYSTEM.EMIT and friends are being replaced accordingly whenever I work on a module, so that module m33/ASM will become redundant and can be retired.
  • sec-epilogue – add Secure epilogues to procedures that are to be exposed to Non-secure programs

Other Documentation

Updated: 2026-03-31