Skip to content

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:

  1. Write a bare-metal startup sequence for an ARM Cortex-M MCU from reset vector to main()
  2. Configure and use I2C, SPI, UART, and CAN peripherals at the register level
  3. Design a FreeRTOS task architecture with appropriate priorities and synchronization primitives
  4. Boot embedded Linux on an ARM SoC using U-Boot with a device tree
  5. Implement a safe OTA firmware update system with rollback capability
  6. Explain the key requirements of IEC 61508 SIL levels and ISO 26262 ASIL levels
  7. Profile power consumption and implement sleep/wakeup strategies for battery-powered systems
  8. 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)