Printhor is a generic a hardware-agnostic firmware framework focused on FDM printers, CNC and Engravers implemented in Rust.
There are many productive firmwares in the community like gbrl, marlin, reprap, etc. Each single one have a concrete approach and guidelines. This one aims to provide a research environment for not strictly productive purpose, but a reliable platform with the following goals: * Robustness. * Numerical stability. * Efficient resources utilization and close-to-preemptive multitasking. * Leverage async multitasking. * Maintain busy waits to a minimum. * Ensure leverage of DMA transfers as much as possible. * Ensure of leverage of FPU when present. * Simplicity. * Clarity and readability.
Which means the principal short-term goal is not to develop a productive firmware for final user rather than providing an environment in which anyone can test and experiment any concrete approach to feed the community with good quality, state-of-the-art or innovative feature increments.
| Feature | Status |
|---|---|
| Simulation | Functional |
| I/O | Functional |
| State and logic | Incubation |
| Motion Planner | Incubation |
| Kinematics | Draft |
| Thermal Control | Draft |
| Display | Draft |
| Laser/CNC | TODO |
If you are interested in this project and want to collaborate, you are welcome.
A Discord server has been created for informal discussions. Otherwise, Github Issues and Pull Requests are preferred.

git clone https://github.com/cbruiz/printhor
cd printhor
The minimal toolset required to build and run is: * Rust, in order to compile * cargo binutils, to produce the image binary that you can flash via SD card as usual. * [Optionally] probe-run, if you are willing to use a SWD/Jlink debugger (https://github.com/knurling-rs/probe-run) * [Optionally] cargo-bloat and cargo-size utils are great to analyze the code size. * [Optionally] A Rust IDE, like VStudio Code (recommended), Jetbrains IDE (IntelliJ, CLion or RustRover (recommended)), or others
This crate requires Rust >= 1.75.
For official guide, please see https://www.rust-lang.org/tools/install
However, if your os is unix based:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup update
For microcontrollers (currently few stm32 only), the specific target toolchain and cargo binutils is also needed:
rustup target add thumbv7em-none-eabi
rustup target add thumbv7em-none-eabihf
rustup target add thumbv6m-none-eabi
rustup component add llvm-tools
cargo install cargo-binutils
Optionally, for debugging on baremetal microcontrollers (currently few stm32 only):
cargo install probe-run
The framework with a set of mocked peripherals (most of them without any logic). Provides a commandline GCode prompt on standard input
Note: A SDCard image in ./data/ is required to be open if sdcard feature is enabled in native :)
RUST_LOG=info cargo run --bin printhor
Native backend has a special feature called integration-test which is used to perform "some kind of" integration tests. Still pending to be matured.
RUST_LOG=info cargo run --features integration-test --bin printhor
Testing with GCode sender though socat
RUST_LOG=info cargo build --bin printhor
socat pty,link=printhor,rawer EXEC:target/debug/printhor,pty,rawer
This board (https://www.makerbase.store/pages/mks-robin-nano-v3-1-intro) is still work in progress
The firmware.bin file ready to be uploaded to the SD can be produced with the following commandline:
DEFMT_LOG=info cargo objcopy --release --no-default-features --features mks_robin_nano --target thumbv7em-none-eabihf --bin printhor -- -O binary firmware.bin
Firmware size if 200kB as of now with previous settings.
DEFMT_LOG=off RUST_BACKTRACE=0 cargo objcopy --profile release-opt --no-default-features --features mks_robin_nano --target thumbv7em-none-eabihf --bin printhor -- -O binary firmware.bin
Firmware size if 164kB as of now with previous settings.
DEFMT_LOG=info RUST_BACKTRACE=1 RUSTFLAGS='--cfg board="mks_robin_nano"' cargo run --release --no-default-features --features mks_robin_nano --target thumbv7em-none-eabihf --bin printhor
There are two base boards supported in this category.
The assumption/requirement is to use any of these generic purpose development board with the Arduino CNC Shield v3 (hat):

In these development boards, flash and run can be directly performed with probe-rs just connecting USB as they have a built-in SWD/JTAG interface:
Please, note that this board is very limited in terms of flash and memory (48kB SRAM, 128kB flash). You might not assume that a firwmare not optimized for size (LTO, etc...) will fit in flash.
Note: This target uses flip-link by default, requiring flip-link tool. To change this behavior please check .cargo/config.toml
cargo install flip-link
DEFMT_LOG=info RUST_BACKTRACE=0 RUSTFLAGS='--cfg board="nucleo64-f410rb"' cargo run --release --no-default-features --features nucleo_64_arduino_cnc_hat,nucleo64-f410rb --target thumbv7em-none-eabihf --bin printhor
This one is a bit slower but much more RAM and flash. Enough even though with non very optimized firmware and may features
DEFMT_LOG=info RUST_BACKTRACE=0 RUSTFLAGS='--cfg board="nucleo64-l476rg"' cargo run --release --no-default-features --features nucleo_64_arduino_cnc_hat,nucleo64-l476rg --target thumbv7em-none-eabihf --bin printhor
This board (https://biqu.equipment/collections/control-board/products/bigtreetech-skr-mini-e3-v2-0-32-bit-control-board-for-ender-3) is quite functional
The firmware.bin file ready to be uploaded to the SD can be produced with the following commandline:
DEFMT_LOG=info cargo objcopy --release --no-default-features --features skr_mini_e3 --target thumbv6m-none-eabi --bin printhor -- -O binary firmware.bin
Firmware size if 196kB as of now with previous settings.
DEFMT_LOG=off RUST_BACKTRACE=0 cargo objcopy --profile release-opt --no-default-features --features skr_mini_e3 --target thumbv6m-none-eabi --bin printhor -- -O binary firmware.bin
Firmware size if 164kB as of now with previous settings.
DEFMT_LOG=info RUST_BACKTRACE=1 RUSTFLAGS='--cfg board="skr_mini_e3"' cargo run --release --no-default-features --features skr_mini_e3 --target thumbv6m-none-eabi --bin printhor
A simple stand-alone std binary to experiment with motion plan (kind of playground):
cargo run --bin scurve_plot
Example output:

For a single board, the high-level features (hotend, hotbed, fan, sdcard, ... ) can be activated/deactivated by cargo feature selection or directly editing the main cargo.toml In order to change pins, writing/adapting some code is required, as of now. There is not expected to be, at least in the short term any kind of configuration file.
Because of that limitation (Rust makes that hard to tackle because of the strict typing), a clean code organization it's crucial and pretty straightforward to assume slight customizations by editing code.
printhor is composed by the following architectural blocks * embassy-rs, as the harware and async foundation https://github.com/embassy-rs/embassy * async-gcode, as the core of the GCode interpretation https://github.com/ithinuel/async-gcode * printhor-hwa-common (within the project), as the hardware abstraction layer contract and common utilery * A set of crates (withn the project) for each harware/board. Currently: * printhor-hwi_native : The native simulator. * printhor-hwi_skr_mini_e3_v3 : (See Datasheets/SKR_MINI_E3-V3.0) * printhor-hwi_mks_robin_nano_v3_1 [WIP] : (See Datasheets/MKS-ROBIN-NANO-V3.1) * printhor-hwi_nucleo_64_arduino_cnc_hat [WIP] : A Nucleo-64 development board (currently L476RG or F410RB) with Arduino CNC Shield v3.x (See Datasheets/NUCLEO-L476RG_CNC_SHIELD_V3)
Intentionally, traits are in general avoided when not strictly required in favour of defining a more decoupled and easy to evolve interface based on: * type aliases * module exports
Diagram is Work in Progress
Gcode implementation status, as from https://reprap.org/wiki/G-code
| M-Code | Mode | Description | Status |
|---|---|---|---|
| M | * | List all supported m-codes | DONE |
| M0 | * | Stop or Unconditional stop | WIP |
| M1 | * | Sleep or Conditional stop | WIP |
| M2 | * | Program End | WIP |
| M3 | CNC | Spindle On, Clockwise | WIP |
| LASER | Laser On | WIP | |
| M4 | CNC | Spindle On, Counter-Clockwise | WIP |
| LASER | Laser On | WIP | |
| M5 | CNC | Spindle Off | WIP |
| LASER | Laser Off | WIP | |
| M6 | * | Tool change | ILT |
| M7 | CNC | Mist Coolant On | ILT |
| M8 | CNC | Flood Coolant On | ILT |
| M9 | CNC | Coolant Off | ILT |
$ claude mcp add printhor \
-- python -m otcore.mcp_server <graph>