Section 34: Embedded Systems
Purpose and Scope
Embedded systems are purpose-built computing platforms tightly integrated into the hardware they control. They operate under constraints that don't exist in server or desktop computing: fixed memory budgets measured in kilobytes or megabytes, power envelopes measured in milliwatts, deterministic timing requirements, and the inability to fail gracefully — a crashed embedded system may mean a stopped production line, a failed medical device, or a vehicle accident. This section covers bare-metal programming, microcontroller architecture, RTOS selection and use, embedded Linux, bootloaders, peripheral interface protocols, power management, OTA update systems, and safety-critical standards for automotive and industrial applications.
Prerequisites
- C programming at an advanced level (pointer arithmetic, bitfield manipulation, volatile)
- Basic computer architecture (registers, memory-mapped I/O, interrupts)
- Operating system fundamentals (processes, scheduling, synchronization concepts)
- Electronics basics (voltage levels, pull-up resistors, open-drain vs push-pull) helpful but not required
Learning Objectives
By the end of this section, you will be able to:
- Write a bare-metal startup sequence for an ARM Cortex-M MCU from reset vector to main()
- Configure and use I2C, SPI, UART, and CAN peripherals at the register level
- Design a FreeRTOS task architecture with appropriate priorities and synchronization primitives
- Boot embedded Linux on an ARM SoC using U-Boot with a device tree
- Implement a safe OTA firmware update system with rollback capability
- Explain the key requirements of IEC 61508 SIL levels and ISO 26262 ASIL levels
- Profile power consumption and implement sleep/wakeup strategies for battery-powered systems
- Compare MCU and MPU product families and select appropriately for a given application
Architecture Overview
Embedded System Spectrum
Bare Metal MCU RTOS MCU Embedded Linux
(Cortex-M0/M4) (Cortex-M4/M7) (Cortex-A53/A72)
RAM: 4KB - 512KB RAM: 64KB - 8MB RAM: 64MB - 8GB
Flash: 16KB - 2MB Flash: 256KB - 16MB Storage: eMMC/SD
CPU: 8-400 MHz CPU: 120-600 MHz CPU: 800MHz - 2GHz
Power: 100uW - 100mW Power: 10mW - 1W Power: 0.5W - 5W
OS: None OS: FreeRTOS/Zephyr OS: Linux 5.x+
Boot: us-ms Boot: ms Boot: 0.5s - 10s
| | |
Sensor nodes Motor control HMI, gateway
Wearables Industrial control Networking
Simple actuators Automotive ECU Vision systems
ARM Cortex-M Memory Map and Boot Sequence
Cortex-M4 Memory Map:
0xFFFFFFFF +-----------+
| Reserved |
0xE0000000 +-----------+
| PPB | Private Peripheral Bus: NVIC, SCB, SysTick, DWT
0xA0000000 +-----------+
| External | External device/RAM (implementation-defined)
0x60000000 +-----------+
| External | External RAM (implementation-defined)
0x40000000 +-----------+
| Peripheral| APB/AHB peripherals: UART, SPI, GPIO, Timers
0x20000000 +-----------+
| SRAM | Internal SRAM (stack, heap, .data, .bss)
0x00000000 +-----------+
| Flash/ROM | Interrupt vector table at 0x0, code, .rodata
Boot sequence:
Reset -> Load SP from vector[0] -> Load PC from vector[1] (Reset_Handler)
Reset_Handler:
1. Copy .data section from Flash to SRAM
2. Zero-initialize .bss section
3. Initialize clock (PLL setup)
4. Enable FPU (if present, Cortex-M4/M7)
5. Call SystemInit() (vendor HAL)
6. Call main()
RTOS Architecture (FreeRTOS)
Application Tasks
+-----------+ +-----------+ +-----------+
| Task A | | Task B | | Task C |
| prio=3 | | prio=2 | | prio=1 |
| (motor) | | (comms) | | (display) |
+-----------+ +-----------+ +-----------+
| | |
+-----+--------------+--------------+-----+
| FreeRTOS Kernel |
| Scheduler: Preemptive, priority-based |
| Context switch: PendSV interrupt |
| System tick: SysTick (configTICK_RATE_HZ)|
+------------------------------------------+
| | |
+-----v----+ +-----v----+ +-----v----+
| Queues | | Semaphore| | Software |
| (IPC) | | /Mutex | | Timers |
+----------+ +----------+ +----------+
Task states:
Running -> Blocked (waiting for event/delay)
Running -> Ready (preempted by higher priority)
Blocked -> Ready (event occurred)
Embedded Linux Boot Chain
Power-On Reset
|
v
+----+----+
| ROM Boot | First-stage bootloader burned in SoC mask ROM
| Loader | Minimal, loads next stage from SD/eMMC/NAND/SPI
+----+----+
|
v
+----+----+
| SPL | Secondary Program Loader (U-Boot SPL)
| (DRAM | Initializes DRAM controller, loads full U-Boot
| init) |
+----+----+
|
v
+----+----+
| U-Boot | Full bootloader: init peripherals, load kernel
| (main) | Reads device tree, passes bootargs to kernel
+----+----+
|
v
+----+----+
| Linux | Decompress kernel, init MMU, parse device tree
| Kernel | Init drivers, mount rootfs, start init process
+----+----+
|
v
init/systemd -> target services -> application
Peripheral Interfaces
I2C (Inter-Integrated Circuit):
Master ----SDA---+---[Device A]---[Device B]
----SCL---+ (7-bit addr) (7-bit addr)
Open-drain bus, multi-master, 100kHz/400kHz/1MHz
Protocol: START | ADDR+R/W | ACK | DATA | ACK | STOP
SPI (Serial Peripheral Interface):
Master --MOSI--> Slave
<-MISO-- Slave
--SCK--> Slave
--CS0--> Slave A (one CS per device)
--CS1--> Slave B
Full-duplex, no addressing, modes 0-3 (CPOL/CPHA), up to 50+ MHz
UART (Universal Asynchronous Receiver-Transmitter):
TX -----> RX (cross-connected)
RX <----- TX
Asynchronous, start bit, 8 data bits, optional parity, stop bit(s)
Baud: 9600, 115200, 921600 common
CAN (Controller Area Network):
Node A ---CANH/CANL--- Node B --- Node C (bus topology with 120R termination)
Multi-master, CSMA/CD with arbitration, 1 Mbit/s (CAN FD: 8 Mbit/s)
Message-based (not address-based), priority by arbitration ID
Dominant in automotive and industrial
Key Concepts
- Bare-Metal Programming: Writing software that runs directly on hardware with no OS layer. Requires direct register manipulation, interrupt service routine (ISR) management, and explicit handling of all hardware resources.
- Interrupt Service Routine (ISR): Code executed in response to a hardware interrupt. Must be short, non-blocking, and carefully synchronized with task context. Stack usage and re-entrancy must be analyzed.
- RTOS Task vs Thread: An RTOS task is a schedulable unit with its own stack and priority. Tasks communicate via queues, semaphores, and event groups — not shared memory in the general case.
- FreeRTOS: Dominant open-source RTOS with MIT license since 2017. Portable to hundreds of MCU targets. ~10KB flash, ~2KB RAM footprint for minimal configuration.
- Zephyr: Linux Foundation RTOS. More complete OS model, device driver framework, structured networking stack (Bluetooth, Wi-Fi, Ethernet), suited for complex connected embedded systems.
- Device Tree: Hardware description language used by Linux (and U-Boot) to describe SoC topology without hard-coding it in the kernel. Compiled to DTB (Device Tree Blob) and passed by bootloader to kernel.
- U-Boot: Most widely deployed open-source embedded bootloader. Handles DRAM initialization, storage initialization, network booting (TFTP), environment variable storage, and kernel handoff.
- IEC 61508: Functional safety standard for electrical/electronic systems. Defines Safety Integrity Levels (SIL 1-4) based on risk reduction required. Mandates specific development processes, coding standards, and verification activities.
- ISO 26262: Automotive functional safety standard derived from IEC 61508. Defines Automotive Safety Integrity Levels (ASIL A-D). ASIL D is the highest (airbags, brakes, steering). Mandates FMEA, fault tree analysis, hardware/software safety requirements.
- OTA (Over-the-Air) Update: Remote firmware update capability. Critical design consideration: must handle partial writes, power loss during update, and rollback. A/B partitions or bootloader rollback flags are standard patterns.
Major Historical Milestones
| Year | Milestone |
|---|---|
| 1971 | Intel 4004 — first microprocessor; 4-bit, 740 kHz |
| 1974 | Intel 8080 — first practical embedded MCU target |
| 1979 | Motorola 68000 — dominant in industrial embedded through 1990s |
| 1983 | Intel 8051 — 8-bit MCU, still in production variants today |
| 1993 | ARM7TDMI — low-power ARM core that defined portable embedded |
| 1994 | IEC 61508 first draft — functional safety formalized |
| 1997 | FreeRTOS 1.0 by Richard Barry |
| 2001 | ARM9 family — dominant in early Linux embedded (PXA, AT91) |
| 2004 | ARM Cortex-M3 — Thumb-2 ISA, NVIC, designed for MCUs |
| 2005 | ISO 26262 begins development (ratified 2011) |
| 2008 | Cortex-M0 — ultra-low-power ARM MCU core |
| 2009 | ARM Cortex-M4 with FPU — DSP instructions in MCUs |
| 2012 | Raspberry Pi Model B — embedded Linux accessible to all |
| 2014 | ARM Cortex-M7 — superscalar MCU core (460 CoreMark/MHz) |
| 2015 | ESP8266 — low-cost Wi-Fi MCU disrupts IoT market |
| 2017 | FreeRTOS becomes MIT-licensed under Amazon FreeRTOS |
| 2019 | Zephyr 1.13 — LF Project, broad hardware support |
| 2020 | Raspberry Pi Pico (RP2040) — dual-core Cortex-M0+, $4 |
| 2022 | RISC-V MCUs (ESP32-C3, GD32VF103) become mainstream |
Modern Relevance
Billions of embedded systems ship annually — far exceeding server or desktop deployments. IoT, industrial automation, automotive ADAS, and medical devices all run embedded software where failure has physical consequences. The shift to RISC-V in embedded (RISC-V MCUs from Espressif, SiFive, and Chinese vendors) is real. Rust is gaining traction for safety-critical embedded via the embedded-hal ecosystem and RTIC framework. The automotive AUTOSAR standard and functional safety (ISO 26262) require rigor that server engineers rarely encounter. As vehicles become software-defined and industrial systems become connected, embedded systems engineering is increasingly a security discipline as well.
File Map
34-embedded-systems/
├── 00-overview.md <- This file
├── 01-embedded-constraints.md
├── 02-mcu-vs-mpu.md
├── 03-bare-metal-programming.md
├── 04-arm-cortex-m-internals.md
├── 05-interrupt-handling.md
├── 06-freertos.md
├── 07-zephyr.md
├── 08-rtlinux-for-embedded.md
├── 09-embedded-linux.md
├── 10-uboot-and-barebox.md
├── 11-device-tree.md
├── 12-i2c-and-spi.md
├── 13-uart-and-can.md
├── 14-power-management.md
├── 15-ota-updates.md
└── 16-safety-critical-iec61508-iso26262.md
Cross-References
- Section 03 (Kernel Fundamentals): Interrupt handling, scheduling concepts apply to RTOS
- Section 05 (Boot Process): U-Boot and embedded Linux boot chain in detail
- Section 14 (Device Drivers): Linux device driver model for embedded SoC peripherals
- Section 33 (Hardware Architecture): ARM Cortex-M/A architecture, memory-mapped I/O
- Section 35 (Real-Time Systems): RTOS scheduling theory, jitter analysis, PREEMPT_RT
- Section 44 (Rust and Memory Safety): Rust for embedded (
no_std, RTIC framework)