Skip to main content
emobility.academy
PhDDiagnostics & cybersecurityResearch About 18 weeksKit + add-ons

Embedded Machine-Learning Intrusion Detection for CAN under Real-Time Constraints

You deploy a machine-learning CAN intrusion detector on the kit's STM32F103 that classifies traffic in real time within the budget of a 500 kbit/s classic CAN bus. Models are trained on public attack datasets and evaluated live with attacks replayed through a USB-CAN adapter.

Uses: CAN · UART

The problem

Machine-learning CAN intrusion detectors often report high accuracy on PCs, but an ECU must process every frame in real time with a few kilobytes of RAM. Whether such detectors keep their accuracy and meet timing on low-end automotive-class hardware is a key open question.

Objectives

  • Engineer per-frame and per-window features that can be computed in constant time on the MCU.
  • Train and compare models (decision trees, small neural networks) on public CAN datasets.
  • Compress models for the STM32F103 and verify integer inference.
  • Run live detection at full bus load and measure accuracy, latency and CPU use.
  • Compare with a timing-rule baseline.

What you need

From the EV Embedded Development Kit

  • STM32F103C8T6 microcontroller unit (Arm Cortex-M3)
  • CAN bus interface
  • SPI flash memory
  • 16×2 LCD
  • RGB LEDs and a buzzer
  • Serial UART interface

Software

  • STM32CubeIDE
  • Embedded C with HAL drivers
  • Python (pandas, NumPy, scikit-learn, TensorFlow or PyTorch)
  • python-can for replay
  • Public datasets such as the HCRL Car-Hacking dataset and the ORNL ROAD dataset

Extra parts

  • A USB-CAN adapter — The PC replays dataset traffic and attacks onto the bus for live evaluation; the kit has one CAN node.

Key concepts

Real-time budget per frame
At 500 kbit/s, a short frame takes roughly 100 µs on the bus, so at full load the detector has on the order of 100 µs per frame, about 7,000 CPU cycles at 72 MHz, including everything else the ECU does.
Windowed features
Statistics over the last N frames or milliseconds, such as ID frequency and inter-arrival deviation, updated incrementally so each new frame costs constant time.
Dataset bias
Some public CAN datasets contain attacks that are easy to detect from artefacts such as fixed injected IDs, so high accuracy may not reflect realistic attackers.
Shared CAN and USB memory on the F103
On the STM32F103 the USB and CAN peripherals share a dedicated SRAM buffer, so they cannot be used together; this design uses UART for logging.

