Elective Embedded Systems Programming

Embedded Systems ProgrammingUnit 713 min read

Firmware & Embedded OS: Bootloaders, RTOS, and Real-Time Control

Unit 7 of Embedded Systems Programming: explores firmware design, bootloaders, real-time operating systems (RTOS), scheduling, and embedded OS architectures, with practical insights into how they power devices from smartwatches to industrial controllers.

TAKEAWAYS:

  • Firmware is the low-level software that initializes hardware and enables embedded systems to function autonomously.
  • Bootloaders are critical for secure firmware updates and recovery, using checksums and encryption to verify integrity.
  • RTOS prioritizes deterministic task scheduling (e.g., round-robin, rate-monotonic) to meet strict timing constraints in real-time systems.
  • Embedded OS kernels (e.g., FreeRTOS, Zephyr) abstract hardware resources (CPU, memory, I/O) via device drivers and interrupt handlers.
  • Power management techniques (sleep modes, dynamic voltage scaling) extend battery life in portable devices like eSewa’s payment terminals.
  • Debugging embedded systems relies on JTAG/SWD interfaces and logging frameworks (e.g., printf over UART or RTOS hooks).

1. Firmware: The Embedded System’s Soul

Firmware is the non-volatile software embedded in hardware to control its operation. Unlike general-purpose OSes, firmware is tightly coupled to hardware and often written in C (or assembly) for efficiency. It resides in flash memory (e.g., SPI NOR, NAND) or EEPROM and executes at boot.

Key Components of Firmware

  1. Bootloader: Initializes hardware, loads the main application, and enables updates.
  2. Main Application: The core logic (e.g., sensor reading, motor control).
  3. Device Drivers: Interfaces between hardware (e.g., ADC, UART) and firmware.
  4. Configuration Data: Calibration values, MAC addresses, or encryption keys.

How Firmware Works: A Worked Example

Consider a smart thermostat (like those used in Nepali homes with inverter ACs). Its firmware:

  • Initializes the microcontroller (MCU) and sensors (temperature, humidity).
  • Loads the main loop to adjust heating/cooling based on setpoints.
  • Uses a PID controller (implemented in firmware) to stabilize temperature.

Firmware Flowchart:

flowchart TD
    A["Power On"] --> B["Reset Vector\nJump to Bootloader"]
    B --> C["Initialize MCU\n(Stack, Clock, GPIO)"]
    C --> D["Check Flash\nfor Main App"]
    D --> E["Load Main App\ninto RAM"]
    E --> F["Jump to Main\nApplication"]
    F --> G["Main Loop:\nRead Sensors\nExecute Logic"]
    G -->|"Timeout"| H["Sleep Mode\n(Low Power)"]
    G -->|"Update"| I["Flash Update\n(If Bootloader Enabled)"]

Firmware Storage: Flash Memory Layout

mindmap
  root((Firmware Flash Layout))
    Bootloader[Bootloader (16KB)]
    MainApp[Main Application (128KB)]
    Config[Configuration (4KB)]
    OTA[OTA Partition (32KB)]
    FreeSpace[Free Space]


2. Bootloaders: The Gatekeepers of Firmware Updates

Bootloaders are the first code executed after reset. They handle:

  • Hardware initialization (clocks, memory, peripherals).
  • Secure firmware loading (checksum verification, encryption).
  • Over-the-air (OTA) updates (critical for IoT devices like Pathao’s GPS trackers).

Bootloader Workflow

  1. Power-on Reset (POR): MCU starts at reset vector (e.g., 0x08000000 for STM32).
  2. Jump to Bootloader: If a flag (e.g., BOOT0 pin) is set, execution starts at the bootloader’s entry point.
  3. Verify Firmware Integrity: Checksum or cryptographic hash (e.g., SHA-256) ensures no corruption.
  4. Load Main Application: Copies firmware from flash to RAM and jumps to its entry point.

Worked Example: Secure Bootloader for a Smart Meter

A Nepal Electricity Authority (NEA) smart meter uses a bootloader to:

  • Verify the firmware’s SHA-256 hash before execution.
  • Roll back to a previous version if the new firmware fails checksum.
  • Support OTA updates signed by NEA’s private key.

Bootloader Pseudocode:

uint32_t verify_firmware(uint8_t *firmware, uint32_t size) {
    uint8_t hash[32];
    SHA256_CTX sha256;
    SHA256_Init(&sha256);
    SHA256_Update(&sha256, firmware, size);
    SHA256_Final(hash, &sha256);

    // Compare with stored hash (from flash)
    if (memcmp(hash, STORED_HASH, 32) != 0) {
        return ERROR_CORRUPT;
    }
    return SUCCESS;
}

Trace Table:

Step Action hash[0] hash[1] ... Result
1 SHA256_init() - - ... Initialized
2 SHA256_update(firmware, 128KB) 0xA1 0xB2 ... Processing
3 SHA256_final(hash) 0xA1 0xB2 ... Computed
4 memcmp(hash, STORED_HASH) 0xA1 0xB2 ... MATCH


