A whole computer on one chip
A microcontroller, shortened to MCU, is the small computer inside a device that is not itself a computer: a thermostat, a sensor, a motor controller, a fitness band. The Embedded Rust Book compares it to the main board of a 1970s or 1980s home computer, which had a processor, a RAM chip, a ROM chip and an I/O controller joined by a bus. In a microcontroller, the same principles apply, but everything is packed on to a single piece of silicon.
That gives an MCU four parts:
- A processor core that runs the program.
- Flash memory that holds the program and keeps it when the power is off.
- RAM for the program’s working data while it runs.
- Peripherals, the blocks that deal with the outside world: timers, general-purpose pins, analogue-to-digital converters, serial interfaces such as UART, SPI and I2C, and on some parts a radio.
The program stored in that flash is the device’s firmware. It is written for one job, and on a simple device it can be the only code that runs.
What a real part looks like
The Embedded Rust Book uses the STM32F303VCT6, a microcontroller from STMicroelectronics, for its examples. The book lists a Cortex-M4F core with a single-precision floating-point unit, 256 KiB of flash and 40 KiB of RAM, with another RAM region besides. Those are small numbers next to a laptop, and that is the point: the part is sized for its task and its cost.
The processor core and the chip can come from different companies. Arm, for example, licenses its Cortex-M processor designs, and chipmakers build microcontrollers around them, as STMicroelectronics did with the Cortex-M4F in the part above. Arm describes the Cortex-M series as designed for cost-sensitive and power-constrained devices. Its Cortex-M0+ has the smallest footprint and lowest power requirements in the series and suits sensors and wearables, while the Cortex-M4 adds signal processing instructions and an optional floating-point unit for markets such as motor control, automotive and power management. Other microcontrollers use RISC-V or other processor architectures; Espressif’s ESP32 family uses both Xtensa and RISC-V cores.
How it differs from the computer in your laptop
Three differences stand out when you write code for an MCU.
Memory is physical and shared with hardware. On a desktop system, a memory management unit (MMU) stops one process from touching another’s memory and maps physical memory to virtual addresses. The Embedded Rust Book notes that microcontrollers do not typically have an MMU and use real physical addresses in software. Peripherals appear at fixed addresses too, so writing a value to a particular address can switch on a pin or start a timer.
There may be no operating system. The simplest firmware is a single loop that reads inputs, processes them and writes outputs, forever. When something urgent happens, such as a byte arriving on a serial line, the hardware raises an interrupt and a handler runs, then the loop resumes. Arm describes its Armv7-M architecture as offering minimal interrupt latency and being designed for deeply embedded systems. When the work grows, firmware can include a real-time operating system (RTOS) kernel. Zephyr, for example, describes itself as a small-footprint kernel for resource-constrained and embedded systems and supports Cortex-M, RISC-V and Xtensa among other architectures.
Power is a design budget. A battery device saves energy by sleeping whenever it has nothing to do. Arm’s Cortex-M0+ has three low-power modes, so the processor can match its energy use to the work in hand. Firmware wakes on a timer or an interrupt, does its job, and goes back to sleep.
Microcontrollers and the code that runs on them
Firmware for microcontrollers is written in compiled languages such as C, C++, Ada and Rust. The Embedded Rust Book assumes its readers have worked in C, C++ or Ada and know concepts such as cross-compilation, memory-mapped peripherals, interrupts and interfaces like I2C, SPI and serial, which is a fair list of what is different from desktop programming. Code is compiled on a computer for the MCU’s instruction set, then written into its flash over a debug probe or a serial connection.
Rust code that runs on a microcontroller with no operating system is written without the standard library, because the standard library assumes an operating system underneath it. That mode is called no_std Rust.
Choosing one
The Embedded Rust Book suggests checking a few facts in the documentation of any target part: which processor core it has, whether the core includes a floating-point unit, and how much flash and RAM it has. To that list, add the peripherals and radios your design needs, the low-power modes, and the security features, such as a hardware random number generator, secure boot or flash encryption, if the device will hold keys.
A microcontroller can do more than it first appears. With a real entropy source and careful storage, one can take part in end-to-end encrypted messaging, though the memory and energy budget shapes which parts of a protocol it should run itself. Measure on the part you will ship, because figures change from one chip, library and radio stack to the next.