Step-by-step guide

  1. 1

    Frame the research and protocol

    Set research questions: can an ML IDS on a Cortex-M3 meet per-frame timing at full 500 kbit/s load, and how much accuracy is lost against PC models? Choose datasets (HCRL Car-Hacking and ORNL ROAD), attack types, metrics (F1, false positive rate, detection latency, cycles per frame) and baselines (timing rules). Define splits by capture so test data are truly unseen.

    Checkpoint: A protocol document with questions, datasets, splits, metrics and baselines.

  2. 2

    Analyse the datasets

    Load the datasets in pandas and study IDs, periods, payload patterns and attack labelling. Identify shortcuts such as attacks using IDs never seen in normal traffic. Plan evaluation subsets that remove easy shortcuts, such as masquerade-style attacks in ROAD, so the results reflect harder cases. Also check how labels are assigned in each dataset, since some label whole time windows while others label individual frames, which changes how metrics must be calculated.

    Checkpoint: A data analysis note listing shortcuts and the evaluation subsets chosen.

  3. 3

    Design MCU-friendly features

    Design features updated in constant time per frame: ID lookup index, inter-arrival time deviation from the learned period, frame count per ID in a sliding window, payload byte change counts and simple bit-flip rates. Implement them first in Python exactly as the firmware will, in integer arithmetic. Limit the number of tracked IDs to fit RAM, and decide in advance what happens when an ID outside the table appears, since this is itself a useful feature.

    Checkpoint: A Python feature extractor that mirrors the planned C code, with memory use per ID calculated.

  4. 4

    Train and compare models

    Train decision trees, small random forests and small int8-friendly neural networks on the features. Evaluate F1 and false positive rate per attack type and on the harder subsets. Record model size and estimated operations, and select candidates that fit the memory budget left after the CAN and application firmware. Use the same feature extractor for every model so differences come from the models, and keep the test captures untouched until the final evaluation.

    Checkpoint: A table of models with accuracy, size and estimated cost.

  5. 5

    Compress and port

    Convert trees to generated C code and quantise neural networks to int8 with integer inference routines. Verify bit-exact outputs against Python integer references using frames sent over UART. Measure cycles per frame for feature update plus inference with the DWT counter. If a model exceeds the budget, reduce depth, number of trees or hidden units and record the accuracy lost at each step. This builds the accuracy-versus-cost curve that is central to the research question.

    Checkpoint: Verified C models with measured cycles per frame, compared with the per-frame budget.

  6. 6

    Build the live testbed

    Turn on the CAN, SPI flash, LCD, LED and UART blocks. Configure bxCAN at 500 kbit/s with accept-all filters and both FIFOs, and connect the USB-CAN adapter with 120 ohm termination. Replay dataset captures from Python with original timing, including attacks. Timestamp frames in the RX interrupt and run detection without blocking reception. Check that replay timing on the PC matches the original captures, since a slow replay understates real load.

    Checkpoint: Replay at the original rate with no FIFO overruns, confirmed by frame counters.

  7. 7

    Run live experiments

    Run every test capture through the kit and log detections over UART with frame indices. Compute live F1, false positives and detection latency against labels, and compare with the PC results. Stress the system by replaying at maximum bus load and check for overruns and missed frames. Repeat each capture several times to check that results are stable, and record the CPU load during each run using an idle-task counter or GPIO marker timing.

    Checkpoint: Live results tables per attack type and a stress test showing whether real-time operation holds.

  8. 8

    Compare with baselines

    Run the timing-rule baseline on the same captures on the kit. Compare accuracy, latency, false positive rate and CPU use. Show which attacks the ML model catches that timing rules miss, and the reverse. Use the same captures, labels and metrics for both detectors, and run them on the same firmware build so CPU use is directly comparable. Discuss whether combining both detectors, with timing rules first and the model second, would give a better overall result.

    Checkpoint: A comparison table and per-attack analysis.

  9. 9

    Study robustness and limits

    Test with traffic that differs from training, such as changed periods or a new ID, to see whether false positives rise. Discuss adversarial attackers who mimic timing and payload. Report the CPU margin left for other ECU tasks. Create these variations by editing the replay scripts, for example adding a new periodic ID or shifting periods by a few per cent. Report false positive rates for each variation so readers can see how sensitive the model is to normal network changes.

    Checkpoint: Robustness results and a limits section.

  10. 10

    Prepare the contribution

    Release feature code, models, firmware and replay scripts. Write the thesis chapter with methods, live results, comparisons and threats to validity, including dataset bias and single-node evaluation. Organise the chapter around the research questions, with sections on dataset analysis, feature design, model selection, embedded cost and live results. Include the accuracy-versus-cost curve, the per-attack comparison with the baseline and a clear statement of which results were measured live on the kit and which come from offline evaluation only.

    Checkpoint: A reproducible package and a draft paper-style chapter.

Testing & validation

  • C feature extraction and inference verified against Python.
  • No frame loss during replay at original and maximum bus load.
  • Live F1, false positive rate and latency per attack type reported.
  • Comparison with a timing-rule baseline on the same captures.

Expected results

A real-time ML CAN intrusion detector running on a Cortex-M3 with measured live accuracy, latency and CPU cost on public datasets, and an honest comparison with simpler detectors and with PC-only results.

Research angle for your PhD

Research questions: can ML-based CAN intrusion detection run within the per-frame budget of full-load 500 kbit/s classic CAN on a Cortex-M3, and how much does accuracy fall from PC evaluation to live embedded operation? Metrics: live F1 and false positive rate per attack type, detection latency, cycles per frame, RAM and flash, CPU margin. Baselines: timing rules and PC models on the same data. Datasets: HCRL Car-Hacking and ORNL ROAD. Publishable contributions include live on-target evaluation, analysis of dataset shortcuts and a clear resource-accuracy trade-off.

Take it further

  • Add on-device adaptation of learned periods for new vehicles.
  • Combine ML detection with message authentication.
  • Run detection on the second STM32 as a dedicated security monitor.
  • Store detection events with RTC timestamps in SPI flash for forensics.

Viva and review questions

What is your time budget per frame?

At 500 kbit/s and full load, a short frame arrives about every 100 µs, so feature update and inference must take well under roughly 7,000 cycles at 72 MHz, leaving time for other ECU work.

Why are some public datasets easy?

Some attacks use IDs never seen in normal traffic or very high injection rates, which any simple rule catches. We used harder subsets such as masquerade attacks to avoid overstating results.

Why not use USB for logging?

On the STM32F103 the USB and CAN peripherals share the same packet memory, so they cannot be used together. We logged over UART instead.

Related EV projects

All 100 EV projects