Repository navigation
Releases: modules-cpp/modules.cpp
Release list
v1.3.4
modules.cpp v1.3.4
Something to share and connect with. v1.3.4 introduces configure-managed
external C++20 modules shared across applications, backports the high-speed
4-bit SDIO driver for RP2350 with SD/FAT hardware diagnostics, adds an uptime
RTC provider and display gamma corrections for RP2350 LCD boards, suppresses
GCC psabi diagnostics on 32-bit ARM, and provides absent storage fallbacks for
Linux SDL environments.
./build.sh
./test.sh
# Check shared external modules:
./out/bin/shell --run tests/scripts/external-modules.sh
# Build SD/FAT test firmware for RP2350 Touch LCD 2.8:
./configure.sh --target arm-none-eabi --compiler arm-none-eabi-gcc --sdk pico-arm --board rp2350_touch_lcd_28 --runner none --build debug
./test.sh --target --compile-only tests/boards/rp2350_touch_lcd_28Configure-managed external kind: module children can now live alongside
applications in connected kind: dir trees using manifest 1.3 schema.
External applications import these shared modules and partitions without
handwritten header workarounds. Configure validates interfaces, rejects
collisions with installed module names, checks dependency ordering, and
detects cycles before publishing bindings, while build keeps objects and
BMIs in the external tree.
The 4-bit SDIO driver provides fast SD card transfers over PIO and DMA on
RP2350, integrated into the Pico SDK bridge. The rp2350_touch_lcd_28 profile
binds the driver to its TF card socket as mm.sdcard.socket. A dedicated
read-only on-board test in tests/boards/rp2350_touch_lcd_28 validates sector
reading, timeouts, multi-block reads, and FAT mounting on hardware.
platform.rp2350_touch_lcd_154.rtc provides an uptime-based software mm.rtc
clock for RP2350 1.54-inch LCD boards, enabling calendar and clock applications
such as clockcal without requiring external RTC hardware. The ST7789 display
driver updates positive and negative gamma curves and inverted display mode for
rp2350_touch_lcd_154. For Linux SDL builds, platform.linux.storage.absent
supplies an explicit unavailable SD socket, FAT, and LittleFS provider returning
Unsupported so applications referencing storage build cleanly without local
storage emulation.
SDIO operation and software RTC are verified on RP2350 development boards;
write operations and high-load wear-leveling are not formally qualified.
External named module declarations remain restricted to kind: module manifests
and cannot be declared directly in app sources.
Source manifests mm: 1.0 through 1.3 remain supported; the persisted
configuration schema is unchanged.
Requires a C++20 compiler with module support (GCC 14/15 or Clang 18+). Pico
builds require the Arm toolchain, Pico SDK, picotool, and its tools. See
CHANGELOG.md, docs/modules-external-apps.mdy,
docs/modules-sdcard.mdy, docs/modules-configure.mdy, and
docs/modules-display.mdy.
v1.3.3
modules.cpp v1.3.3
Something to build beyond the checkout with. v1.3.3 lets an application
keep its manifest portable while configure records the chosen modules.cpp
installation and toolchain locally. Build, run, flash, debug, and clean then
use that binding across standalone and multi-app projects.
./build.sh
./test.sh
# From a separate directory containing mm.mdy and application sources:
/path/to/modules.cpp/configure.sh --host --compiler clang++
/path/to/modules.cpp/build.sh --host
/path/to/modules.cpp/run.sh --hostAn external application's source manifest stays on the supported mm: 1.3
schema and does not name a particular modules.cpp installation. Configure
finds the installed tool root and writes the machine-local binding to the
external project's out/config.mdy. Consumers use that saved binding and
reject stale or incomplete build outputs. Multiple ordinary C++ source files
can form an application, and connected kind: dir projects share one
configuration tree. A native Linux target can infer host compiler defaults
from its selected native compiler.
sketch --external generates a locator-free sketch application. Existing
project: sketches keep their established workflow. The installed clean tool
can remove owned external build lanes without losing configuration, or reset
an owned external tree with --distclean. The shell regression suite now
covers wrappers, release-fetch diagnostics, standalone UF2 argument handling,
external application lifecycles, and native provider and sketch builds.
External named C++20 module declarations are not supported. Use installed
module interfaces from ordinary application translation units. Optional
Pico validation builds firmware and uses a recording flash backend; it does
not establish operation on hardware. The v1.3.2 camera hardware observation
remains documented separately.
Source manifests mm: 1.0 through 1.3 remain supported. Managed external
applications generate a local configuration record using schema 3.0; source
manifests do not require version 1.4.
Requires a C++20 compiler with module support and the development packages
for the chosen host providers. External Linux integration tests require GCC
and Clang. Pico builds require the Arm toolchain, Pico SDK, picotool, and
its tools. See CHANGELOG.md,
docs/modules-external-apps.mdy, docs/modules-clean.mdy,
docs/modules-configure.mdy, and docs/modules-sketch.mdy.
v1.3.2
modules.cpp v1.3.2
Something to capture and keep. v1.3.1 added USB connectivity; v1.3.2 gives
programs a portable file system with littlefs and FAT on Pico, SD-card and
SPI-flash drivers with Linux emulation, addressable RGB LEDs, and live
HM01B0 camera preview on PICO-Cam-A. New Waveshare board profiles, standalone
UF2 flashing, and USB console fixes complete the release.
./build.sh
./test.sh
./scripts/build-pico.sh --board pico_cam_a --app camera-demo --dry-run
./scripts/build-rgb-led.sh --board rp2040_zero --dry-run
./scripts/build-fs.sh --board generic --dry-runmm.fs adds allocation-free paths, mounts, files and directories, with
move-only handles and a reusable 25-check volume contract. Pico applications
can mount littlefs on reserved program-flash storage, or FAT12/16/32 on block
devices. Linux mounts ordinary directories through mm.fs.local and
mm.fs.native. mm.sdcard drives SD cards in SPI mode, board socket
providers supply wiring, and mm.spiflash drives W25Q-family NOR flash.
The storage-linux profiles emulate both chips in persistent image files,
with CRC checks and fault injection for host-side driver tests.
mm.led and mm.led.ws2812b provide addressable RGB LEDs over the new
mm.mcu pulse facility. Waveshare RP2040/RP2350 Zero profiles bind the
onboard WS2812B; GEEK profiles bind their LCDs and SD sockets; RP2350-PiZero
profiles select the RP2350B SDK header and offer a USB-host variant.
These new LED and storage board paths are not yet qualified on hardware.
PICO-Cam-A binds an HM01B0 camera and a 240x135 ST7789V LCD. camera-demo
starts live capture in CROP after reset, with K3 stop/restart and K4 cycling
crop, nearest, area and temporal sampling. mm.camera.preview implements
processing and debounce as C++20 module code; the display receives complete
RGB565 frames. Sensor settings and initialization delays follow Waveshare's
working C demo. Camera support adapts ArduCAM/RPI-Pico-Cam through Waveshare;
original attribution and local changes are recorded in
boards/pico_cam_a/mm.mdy. Basic preview has been confirmed on the board.
The 250 MHz capture clock exceeds the RP2040's documented 200 MHz operating
point. Frame rate and image quality are not formally qualified.
flash --image <file.uf2> installs independently built firmware through the
existing Pico backend, including --auto-flash. USB console connection and
flush behavior now handle terminals without DTR, deconfiguration, debugger
halts and disconnected hosts with bounded waits. scripts/install-linux-deps.sh
provides an Ubuntu/Debian dependency installer.
Source manifests mm: 1.0, 1.1, 1.2 and 1.3 remain supported; the
persisted configuration schema is unchanged. Linux littlefs/FAT providers,
4-bit SDIO, file commands in the shell, and manifest version 1.4 remain
unreleased development work on main.
Requires a C++20 compiler with module support (GCC 15 recommended), a POSIX
shell, and the development libraries required by the selected hosted
providers. Pico builds require an Arm or RISC-V toolchain, the Pico SDK and
picotool; vendored littlefs and FatFs are provisioned by their vendor scripts.
See CHANGELOG.md, docs/modules-fs.mdy,
docs/modules-sdcard.mdy, docs/modules-spiflash.mdy,
docs/modules-linux-storage.mdy, docs/modules-led.mdy,
docs/modules-pico-cam-a.mdy, docs/modules-stdio.mdy, and
docs/modules-flash.mdy for the released behavior and its limits.
v1.3.1
modules.cpp v1.3.1
Something to connect and store with. v1.3.0 gave the project a language of its
own with sketches and a native shell; v1.3.1 gives programs standard USB
connectivity and mass storage: the USB subsystem (mm.usb) introduces device
and host abstractions, CDC ACM console communication for mm.stdio, and SCSI
Mass Storage Class (mm.usb.msc) for block storage; sketches gain secondary
peripheral buses (Wire1, Wire2, Serial1, Serial2), interrupts, SD card
redirection, and a legacy profile (sketch --legacy) for seamless third-party
Arduino library compatibility; native USB port ownership is unlocked on
Raspberry Pi Pico; Linux adds emulated ST7789 and ILI9341 display support over
SDL2; and fenced code blocks arrive in mm.mdy.
out/bin/sketch apps/ino/blink && ./build.sh apps/ino/blink/
./scripts/build-pico.sh --board pico_usb_device --app apps/shell-smoke --dry-run
./scripts/build-linux.sh --board lcd --app apps/gfx-demo --dry-run
./test.shThe USB subsystem introduces standard USB vocabularies and platform interfaces.
mm.usb defines status, speed, transfer types, endpoint addresses, and setup
packets. mm.usb.device provides nonblocking asynchronous transfers, device
descriptors, and setup request dispatching. mm.usb.host handles device
enumeration, pipe allocation, and interface claiming. On top of these,
mm.usb.cdc supplies CDC ACM device functions and a CdcConsole provider for
mm.stdio, mm.usb.msc implements Bulk-Only Transport (BOT) backing block
storage via transparent SCSI commands, and mm.usb.vendor provides echo
devices and hosts for loopback qualification.
Sketches expand their hardware reach and library compatibility. Wire1 and
Wire2 add second and third I2C buses with independent buffers, pins, and clock
configuration. Serial1 and Serial2 expose hardware UART streams with pin
assignment, timeouts, and nonblocking reads. The legacy profile
(sketch --legacy) enables seamless compilation of third-party Arduino
libraries by providing using namespace mm::sketch::legacy, defining
ARDUINO=10819, redirecting SD.h to SdFat, exporting standard SPI pin names
(SS, MOSI, MISO, SCK), providing flash helper macros, and adding
interrupts() and noInterrupts() control.
On hardware and platforms, Raspberry Pi Pico gains native USB port ownership
options (console vs application) with dedicated pico_usb_device and
pico2_usb_device boards, while pico_usb_host and pico2_usb_host support
mass storage drives via Pico-PIO-USB. On Linux, platforms/linux/lcd provides
emulated ST7789 and ILI9341 displays rendered in SDL2 windows for desktop
graphics development, and platforms/linux/libusb provides the Linux USB host
provider.
mm.mdy now natively parses multi-line fenced code blocks with language tags,
preserving indentation and blank lines, and renders them into HTML <pre><code class="language-..."> tags. tools/flash adds --auto-flash for automatic
Pico device discovery and bootloader reset, configure adds --check to audit
manifest trees, and bootstrap.sh supports custom compiler overrides via
--compiler.
USB device and host hardware operations have been qualified on Raspberry Pi
Pico and Linux host. Emulated displays require SDL2 development libraries on
the host.
mm: 1.0, mm: 1.1, mm: 1.2, and mm: 1.3 manifests remain fully
supported.
Requires a C++20 compiler with module support (GCC 15 recommended, Clang 16+),
a POSIX shell, and libusb / SDL2 for hosted providers. See
CHANGELOG.md for the full change list,
docs/modules-usb.mdy for the USB subsystem, docs/modules-sketch.mdy and
docs/modules-ino.mdy for sketches, and docs/modules-platform-pico.mdy for
Pico platform details.
v1.3.0
modules.cpp v1.3.0
Something to run sketches with. v1.2.4 gave a program sound; v1.3.0 gives the
project a language of its own to be driven in and a door for code written for
another platform: .ino sketches build as ordinary modules.cpp applications,
inside the tree or outside it, over mm.sketch's Arduino-compatible
vocabulary; a shell of the project's own runs the tracked scripts and the root
launchers without /bin/sh, and scales down to an allocation-free embedded
shell on a Pico; and mm.parse gives both shells and the JSON and configure
readers one scanner and one number reader. Manifests gain mm: 1.3.
out/bin/sketch apps/ino/blink && ./build apps/ino/blink/
out/bin/sketch --project . ~/Arduino/MySketch && out/bin/build ~/Arduino/MySketch
out/bin/shell --run scripts/build-gfx.sh -- --dry-run
./check.sh --strictA sketch is a directory of .ino files. tools/sketch writes its
mm.mdy and a main.cpp that mm.ino generates from the sketches -- the
prelude, the includes a sketch leaves to its toolchain, prototypes for every
function, the bodies with line markers so diagnostics point at the .ino, and
a main that runs setup once and loop until requestExit. mm.sketch is
the vocabulary it runs against, over mm.mcu and mm.stdio: pins, analog
reads and writes, tones, pulses, time, the math and character functions,
random numbers, bits and bytes, external interrupts, Serial, SPI, Wire,
Stream, String, and Print. A vendored library that includes Arduino.h
gets a generated compatibility header and compiles unchanged. With mm: 1.3's
project: key a sketch outside the checkout builds, runs, flashes, and is
checked with this project's toolchain, writing only beneath its own tree;
sketch-library: lets a library's example sketches find the library they
exercise. apps/ino has blink, button, and echo.
The project shell comes in four levels. mm.shell is the level-1 foundation
that builds for a target: no allocation, no file system, every buffer the
caller's, and a fixed boundary script in apps/shell-smoke that proves the
capacities it declares. mm.shell.mcu adds mm.mcu and mm.stdio for an
interactive shell on a board; on an RP2040 it adds 110 KiB of flash over a
shell-free control and uses 57 KiB of static RAM, inside its stated ceilings. mm.shell.full
is the host profile -- pipelines, redirections, here-documents, subshells,
traps, functions, command substitution, and now . -- written against
abstract services, and tools/shell runs it natively. The thirteen root
launchers run their scripts through it, and every tracked script is compared
with dash for status, output, files written, and the environment a child tool
sees. --legacy-sh, or MM_SHELL_LEGACY=1, restores /bin/sh for this
release only.
mm.parse is the scanner both shells now share, a number reader, and a time
reader. The move to it had left main unbuildable and, once built, wrong in
ways its tests had not been run to catch; this release fixes every one and
runs every suite in the tests manifest, including the four test.sh had been
missing. mm.build is split into partitions with tests to match, ./check.sh
lists each documented exception to the language rules on every run and fails
on them under --strict, and v1.2.4's build scripts and audio work arrive
here with it.
Sketches and the MCU shell have not been run on hardware in this release.
The sketches, the size measurements, and the Pico lanes are compile and link
qualifications; the M68k and MPS2 QEMU shell smokes pass. mm.sketch keeps
seven documented departures from the project's language rules -- three
unscoped enumerations and four templates that Arduino code depends on --
listed by ./check.sh and recorded in docs/modules-c++20.mdy.
mm: 1.0, mm: 1.1, and mm: 1.2 manifests are unchanged and still valid;
mm: 1.3 adds project:, sketch:, and sketch-library:.
Requires a C++20 compiler with module support, GCC 14 or newer or a recent
Clang, with GCC 15 or newer recommended, and a POSIX shell. The Pico platforms
require the prebuilt tools that platforms/pico/install-sdk-tools.sh
provisions. See CHANGELOG.md for the full list,
docs/modules-ino.mdy and docs/modules-sketch.mdy for sketches,
docs/modules-shell.mdy for the shell, and docs/modules-parse.mdy for
mm.parse.
v1.2.4
modules.cpp v1.2.4
Something to listen with. v1.2.3 gave a program the analog world; v1.2.4
gives it sound: a portable audio interface of sources, sinks, and the stream
between them, I2S in mm.mcu as a continuous transport over PIO and DMA on
every Pico SDK lane, an ES8311 codec driver for both directions, and audio
providers for the RP2350 LCD 1.54 family and the RP2350-Touch-LCD-2.8. It
adds critical sections to mm.mcu and the transport model to the execution
model, and rebuilds the build scripts around two platform scripts whose
checks are read from the manifests.
scripts/build-audio.sh --board rp2350_touch_lcd_154 --flash
scripts/build-audio.sh --board rp2350_touch_lcd_28
scripts/build-gfx.sh --board rp2350_lcd_154
scripts/build-aarch64-linux-gnu.sh --board sdl-linux-aarch64 --app gfx-demo --runmm.audio is three interface classes and knows no pin, transport, or
board. In is a source of sampled sound, Out a sink, and Stream the
connection with one producer and one consumer that carries samples between
either one and an application, or between the two directly. A board's
platform provider derives a Microphone from In and a Speaker from
Out and registers one of each; a board without one registers a device that
answers Unsupported. Ring is the shipped Stream: a ring over
caller-owned storage that never allocates, with two indices each written by
one side, zero-copy regions bounded by the wrap, and underrun and overrun
counts. Samples are sixteen-bit and mono, Format carries the nominal rate
and Rate the exact one, because two devices asked for one rate generally
run at two, and service never waits.
I2S in mm.mcu became a continuous transport: its clock runs from
configure to release, and i2s_write and i2s_read queue into a buffer
the platform owns, beside i2s_rate, i2s_start, i2s_progress,
i2s_stop, and i2s_release. Paced ADC capture and a DAC facility share
that lifecycle and are specified with it, though no provider implements
them yet. On the Pico SDK lanes, platform.pico.mcu implements I2S instance
zero over PIO and DMA on RP2040 and on RP2350 Arm and RISC-V: side-set clocks,
ping-pong DMA over blocks the adapter owns, and a DMA interrupt that refills
or empties them from 256-frame rings, sending zeros on underrun and counting
what it drops. interrupts_disable, interrupts_enable, and
InterruptGuard give critical sections that nest, and
docs/modules-execution.mdy adds model 3, the transport: what a transport's
handler may do, which is acknowledge, count, re-arm, switch to silence, and
drop, and nothing above the seam.
mm.audio.es8311 drives the Everest ES8311 over mm.mcu I2C and I2S:
Output, its DAC as an Out, and Input, its ADC recording the analog
microphone as an In, sharing one Codec. The review that brought it over
corrected its I2C address, its serial-port register, and its missing clock
and power-up programming. rp2350_lcd_154 and rp2350_touch_lcd_154 are
the RP2350 LCD 1.54 family, with and without touch; their audio provider
registers the ES8311 as Speaker, with the NS4150B amplifier enable, and as
Microphone. The RP2350-Touch-LCD-2.8 gains a Speaker straight over I2S for
its PCM5101A, and no Microphone, having none. apps/audio-smoke plays a
tone while recording through whichever devices a board registers.
The build scripts are two platform scripts and their wrappers.
scripts/build-pico.sh and scripts/build-linux.sh build one application
for any board of their platform, and scripts/build-target.sh for any
target lane configure accepts. None of them lists what an image must
contain: they walk the application's closure through the lane's bindings as
the build does, and require one initializer of every reached provider, none
of any other, the symbols of every driver, and every library link. Feature
wrappers -- build-gfx.sh, build-font.sh, build-epaper.sh,
build-audio.sh, and the rest -- work on any board of either platform, and
one wrapper per target platform, from build-aarch64-linux-gnu.sh to
build-m68k-linux-external.sh, names a lane and a default application.
Every script has a --dry-run that test.sh pins, and every script
restores the configuration it found. The per-board and per-lane scripts
of earlier releases are removed; each maps to a wrapper and a board, as
build-linux-epaper-font-demo.sh does to
build-epaper.sh --app font --board epaper.
None of the audio is qualified on hardware. The PIO program, the DMA
ping-pong, the ES8311 transcripts, and both boards' wiring are built for
every Pico SDK lane and checked against datasheets and Waveshare's
schematics, and the host suite pins the ring, the conversions, the codec
contracts against a recording platform, and the critical sections; a tone
from the speaker and a recording from the microphone are physical runs a
person hears. Paced ADC capture and the DAC answer Unsupported everywhere,
and audio is mono.
mm: 1.0, mm: 1.1, and mm: 1.2 manifests are unchanged and still valid.
No manifest key or value is introduced.
Requires a C++20 compiler with module support, GCC 14 or newer or a recent
Clang, with GCC 15 or newer recommended, and a POSIX shell. The Pico
platforms require the prebuilt tools that
platforms/pico/install-sdk-tools.sh provisions. The Linux SDL2 and e-paper
boards additionally require the SDL2 development libraries, and the target
wrappers their cross toolchains and, to run, qemu. See
CHANGELOG.md for the full list, docs/modules-audio.mdy for
the audio interface, docs/modules-platform-mcu.mdy for I2S and critical
sections, and docs/modules-execution.mdy for the transport model.
v1.0.1
- fixed test tool and script to work on macos
- fixed build script to work for macos
- more fixes for mac os, backported from 03fcd94
- this is done to avoid ICE and enable bootstrap with gcc-14
- reonciled documentation with the latest changes
v1.0.0
- rename Unit → TranslationUnit, Target → BuildableNode, and Node → ManifestNode
- update license
- added compiler-is-all-you-need
- fix spelling
- simplify the concrete model adapter use RAII
- remove duplicated code in mdy app
- implemented single traversal for manifest files
- refactor tests to have a single scoped_file class
- noted check tool known limitation
- handle -v -h properly in scripts
- second step to unifying cli processing
- all tools - buiuld0 use mm.app and, first step to unifying cli processing
- added back links to files in manifests and -v for verbose outout
- added descriptions to non-dir manifests
- improved mm.mdy rendering
- fixed formatting issues
- cleanup
- added documentation for wrapper scripts
- bump mm.mdy version to 1.0
- resolve versioning issues
- git ignore drafts
- cleanup of minor issues
- clarified locale C and compiler configuration
- fixed documentation generation
- cleanup of mdy defect regression tess
- added proper handling of unresolved imports
- added foreign project
- refined check
- improved path safety
- reconcile workflow model and description
- further refinment of the models specifically modules
- resolved issues with workflows model
- updated bootstrap build and tests scripts
- updated tools model and add --tools to model tool
- build0 now builds build1
- update configuration model and tool to report it
- tests added to the root manifest
- improved scripts and script handling
- improved handling of module cache clearing
- fixed using template
- fixed error handling is inconsistent with the project’s own specification.
- fixed manifests can write or delete files outside the project.
- fixed duplicate targets and target identity is not validated.
- fixed model adapter knowingly returns structurally false data.
- fix for malformed manifest nodes
- fix for malformed test trees
- mdy documents are rendered now
- fix for dead store
- resolved issue with name conflict for models module is now modules
- further refinment of models
- resolved model inconsitencies
- shell tool integrated into check document and model commands
- added shell tool
- added full models and model tool implementation
- added first version of models
- updated documentation with check tool and check.sh
- added initial version of the check tool
- added c++20 rules for modules
- added glossary to documentation
- small fixes to documentation
- updated README.md
- fix stylistic pattern of passive voice with active voice
- fix stylistic issue
- clarify design goals vs boundaries
- fix for clarity
- fix file names
- added modules document
- couple of fixes for inconsitencies
- added first step in doumentation geration
- first update for building documentation
- addd test tool and tests
- added build tool as mm::build module, fixed manifests
- fix trim() when parsing mdy and restore ->
- added docs/mdy.mdy and updated mdy parsing to parse mdy.mdy
- we have apps modules and build.sh scipt
- buld0 can buld build and we can test it too
- added botostrap
- Initial commit
v1.2.3
- fixes for tests on macos
- more fixes for mac os
- updated linux platform
- fixing Clang code-generation bug for a class with virtual functions in an unnamed namespace
- analog adc and pwm stage 3 linux
- analog adc and pwm stage 2
- added analod adc and pwm to mm.mcu
- json support stage 2
- added json module and tool
- docs cleanup
- added modules-execution model and required fixes
- added support for interrupts
v1.1.1
- prepare v1.1.1: docs release marker and CHANGELOG entry
- fixes for tests on macos
- more fixes for mac os
- this is also done to avoid ICE and enable bootstrap and configure with gcc-14
- this is done to avoid ICE and enable bootstrap with gcc-14
- build with gcc-15 and install cppcheck in CI