1534  Software Prototyping: Architecture Patterns

1534.1 Learning Objectives

By the end of this chapter, you will be able to:

  • Implement Bare-Metal Architecture: Write efficient single-loop firmware for simple applications
  • Design State Machines: Organize firmware using states and transitions for predictable behavior
  • Build Event-Driven Systems: Use interrupts and callbacks for responsive, power-efficient code
  • Understand RTOS Concepts: Apply real-time operating systems for complex multi-tasking

1534.2 Prerequisites

Before diving into this chapter, you should be familiar with:


1534.3 Bare-Metal Architecture

Description: Direct programming without operating system, executing in a single infinite loop.

Structure:

void setup() {
  // Initialize hardware
  initHardware();
  initSensors();
  initCommunication();
}

void loop() {
  // Main program logic
  readSensors();
  processData();
  transmitData();
  checkCommands();
  delay(1000);
}

Advantages: - Simple and predictable - Minimal overhead - Full control over execution - Easy to understand

Disadvantages: - Blocking operations problematic - Difficult to manage complex timing - Poor scalability

Best For: - Simple applications - Learning and experimentation - Resource-constrained devices

1534.4 State Machine Architecture

Description: Organizing code around states and transitions, common in embedded systems.

State Diagram:

%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#ECF0F1'}}}%%
stateDiagram-v2
    [*] --> IDLE
    IDLE --> SENSING: Timer expires
    SENSING --> TRANSMITTING: Data ready
    TRANSMITTING --> SLEEPING: Send complete
    SLEEPING --> IDLE: Wake up
    TRANSMITTING --> IDLE: Send failed

Implementation:

enum State {
  IDLE,
  SENSING,
  TRANSMITTING,
  SLEEPING
};

State currentState = IDLE;

void loop() {
  switch(currentState) {
    case IDLE:
      if (shouldSense()) {
        currentState = SENSING;
      }
      break;

    case SENSING:
      readSensors();
      currentState = TRANSMITTING;
      break;

    case TRANSMITTING:
      if (sendData()) {
        currentState = SLEEPING;
      }
      break;

    case SLEEPING:
      enterSleep(SLEEP_TIME);
      currentState = IDLE;
      break;
  }
}

Advantages: - Clear logic flow - Easier to debug - Predictable behavior - Power management friendly

Disadvantages: - Can become complex with many states - Requires careful design

Best For: - Battery-powered devices - Applications with distinct modes - Safety-critical systems

1534.5 Event-Driven Architecture

Description: Responding to events (interrupts, messages, timers) rather than polling.

Implementation:

volatile bool dataReady = false;

void setup() {
  attachInterrupt(digitalPinToInterrupt(SENSOR_PIN),
                  sensorISR, RISING);
}

void sensorISR() {
  dataReady = true;
}

void loop() {
  if (dataReady) {
    processData();
    dataReady = false;
  }
  // MCU can sleep when no events
  lowPowerMode();
}

Event Queue Pattern:

struct Event {
  uint8_t type;
  uint32_t data;
};

Queue<Event> eventQueue;

void buttonISR() {
  Event e = {EVENT_BUTTON, millis()};
  eventQueue.push(e);
}

void timerISR() {
  Event e = {EVENT_TIMER, 0};
  eventQueue.push(e);
}

void loop() {
  if (!eventQueue.isEmpty()) {
    Event e = eventQueue.pop();
    handleEvent(e);
  } else {
    enterLowPowerMode();
  }
}

Advantages: - Responsive to external events - Power-efficient (sleep when idle) - Scales well with complexity

Disadvantages: - Interrupt handling complexity - Potential race conditions - Debugging can be challenging

Best For: - Interactive devices - Low-power applications - Complex systems with multiple inputs

1534.6 RTOS-Based Architecture

Description: Using Real-Time Operating System for task scheduling and resource management.

FreeRTOS Example:

#include <Arduino.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

void sensorTask(void *parameter) {
  while(1) {
    readSensors();
    vTaskDelay(1000 / portTICK_PERIOD_MS);
  }
}

void communicationTask(void *parameter) {
  while(1) {
    sendData();
    vTaskDelay(5000 / portTICK_PERIOD_MS);
  }
}