3. Real-Time Operating Systems (RTOS)

RTOSes manage tasks with deterministic timing guarantees, critical for:

  • Medical devices (e.g., pacemakers).
  • Automotive ECUs (e.g., engine control units).
  • Industrial automation (e.g., Daraz’s warehouse robots).

RTOS vs. General-Purpose OS

Feature RTOS General-Purpose OS (Linux)
Scheduling Fixed-priority (rate-monotonic) Preemptive (CFS)
Latency <1ms 10–100ms
Memory Usage <10KB heap GBs
Interrupt Handling Fast (no context switch) Slower (may block)
Examples FreeRTOS, Zephyr, VxWorks Linux, Windows

RTOS Scheduling Algorithms

  1. Rate-Monotonic Scheduling (RMS):
    • Prioritizes tasks with shorter periods.
    • Used in automotive ECUs (e.g., Bosch’s MCAL).
  2. Round-Robin (Cooperative):
    • Each task gets a time slice (e.g., 10ms).
    • Used in home automation (e.g., Blynk IoT devices).
  3. Priority-Based Preemptive:
    • Higher-priority tasks interrupt lower ones.
    • Used in medical imaging (e.g., MRI scanners).

RTOS Task States:

stateDiagram-v2
    [*] --> Ready
    Ready --> Running : Task starts
    Running --> Ready : Time slice expires
    Running --> Blocked : Waits for I/O/event
    Blocked --> Ready : Event occurs
    Running --> Suspended : Low-priority task
    Suspended --> Ready : Resumed

Worked Example: RTOS in a Daraz Warehouse Robot

A Daraz fulfillment robot uses FreeRTOS to:

  • Task 1 (Period: 10ms): Read ultrasonic sensor for obstacle avoidance.
  • Task 2 (Period: 50ms): Control motor encoders for path following.
  • Task 3 (Period: 1s): Update GPS position for warehouse mapping.

FreeRTOS Task Creation:

xTaskCreate(
    obstacle_avoidance_task,  // Task function
    "ObstacleAvoid",          // Task name
    200,                      // Stack size (bytes)
    NULL,                     // Parameters
    2,                        // Priority (higher = 2)
    NULL                      // Task handle
);

Trace Table (First 50ms):

Time (ms) Task 1 (10ms) Task 2 (50ms) Task 3 (1s) CPU Usage
0–10 Running Blocked Blocked 100%
10–20 Blocked Running Blocked 0%
20–30 Running Blocked Blocked 100%
30–40 Blocked Running Blocked 0%
40–50 Running Running Blocked 50%


4. Embedded OS Kernels: FreeRTOS and Zephyr

FreeRTOS

  • Pros:
    • Lightweight (~10KB RAM).
    • Portable (ARM, AVR, ESP32).
    • Open-source (MIT license).
  • Cons:
    • Limited networking (requires FreeRTOS+TCP).
    • No built-in file system.

Zephyr

  • Pros:
    • Unified API for multiple architectures (ARM, x86).
    • Built-in Bluetooth/Wi-Fi (via modules).
    • Supports multi-core.
  • Cons:
    • Larger footprint (~500KB).
    • Steeper learning curve.

Comparison Table

Feature FreeRTOS Zephyr
License MIT Apache 2.0
Networking FreeRTOS+TCP (add-on) Built-in (lwIP)
Bluetooth Requires stack (e.g., Nordic) Built-in (Zephyr BLE)
File System None FAT, LittleFS
Multi-core Limited support Full support

Worked Example: Zephyr on a Pathao GPS Tracker

Pathao’s vehicle tracking system uses Zephyr to:

  • Task 1: Read GPS data (period: 1s).
  • Task 2: Send data to cloud via MQTT (period: 5s).
  • Task 3: Handle driver alerts (e.g., speeding, harsh braking).

Zephyr MQTT Task:

void mqtt_task(void *p1, void *p2, void *p3) {
    struct net_mgmt_event_pkt *pkt;
    struct net_buf *buf;

    while (1) {
        buf = net_mgmt_alloc_buf(DATA_BUF_SIZE);
        if (!buf) {
            continue;
        }
        // Parse GPS data from UART
        // Publish to MQTT broker
        net_mgmt_event_port_add(buf, NET_EVENT_MQTT_PUBLISHED);
        k_sleep(K_SECONDS(5));
    }
}


5. Power Management in Embedded Systems

Battery life is critical for portable devices like:

  • eSewa’s POS terminals (must last 8+ hours).
  • Khalti’s mobile wallets (low-power sensors).
  • Ncell’s IoT trackers (solar-powered).

