Skip to content

modm: a barebone embedded library generator

modm (pronounced like dial-up "modem") is a toolbox for building custom C++20 libraries tailored to your embedded device. modm generates startup code, HALs and their implementations, communication protocols, drivers for external devices, BSPs, etc… in a modular, customizable process that you can fine-tune to your needs.

This project also has a forum for discussions and a technical blog to document larger design concepts.

modm is optimized for the harsh requirements of the Eurobot competition, where our robots need to run reliably and completely autonomously for the game's 100 second duration. Our robots contain a lot of different microcontrollers, some without a lot of resources, so modm needs to fulfill a diverse set of objectives, like small code size with small memory consumption, predictable program flow, extreme portability.

The library source code is licensed as MPLv2 with any external source code under compatible licenses (BSD, Apache2, MIT). So feel free to fork this project and adapt it to your needs. The only thing we ask of you is to contribute your changes back so everyone can benefit.

Please clone modm recursively, you need all the submodules:

git clone --recurse-submodules --jobs 8 https://github.com/modm-io/modm.git

Features

  • Efficient and fast object-oriented C++20 API.
  • Support for hundreds of AVR and ARM Cortex-M microcontrollers from Atmel and ST.
  • Build system agnostic: Choose SCons, CMake, Makefile or use your own.
  • Data-driven, target-specific HAL generation using the lbuild engine.
  • No memory allocations in HAL with very low overall RAM consumption.
  • Highly configurable modules with sensible defaults and lots of documentation.
  • Cross-platform peripheral interfaces incl. bit banging:
    • GPIO, External Interrupt and IO expanders.
    • ADC, DAC and Comparators.
    • UART, I2C, SPI, CAN and Ethernet.
  • Interfaces and drivers for many external I2C and SPI sensors and devices.
  • Debug/logging system with IOStream and printf interface.
  • Lightweight, stackless threads and resumable functions using cooperative multitasking.
  • Functional (partial) libstdc++ implementation for AVRs.
  • Useful filter, interpolation and geometric algorithms.
  • Lightweight unit testing system (suitable for AVRs).
  • Hundreds of tests to ensure correct functionality.
  • Integration of useful third-party software:

Microcontrollers

modm can create a HAL for 3195 devices of these vendors:

  • STMicroelectronics STM32: 2621 devices.
  • Microchip SAM: 186 devices.
  • Microchip AVR: 388 devices.

Here is a table with all device families and the peripheral drivers they support:

  • ✅ Implemented as a software driver in modm.
  • ○ Available in hardware but missing a software driver in modm.
  • ✕ Unavailable in hardware or device with that peripheral not supported by modm.

Note that this is a summary overview and your specific device may not have all the peripherals in this table. Please discover modm's peripheral drivers for your specific device.

STM32 SAM AT
Peripheral F0 F1 F2 F3 F4 F7 G0 G4 H7 L0 L1 L4 D21 G55 V70 90 Mega Tiny
ADC
CAN
Comparator
DAC
DMA
Ethernet
External Interrupt
External Memory
GPIO
I2C
Internal Flash
Random Generator
SPI
System Clock
Timer
UART
Unique ID
USB

We are only a small team of developers and are limited in the amount of devices we can support and test in hardware. Open an issue to ask if your specific device is supported out-of-the-box and what you can do if it is not.

Boards

We have out-of-box support for many development boards including documentation.

AL-AVREB-CAN Arduino NANO Arduino UNO Black Pill F103
Black Pill F401 Black Pill F411 Blue Pill F103 DEVEBOX-STM32F4XX
DEVEBOX-STM32H750VB DISCO-F051R8 DISCO-F072RB DISCO-F100RB
DISCO-F303VC DISCO-F407VG DISCO-F429ZI DISCO-F469NI
DISCO-F746NG DISCO-F769NI DISCO-L152RC DISCO-L476VG
FEATHER-M0 MEGA-2560-PRO NUCLEO-F031K6 NUCLEO-F042K6
NUCLEO-F072RB NUCLEO-F091RC NUCLEO-F103RB NUCLEO-F303K8
NUCLEO-F303RE NUCLEO-F334R8 NUCLEO-F401RE NUCLEO-F411RE
NUCLEO-F429ZI NUCLEO-F439ZI NUCLEO-F446RE NUCLEO-F446ZE
NUCLEO-F746ZG NUCLEO-F767ZI NUCLEO-G071RB NUCLEO-G431KB
NUCLEO-G431RB NUCLEO-G474RE NUCLEO-H723ZG NUCLEO-H743ZI
NUCLEO-L031K6 NUCLEO-L053R8 NUCLEO-L152RE NUCLEO-L432KC
NUCLEO-L452RE NUCLEO-L476RG NUCLEO-L496ZG-P OLIMEXINO-STM32
Raspberry Pi SAMD21-MINI SAMG55-XPLAINED-PRO STM32-F4VE
STM32F030-DEMO Smart Response XE

