You are viewing a free preview of this lesson.
Subscribe to unlock all 10 lessons in this course and every other course on LearningBro.
An embedded system is a complete computer hidden inside a larger device, built to do one job rather than run any software you choose. This lesson explains what makes a system "embedded", the microcontroller at its heart, why so many embedded systems are real-time and safety-critical, and how they contrast with the general-purpose computers studied earlier.
This lesson develops OCR H446 section 1.1.2 (types of processor / embedded systems). It defines an embedded system and its defining characteristics — dedicated function, constrained resources, real-time response and often headless operation — introduces the microcontroller as its typical processor, explores real-time and safety-critical systems (including redundancy and watchdog timers), and contrasts embedded with general-purpose computers. It links to processor types and the FDE cycle (1.1.1), to ROM/flash firmware and the memory hierarchy (1.1.2), to sensors/actuators and control loops (1.1.3), and to the Internet of Things.
An embedded system is a computer built into a larger device to perform a specific, dedicated function, rather than acting as a stand-alone general-purpose machine. The washing machine, the car's engine controller, the smartwatch and the router each contain a complete computer — processor, memory, I/O — but you cannot install arbitrary software on them; they run a fixed program (firmware) held in ROM/flash and do that one job for the device's whole life. The contrast to hold throughout this lesson is dedicated vs general-purpose: an embedded system is engineered, sized and priced for one task, whereas a PC is deliberately over-provisioned so it can run anything.
| Characteristic | Explanation |
|---|---|
| Dedicated function | Performs one task or a small fixed set; the program does not change in normal use |
| Built into a larger product | Not a stand-alone computer — part of an appliance, vehicle or instrument |
| Resource-constrained | Small/slow processor, limited RAM and storage (KB–MB), chosen to be just enough |
| Real-time operation | Often must respond within strict time limits (ms or µs) |
| Low power | Frequently battery-powered or must run continuously on minimal energy |
| Runs firmware | Program lives in ROM/flash; rarely (if ever) updated by the user |
| Often headless | May have no screen or keyboard — interaction via buttons, LEDs, sensors and actuators |
| Low unit cost | Mass-produced; every penny of bill-of-materials matters |
| High reliability | Must run for years without crashing, often in safety-critical roles |
The characteristics are not independent — they follow from "dedicated function". Because the task is fixed and known, the designer can fit exactly the minimum processor, RAM and storage needed, which in turn drives down cost and power; because there is no general-purpose use, there is no need for a rich user interface; and because the firmware never changes, it can be hardened for reliability. Tracing the other traits back to "dedicated function" is the insight examiners reward.
To make the list concrete, map it onto a single device — a fitness watch's heart-rate monitor. Its dedicated function is to sample heart rate and display it; it is built into the watch, not a stand-alone computer. It is severely resource-constrained (a tiny processor and kilobytes of RAM — there is no need for more), which keeps the watch small and cheap. It must update in real time so the reading is current during exercise, and it is overwhelmingly low-power because it runs for days on a small battery — so it spends most of its time asleep, waking on a timer interrupt to take each sample. It runs fixed firmware in flash, has a minimal interface (a small screen and one or two buttons), and must be reliable enough to run unattended on the wrist for years. Every characteristic in the table is visible in this one device, and each is a consequence of it doing one job on a battery — which is exactly the kind of joined-up explanation that scores above a bare list.
Where a PC has a CPU plus separate RAM, storage and I/O chips, most embedded systems use a microcontroller (MCU): a complete computer on a single chip. Integrating everything onto one inexpensive, low-power chip is exactly what suits the cost, size and power constraints above.
flowchart TB
subgraph MCU["Microcontroller (single chip)"]
CPU["CPU core<br/>(often RISC, e.g. ARM Cortex-M)"]
RAM["RAM (SRAM)<br/>KB"]
FLASH["Flash / ROM<br/>(firmware) KB–MB"]
IO["I/O ports, ADC,<br/>timers, comms"]
CPU --- RAM
CPU --- FLASH
CPU --- IO
end
IO --> SENS["Sensors (input)"]
IO --> ACT["Actuators (output)"]
| Feature | Microcontroller (embedded) | Microprocessor (PC CPU) |
|---|---|---|
| Integration | CPU + RAM + flash + I/O on one chip | CPU core only; RAM/storage/I/O are separate chips |
| Memory | Tiny on-chip (KB) | Large external (GB) |
| Architecture | Usually RISC, low clock (MHz) | High clock (GHz), complex |
| Power | Very low (often µA–mA) | High (watts) |
| Purpose | One dedicated control task | Any software |
| Example | ARM Cortex-M, PIC, AVR | Desktop/laptop x86 or ARM |
The link to the processor-types lesson is direct: embedded MCUs are almost always RISC, because a small, simple, low-power core with predictable timing is precisely what a dedicated real-time task needs — the very trade-off that makes RISC win in phones and controllers.
An embedded system boots and runs from firmware in ROM/flash (non-volatile, so it survives power-off — the ROM role from the primary-storage lesson), using only a small amount of volatile RAM for working variables. There is no hard disk and no general-purpose OS to load; on power-up the MCU simply begins executing its firmware. This is the memory hierarchy at miniature scale: a little fast RAM, a modest non-volatile store, no secondary-storage tier at all.
Integrating memory onto the chip is only half the story; an MCU also bundles the peripherals a control task needs, so it can interface with sensors and actuators directly without extra components. The ones that recur in exam scenarios are:
| Peripheral | Role |
|---|---|
| GPIO (general-purpose I/O pins) | Read a button/switch (digital in) or switch an LED, relay or transistor (digital out) |
| ADC (analogue-to-digital converter) | Sample an analogue sensor (temperature, light) into a number — the input-lesson ADC, on-chip |
| PWM (pulse-width modulation) | Vary average power to dim an LED, set motor speed or drive a servo |
| Timers/counters | Measure time intervals, generate periodic interrupts, drive the watchdog |
| Serial comms (UART/SPI/I²C) | Exchange data with other chips, sensors and modules |
Having all of this on one inexpensive chip is precisely what makes the MCU suit the cost, size and power constraints of an embedded system — a general-purpose PC would need a clutter of separate add-in cards to do the same.
The control loop shown next polls — it actively reads the sensor each pass. The alternative, central to efficient embedded design, is the interrupt met in the FDE lesson: a peripheral (a button press, a completed ADC conversion, a timer expiry) signals the CPU, which suspends what it is doing, runs a short interrupt service routine, then resumes. Interrupts let the MCU sleep to save power and wake instantly when an event occurs, instead of burning energy constantly checking — a decisive advantage for a battery-powered device. So the same interrupt mechanism that drives I/O on a PC is, in embedded systems, also a key power-saving and responsiveness technique, directly serving the low-power and real-time characteristics above.
Most simple embedded firmware is structured as an endless control loop: read inputs, decide, drive outputs, repeat. The greenhouse/thermostat pattern from the input and output lessons, expressed as real code, looks like this:
// Embedded thermostat firmware (microcontroller, C)
#define SET_POINT 25 // desired temperature, degrees C
int main(void) {
init_hardware(); // configure ADC, output pins, watchdog
while (1) { // run forever — no OS to return to
int temp = read_adc(TEMP_SENSOR); // sample analogue sensor via ADC
if (temp < SET_POINT) {
heater_on(); // drive actuator
vent_close();
} else {
heater_off();
vent_open(); // open vent to cool
}
kick_watchdog(); // reassure the watchdog we are alive
delay_ms(1000); // re-sample once per second
}
}
Several themes from the whole module appear at once: an ADC turns the analogue sensor reading into a number (data representation), the firmware compares it to a set point and drives actuators (closed-loop control), the program never terminates (there is no OS to return to), and it periodically kicks a watchdog timer (explained below). This single super-loop is the simplest scheduling model; richer systems use an RTOS instead.
Many embedded systems are real-time: correctness depends not only on producing the right output but on producing it within a strict deadline. An airbag that fires 200 ms late is worse than useless. Real-time requirements come in three strengths:
| Type | Requirement | Example |
|---|---|---|
| Hard real-time | The deadline must be met; a miss is catastrophic | Airbag/ABS, flight control, pacemaker |
| Firm real-time | A missed result is useless but not catastrophic | A frame dropped from a production-line vision check |
| Soft real-time | Deadlines should be met; occasional misses just degrade quality | Video/audio streaming |
When a system juggles several timed tasks, a lightweight RTOS (e.g. FreeRTOS, VxWorks, Zephyr) replaces the simple super-loop. Its job is deterministic timing: it guarantees that high-priority tasks meet their deadlines.
| Feature | RTOS | General-purpose OS |
|---|---|---|
| Response time | Guaranteed / deterministic | Best-effort / non-deterministic |
| Scheduling | Priority-based, pre-emptive | Time-sharing, fairness-oriented |
| Size | Tiny (KB) | Large (GB) |
| Examples | FreeRTOS, VxWorks, Zephyr | Windows, macOS, Linux |
The contrast with a desktop OS is the exam point: Windows optimises for average responsiveness and fairness across many apps, accepting the odd pause; an RTOS optimises for worst-case guarantees so a critical task never misses its deadline — which is why a PC OS is unacceptable for hard real-time control. This connects to scheduling in the software-systems module.
It is worth seeing why a system would move from the simple super-loop to an RTOS. In a plain super-loop, every task runs in turn, so a slow task delays all the others: if reading a sensor occasionally blocks for 50 ms, a separate task that must react within 10 ms will miss its deadline, because it cannot run until the loop comes round again. An RTOS solves this with pre-emptive, priority-based scheduling: the high-priority task is assigned a higher priority, and when its moment comes the scheduler interrupts (pre-empts) whatever lower-priority work is running and switches to it immediately, guaranteeing the deadline regardless of what else is happening. This is the heart of "deterministic timing" — not that the system is fast, but that the worst-case response of a critical task is bounded and known. The trade-off is added complexity and a little RAM/ROM for the scheduler, which is why trivial single-task devices (a TV remote, a simple timer) stick with the super-loop, while multi-task, deadline-driven systems (an engine controller juggling fuel, ignition and diagnostics) need the RTOS.
Because embedded systems often run unattended for years, sometimes in safety-critical roles, they use specific techniques to stay reliable.
A watchdog timer is a hardware countdown timer that automatically resets the system if the software stops responding. The firmware must periodically "kick" (reset) the watchdog — the kick_watchdog() call in the loop above. If the program hangs (an infinite loop, a crash, a stuck sensor read), it stops kicking, the timer expires, and the watchdog forces a hardware reset, restarting the firmware in a known-good state. This lets an unattended device recover automatically from a software fault with no human present — vital for a remote sensor, a router, or a spacecraft.
flowchart LR
FW["Firmware loop"] -->|kick before timeout| WDT["Watchdog timer<br/>(counts down)"]
WDT -->|reaches zero = no kick| RST["Force hardware reset"]
RST --> FW
Redundancy means providing duplicate (or triplicate) components so the system keeps working if one fails. In safety-critical designs, several independent units compute the same result and a voter takes the majority (Triple Modular Redundancy), so a single faulty unit is outvoted rather than trusted. Aircraft, for instance, carry multiple independent flight-control computers. Redundancy directly raises reliability by removing single points of failure — at the cost of extra hardware, weight and price.
| Technique | Purpose |
|---|---|
| Watchdog timer | Auto-resets a hung system to a known-good state without human help |
| Redundancy | Duplicate/triplicate units (with voting) so one failure does not stop the system |
| Fail-safe design | On failure, default to a safe state (e.g. signals go to red, valves close) |
| Formal verification | Mathematically prove the firmware meets its specification |
| Extensive testing & certification | Test exhaustively; meet standards (e.g. automotive/aviation safety standards) |
Subscribe to continue reading
Get full access to this lesson and all 10 lessons in this course.