void setup() {
  xTaskCreate(sensorTask, "Sensor", 2048, NULL, 1, NULL);
  xTaskCreate(communicationTask, "Comm", 2048, NULL, 1, NULL);
}

void loop() {
  // Empty - tasks handle everything
}

RTOS Primitives:

Primitive Purpose Example Use
Task Independent execution unit Sensor reading, communication
Queue Inter-task data passing Sensor data to network task
Semaphore Resource synchronization SPI bus sharing
Mutex Mutual exclusion Shared data protection
Timer Periodic callbacks Heartbeat, watchdog

Advantages: - Multiple concurrent tasks - Priority-based scheduling - Resource protection (mutexes, semaphores) - Professional development paradigm

Disadvantages: - Memory overhead - Complexity - Steeper learning curve

Best For: - Complex multi-function devices - Professional embedded development - Systems requiring strict timing

TipTradeoff: RTOS vs Bare-Metal Firmware

Decision context: When deciding whether to use a Real-Time Operating System (FreeRTOS, Zephyr) or write bare-metal firmware for your IoT device

Factor RTOS Bare-Metal
Code Size Overhead 10-50 KB 0 KB
RAM Overhead 1-4 KB per task Minimal
Context Switch Time 1-10 microseconds N/A
Timing Predictability Bounded (configurable priorities) Deterministic
Multi-tasking Native support Manual implementation
Power Management RTOS tickless idle modes Full control
Learning Curve Moderate Low (scales poorly)
Debugging Complexity Higher (race conditions) Lower

Choose RTOS when: - Device has 3+ concurrent activities - Timing requirements vary by priority - Team-maintained code (not solo developer) - Using ESP-IDF, Zephyr, or professional frameworks - Device has 64+ KB RAM available

Choose Bare-Metal when: - Extreme power constraints - Very limited memory (<32 KB RAM) - Single primary function - Hard real-time with sub-microsecond deadlines - Prototyping with Arduino for quick validation

Default recommendation: Start with bare-metal for prototyping, migrate to RTOS when adding concurrent features.

1534.7 Architecture Selection Flowchart

%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#2C3E50', 'primaryTextColor': '#fff', 'primaryBorderColor': '#16A085', 'lineColor': '#16A085', 'secondaryColor': '#E67E22', 'tertiaryColor': '#ECF0F1'}}}%%
flowchart TD
    START["Select Architecture"] --> Q1{"How many<br/>concurrent tasks?"}
    Q1 -->|"1-2"| Q2{"Power<br/>critical?"}
    Q1 -->|"3+"| RTOS["RTOS Architecture"]

    Q2 -->|"Yes"| Q3{"Need instant<br/>response?"}
    Q2 -->|"No"| BARE["Bare-Metal"]

    Q3 -->|"Yes"| EVENT["Event-Driven"]
    Q3 -->|"No"| STATE["State Machine"]

    style START fill:#E67E22,stroke:#2C3E50,color:#fff
    style RTOS fill:#16A085,stroke:#2C3E50,color:#fff
    style BARE fill:#16A085,stroke:#2C3E50,color:#fff
    style EVENT fill:#16A085,stroke:#2C3E50,color:#fff
    style STATE fill:#16A085,stroke:#2C3E50,color:#fff

1534.8 Architecture Comparison

Factor Bare-Metal State Machine Event-Driven RTOS
Complexity Low Medium Medium High
Memory Overhead None Low Low High
Power Efficiency Variable Good Excellent Good
Responsiveness Poor Medium Excellent Good
Scalability Poor Medium Good Excellent
Debug Difficulty Low Low Medium High
Best RAM <16KB 16-64KB 16-64KB >64KB

1534.9 Knowledge Check

Question: Compare three IoT firmware development approaches. Which table correctly matches characteristics?

Explanation: Bare-metal = smallest footprint, deterministic hard real-time, slower development, ultra-low-resource devices. RTOS = medium footprint, hard real-time scheduling, medium development speed, ideal for multi-tasking. Python = largest footprint, soft real-time (garbage collection), fastest development, rapid prototyping.

1534.10 Whatโ€™s Next

The next section covers Libraries and Frameworks, where youโ€™ll learn about sensor libraries, communication protocols, display libraries, and version control practices for IoT firmware development.