Drivers

We also have a number of completely target-independent drivers for external devices connected via I2C, SPI, UART, BitBang, etc. Most of these also give you access to the entire device so you can easily configure them for you specific needs.

AD7280A AD7928 ADNS9800 ADS7843 AMS5915 APA102
SPI-FLASH BME280 BMP085 BNO055 CAT24AA DRV832X
DS1302 DS1631 DS18B20 EA-DOG ENCODER-INPUT-BITBANG ENCODER-OUTPUT-BITBANG
FT245 FT6X06 GPIO-SAMPLER HCLAx HD44780 HMC58x
HMC6343 HX711 I2C-EEPROM ILI9341 IS31FL3733 ITG3200
L3GD20 LAN8720A LAWICEL LIS302DL LIS3DSH LIS3MDL
LM75 LP503X LSM303A LSM6DS33 LTC2984 MAX6966
MAX7219 MCP23X17 MCP2515 MMC5603 NOKIA5110 NRF24
TFT-DISPLAY PAT9125EL PCA8574 PCA9535 PCA9548A PCA9685
SH1106 SIEMENS-S65 SIEMENS-S75 SK6812 SK9822 SSD1306
ST7586S STTS22H STUSB4500 SX1276 TCS3414 TCS3472
TLC594X TMP102 TMP12X TMP175 TOUCH2046 VL53L0
VL6180 WS2812

Examples

We have a huge number of examples which are always up-to-date and compilable as enforced by our CI.