Power-Saving Techniques

  1. Sleep Modes:
    • Idle: CPU stops, peripherals active.
    • Deep Sleep: CPU + peripherals off (wakes on interrupt).
  2. Dynamic Voltage Scaling (DVS):
    • Reduces voltage/frequency when idle (e.g., STM32’s Low-Power Run mode).
  3. Clock Gating:
    • Disables unused peripherals (e.g., UART when not transmitting).

Power States in STM32:

mindmap
  root((STM32 Power Modes))
    Active[Active Mode\n(Full Speed)]
    Stop[Stop Mode\n(CPU Off, RAM Retained)]
    Standby[Standby Mode\n(CPU + Peripherals Off)]
    Shutdown[Shutdown Mode\n(All Off, Backup RAM)]

Worked Example: eSewa POS Terminal

An eSewa POS uses:

  • Deep Sleep: When idle (e.g., no transactions for 5 mins).
  • DVS: Reduces CPU clock to 48MHz during low activity.
  • UART Wakeup: Wakes on transaction request.

Power Consumption Comparison:

Mode Current (mA) Use Case
Active 200 Processing payment
Stop 10 Waiting for transaction
Deep Sleep 0.5 No activity


6. Debugging Embedded Systems

Debugging firmware is harder than desktop apps due to:

  • No GUI/terminal.
  • Limited memory (e.g., 32KB RAM).
  • No OS-level tools (e.g., gdb may not work).

Debugging Tools

Tool Purpose Example Use Case
JTAG/SWD In-circuit debugging (STM32, Arduino) Flashing firmware to a Daraz robot
UART Logging Serial output (printf) Debugging sensor readings in a NEA meter
RTOS Hooks Task monitoring (FreeRTOS vTaskList) Checking if a Pathao GPS task is stuck
Ozone (SEGGER) GUI-based debugging Analyzing a Ncell IoT firmware crash

Worked Example: Debugging a FreeRTOS Task Hang

A Pathao GPS task stops responding. Debug steps:

  1. Check UART Logs:
    printf("GPS Task: Lat=%f, Lon=%f\n", lat, lon);
    
    Output: GPS Task: Lat=0.000, Lon=0.000 (stuck at startup).
  2. Use FreeRTOS Hooks:
    void vTaskGetRunTimeStats(void) {
        UBaseType_t ulTotalRunTime;
        TaskStatus_t *pxTaskStatusArray;
        // Print task stats to UART
    }
    
    Output shows GPS task has 0% CPU time.
  3. JTAG Inspection:
    • Breakpoint at GPS_Init() shows it never returns (hardware issue).


In the Real World

  1. eSewa’s POS Terminals:

    • Use FreeRTOS to manage payment processing tasks (e.g., swipe, PIN entry, cloud sync).
    • Power-saving: Switch to Stop Mode when idle to extend battery life.
    • Firmware Updates: Bootloader verifies OTA updates via SHA-256 to prevent fraud.
  2. Pathao’s Vehicle Tracking:

    • Zephyr OS runs on a STM32H7 MCU to:
      • Read GPS data (1Hz task).
      • Send MQTT updates to Pathao’s cloud (5Hz task).
      • Handle driver alerts (e.g., speeding) via priority interrupts.
    • Real-World Example: If a Pathao driver exceeds 80 km/h, the system logs the event and sends an alert to the dispatcher.
  3. Nepal Electricity Authority (NEA) Smart Meters:

    • Custom RTOS (based on FreeRTOS) ensures:
      • Deterministic power reading (every 15 minutes).
      • Secure firmware updates via AES-128 encryption.
    • Worked Example: If a meter reports 0 kWh for 3 hours, the bootloader detects a corrupt firmware and rolls back to the last good version.

Exam Tips

  1. Bootloaders:

    • Always mention checksum/encryption for secure updates.
    • Draw the flash memory layout (bootloader + app + OTA partitions).
    • Example: "Explain how a NEA smart meter’s bootloader verifies firmware integrity."
  2. RTOS:

    • Compare RMS vs. round-robin scheduling with a table.
    • Show a task state diagram (Ready → Running → Blocked).
    • Example: "Design an RTOS for a Daraz warehouse robot with tasks for GPS, motor control, and cloud sync."
  3. Embedded OS:

    • List FreeRTOS vs. Zephyr pros/cons in a table.
    • Mention power modes (Active → Stop → Deep Sleep) with current consumption.
    • Example: "Why does an eSewa POS use Zephyr instead of FreeRTOS?"
  4. Debugging:

    • Describe JTAG vs. UART logging for embedded systems.
    • Example: "How would you debug a stuck task in a Pathao GPS system?"
  5. Firmware Workflow:

    • Always include a flowchart (reset → bootloader → main app).
    • Example: "Trace the execution flow of a firmware update in a Ncell IoT tracker."
  6. Power Management:

    • Draw the STM32 power modes with current consumption.
    • Example: "Calculate the battery life of an eSewa POS in Stop Mode vs. Active Mode."

Based on the TU BSc CSIT syllabus for Embedded Systems Programming, unit 7.

Discussion

Loading…