AVR: 1-wire/ds18b20 AVR: adc/basic
AVR: adc/oversample AVR: app_can2usb
AVR: assert AVR: block_device_mirror
AVR: can/mcp2515 AVR: can/mcp2515_uart
AVR: display/dogm128/benchmark AVR: display/dogm128/caged_ball
AVR: display/dogm128/draw AVR: display/dogm128/image
AVR: display/dogm128/text AVR: display/dogm128/touch
AVR: display/dogm132 AVR: display/dogm163
AVR: display/hd44780 AVR: display/siemens_s65
AVR: flash AVR: gpio/basic
AVR: gpio/blinking AVR: gpio/button_group
AVR: logger AVR: mega_pro
AVR: ports AVR: protothread
AVR: pwm/pca9685 AVR: sab/master
AVR: sab/slave AVR: timeout
AVR: timer AVR: uart/basic
AVR: uart/extended AVR: xpcc/receiver
AVR: xpcc/sender Arduino NANO: color
Arduino NANO: encoder_input Arduino UNO: basic/analog_read_serial
Arduino UNO: basic/blink Arduino UNO: basic/digital_read_serial
Arduino UNO: basic/read_analog_voltage Black Pill F103: blink
Black Pill F401: blink Black Pill F411: blink
Black Pill F411: usbfatfs Blue Pill F103: adns_9800
Blue Pill F103: blink Blue Pill F103: can
Blue Pill F103: environment Blue Pill F103: flash
Blue Pill F103: graphics Blue Pill F103: itm
Blue Pill F103: logger Blue Pill F103: tlc594x
Blue Pill F103: weight_scale_hx711 Generic: blinky
Generic: delay Generic: etl
Generic: i2c_multiplex Generic: resumable
Generic: ros/can_bridge Generic: ros/environment
Generic: ros/sub_pub Generic: rtc_ds1302
Generic: usb Linux: assert
Linux: block_device/file Linux: block_device/mirror
Linux: block_device/ram Linux: build_info
Linux: can_debugger Linux: etl
Linux: git Linux: logger
Linux: printf Linux: serial_interface
Linux: static_serial_interface Linux: threads
NUCLEO-F031K6: blink NUCLEO-F031K6: sk6812
NUCLEO-F042K6: adc NUCLEO-F042K6: blink
NUCLEO-F042K6: lis3mdl NUCLEO-F042K6: lp503x
NUCLEO-F042K6: lsm6ds33 NUCLEO-F042K6: spi_dma
NUCLEO-F042K6: tmp12x NUCLEO-F072RB: blink
NUCLEO-F091RC: blink NUCLEO-F103RB: blink
NUCLEO-F103RB: hard_fault NUCLEO-F103RB: itm
NUCLEO-F103RB: rtos NUCLEO-F103RB: stts22h
NUCLEO-F103RB: undefined_irq NUCLEO-F303K8: blink
NUCLEO-F303K8: rtos NUCLEO-F303RE: blink
NUCLEO-F303RE: itm NUCLEO-F303RE: rtos
NUCLEO-F303RE: spi_dma NUCLEO-F334R8: blink
NUCLEO-F401RE: blink NUCLEO-F401RE: distance_vl53l0
NUCLEO-F411RE: blink NUCLEO-F411RE: imu_bno055
NUCLEO-F411RE: radio/nrf24-basic-comm NUCLEO-F411RE: radio/nrf24-data
NUCLEO-F411RE: radio/nrf24-phy-test NUCLEO-F411RE: radio/nrf24-scanner
NUCLEO-F411RE: rtos NUCLEO-F411RE: sx1276_rx
NUCLEO-F411RE: sx1276_tx NUCLEO-F411RE: ws2812b
NUCLEO-F429ZI: blink NUCLEO-F429ZI: cmsis_dsp/bayes
NUCLEO-F429ZI: cmsis_dsp/class_marks NUCLEO-F429ZI: cmsis_dsp/convolution
NUCLEO-F429ZI: cmsis_dsp/dotproduct NUCLEO-F429ZI: cmsis_dsp/fft_bin
NUCLEO-F429ZI: cmsis_dsp/fir NUCLEO-F429ZI: cmsis_dsp/graphic_equalizer
NUCLEO-F429ZI: cmsis_dsp/linear_interp NUCLEO-F429ZI: cmsis_dsp/matrix
NUCLEO-F429ZI: cmsis_dsp/signal_converge NUCLEO-F429ZI: cmsis_dsp/sin_cos
NUCLEO-F429ZI: cmsis_dsp/svm NUCLEO-F429ZI: cmsis_dsp/variance
NUCLEO-F429ZI: ethernet NUCLEO-F429ZI: freertos_static
NUCLEO-F429ZI: pat9125el NUCLEO-F429ZI: spi_flash
NUCLEO-F439ZI: blink NUCLEO-F446RE: blink
NUCLEO-F446RE: color NUCLEO-F446RE: flash
NUCLEO-F446ZE: blink NUCLEO-F446ZE: dac_basic
NUCLEO-F446ZE: usbserial NUCLEO-F746ZG: blink
NUCLEO-F767ZI: blink NUCLEO-F767ZI: ethernet
NUCLEO-F767ZI: freertos_blink NUCLEO-G071RB: adc
NUCLEO-G071RB: amnb NUCLEO-G071RB: apa102
NUCLEO-G071RB: blink NUCLEO-G071RB: custom_allocator
NUCLEO-G071RB: flash NUCLEO-G071RB: matrix
NUCLEO-G071RB: rtos NUCLEO-G431KB: blink
NUCLEO-G431RB: blink NUCLEO-G474RE: adc_basic
NUCLEO-G474RE: blink NUCLEO-G474RE: can
NUCLEO-G474RE: dac_basic NUCLEO-G474RE: dac_dma
NUCLEO-H723ZG: blink NUCLEO-H743ZI: blink
NUCLEO-L031K6: blink NUCLEO-L053R8: blink
NUCLEO-L152RE: blink NUCLEO-L432KC: blink
NUCLEO-L432KC: comp NUCLEO-L432KC: gyroscope
NUCLEO-L432KC: pwm NUCLEO-L432KC: pwm_advanced
NUCLEO-L432KC: spi_dma NUCLEO-L432KC: uart_spi
NUCLEO-L452RE: blink NUCLEO-L452RE: graphics_touch
NUCLEO-L452RE: lvgl NUCLEO-L476RG: adc
NUCLEO-L476RG: blink NUCLEO-L476RG: i2c_test
NUCLEO-L496ZG-P: blink OLIMEXINO-STM32: blink
RPI: blinky SAMD: blink
SAMD: interrupt SAMD: usbserial
SAMG55-XPLAINED-PRO: adc-uart SAMG55-XPLAINED-PRO: blink
SAMG55-XPLAINED-PRO: spi-loopback SAMG55-XPLAINED-PRO: usbserial
SAMV: blink STM32-F4VE: flash
STM32-F4VE: gui STM32F0-DISCOVERY: blink
STM32F0-DISCOVERY: logger STM32F030F4P6-DEMO-BOARD: adc
STM32F030F4P6-DEMO-BOARD: blink STM32F072-DISCOVERY: blink
STM32F072-DISCOVERY: can STM32F072-DISCOVERY: hard_fault
STM32F072-DISCOVERY: rotation STM32F072-DISCOVERY: stusb4500
STM32F072-DISCOVERY: tmp102 STM32F072-DISCOVERY: uart
STM32F072-DISCOVERY: unaligned_access STM32F1-DISCOVERY: blink
STM32F1-DISCOVERY: logger STM32F3-DISCOVERY: accelerometer
STM32F3-DISCOVERY: adc/continous STM32F3-DISCOVERY: adc/interrupt
STM32F3-DISCOVERY: adc/simple STM32F3-DISCOVERY: blink
STM32F3-DISCOVERY: can STM32F3-DISCOVERY: comp
STM32F3-DISCOVERY: ft245 STM32F3-DISCOVERY: gdb
STM32F3-DISCOVERY: rotation STM32F3-DISCOVERY: rtt
STM32F3-DISCOVERY: timer/basic STM32F3-DISCOVERY: uart/hal
STM32F3-DISCOVERY: uart/logger STM32F3-DISCOVERY: usb_dfu
STM32F4-DISCOVERY: accelerometer STM32F4-DISCOVERY: adc/interrupt
STM32F4-DISCOVERY: adc/oversample STM32F4-DISCOVERY: adc/simple
STM32F4-DISCOVERY: app_uart_sniffer STM32F4-DISCOVERY: barometer_bmp085_bmp180
STM32F4-DISCOVERY: blink STM32F4-DISCOVERY: can
STM32F4-DISCOVERY: can2 STM32F4-DISCOVERY: colour_tcs3414
STM32F4-DISCOVERY: display/hd44780 STM32F4-DISCOVERY: display/nokia_5110
STM32F4-DISCOVERY: display/ssd1306 STM32F4-DISCOVERY: distance_vl6180
STM32F4-DISCOVERY: encoder_output STM32F4-DISCOVERY: exti
STM32F4-DISCOVERY: fpu STM32F4-DISCOVERY: fsmc
STM32F4-DISCOVERY: led_matrix_display STM32F4-DISCOVERY: open407v-d/gui
STM32F4-DISCOVERY: open407v-d/touchscreen STM32F4-DISCOVERY: pressure_ams5915
STM32F4-DISCOVERY: protothreads STM32F4-DISCOVERY: sab2
STM32F4-DISCOVERY: spi STM32F4-DISCOVERY: temperature_ltc2984
STM32F4-DISCOVERY: timer STM32F4-DISCOVERY: timer_test
STM32F4-DISCOVERY: uart STM32F4-DISCOVERY: uart_spi
STM32F407VET6-DEVEBOX: blinky STM32F407VET6-DEVEBOX: flash
STM32F407VET6-DEVEBOX: logger STM32F429-DISCOVERY: blink
STM32F429-DISCOVERY: logger STM32F469-DISCOVERY: assert
STM32F469-DISCOVERY: blink STM32F469-DISCOVERY: can
STM32F469-DISCOVERY: display STM32F469-DISCOVERY: exceptions_rtti
STM32F469-DISCOVERY: game_of_life STM32F469-DISCOVERY: hard_fault
STM32F469-DISCOVERY: lvgl STM32F469-DISCOVERY: ports
STM32F469-DISCOVERY: threadsafe_statics STM32F469-DISCOVERY: tlsf-allocator
STM32F469-DISCOVERY: touchscreen STM32F746G-DISCOVERY: adc_ad7928
STM32F746G-DISCOVERY: blink STM32F746G-DISCOVERY: rtos
STM32F746G-DISCOVERY: tmp102 STM32F769I-DISCOVERY: blink
STM32H750VBT6-DEVEBOX: blink STM32L1-DISCOVERY: blink
STM32L476-DISCOVERY: blink Smart Response XE: blink
Smart Response XE: display