Systems · 16 pages
- Overview
- Wi-Fi router
- Smartwatch / fitness tracker
- Drone flight controller
- Drone — IMU & sensor fusion
- Drone — BLDC ESC
- EV charger
- EV charger — power stage
- Smart thermostat
- Automotive ECUASIL
- Automotive — AUTOSAR stack
- Industrial motor drive
- Motor drive — FOC algorithm
- IoT sensor node
- Medical wearable
- Industrial gateway
Drone flight controller
Inside a Pixhawk-class flight controller — Cortex-M7 at 480 MHz, 8 kHz attitude loop, IMU + barometer + GPS, DSHOT ESCs, PX4 on NuttX.
A multirotor stays in the air because a Cortex-M7 reads its inertial measurement unit 8000 times per second, runs an extended Kalman filter, and updates four motor PWM outputs faster than the human reaction time. Lose any one of those, lose the aircraft. This is hard real-time at its purest.
At a glance
- Product class
- Open-source FC for racing / fixed-wing / multirotor (Pixhawk-class)
- Newer designs
- Renesas RA8M1 (Cortex-M85) — Helium for ML, faster scalar
- RAM
- 1 MB SRAM + 64 KB ITCM + 128 KB DTCM
- Flash
- 2 MB internal (dual-bank for safe update)
- Sensors
- 2× IMU (redundant), barometer, magnetometer, optical flow, lidar
- Connectivity
- GPS (UART), telemetry radio (UART), R/C receiver (SBUS/CRSF), CAN
- Outputs
- 8–16 PWM/DSHOT channels to ESCs
- Control loop
- 8 kHz attitude, 1 kHz EKF, 100 Hz position
- Certifications
- None for hobby, DO-178C for commercial UAS (rare)
Why Cortex-M7 specifically
The control loop budget on an 8 kHz attitude controller is 125 µs per iteration. In that window the firmware must:
- Read both IMUs over SPI (gyro + accel + temp = 14 bytes × 2 = 28 bytes).
- Apply calibration, temperature compensation, and a low-pass filter.
- Run the inner-loop PID controller (rate → motor command).
- Mix the four-motor allocation matrix.
- Update the four PWM/DSHOT outputs.
A Cortex-M4 at 168 MHz can just barely do this without the FPU; an M7 at 480 MHz with cache + dual-issue does it with ~20% CPU headroom. The headroom is what lets you add velocity estimation, log to SD, stream MAVLink telemetry, and respond to mode changes — all without missing a control deadline.
Block diagram
The 8 kHz attitude loop
Single most important code path in the firmware:
// Pseudocode — runs from ITCM, ISR triggered by TIM5 at 8 kHz
__attribute__((section(".itcm.text"), no_inline))
void attitude_loop_isr(void) {
uint32_t start = DWT->CYCCNT; // for timing watchdog
// 1. Pull fresh IMU samples (already in DTCM via DMA)
imu_sample_t s = imu_samples[imu_select_best(/* health */)];
// 2. Apply notch filter to remove motor-frequency vibration
rate_filtered = notch_apply(s.gyro);
// 3. Inner-loop PID: rate setpoint → torque demand
torque = pid_rate.update(rate_setpoint, rate_filtered);
// 4. Mixer: torque + thrust → 4× motor demands
motor_mix(torque, thrust_setpoint, motors);
// 5. Write to DSHOT600 timer DMA buffer (4 channels)
dshot_write(motors);
// 6. Watchdog — fail if we're more than 80 µs in
if (DWT->CYCCNT - start > 38400) panic("attitude overrun");
}Notable details:
- No malloc, no logging, no waiting on a mutex. Anything that can block is banned.
- Notch filters are critical because brushless motors generate strong vibration at their commutation frequency, which appears in the gyro as broadband noise. Adaptive notches (PX4 calls them "harmonic notch") track the motor RPM and follow the noise peak.
- DSHOT (digital signal for ESCs) is a 16-bit serial protocol where the throttle value is sent over a single PWM line at 150 / 300 / 600 / 1200 kHz. Generated via the timer's DMA + advanced-timer hardware.
- DWT cycle counter is the precision timestamp for the watchdog. See SysTick & timing.
The EKF (state estimation)
The inner loop knows the rate (gyro). To know the attitude (rotation) and position, the firmware runs an Extended Kalman Filter at 250 Hz – 1 kHz that fuses:
- Gyro (high frequency, drifts over seconds)
- Accelerometer (low frequency, noisy short-term)
- Magnetometer (heading, low frequency, distorted by motors)
- GPS (position + velocity, ~10 Hz, ~2 m accuracy)
- Barometer (altitude, 50 Hz, slow drift)
- Optical flow (velocity, available indoors, when present)
PX4's EKF2 (ekf2) and ArduPilot's EKF3 are both 24-state filters running on the Cortex-M7. Each iteration ≈ 200–500 µs depending on which observations are being incorporated. The matrix math relies heavily on the FPU.
Software stack
ArduPilot runs on ChibiOS. PX4 runs on NuttX (a POSIX-like RTOS — see the RTOS landscape). Betaflight (racing/freestyle drones) runs essentially bare-metal with a tiny scheduler.
Boot ROM → custom bootloader → flight stack
│
▼
┌────────────────────┐
│ Sensor drivers │ SPI/I²C tasks
│ Estimator (EKF) │ 250 Hz – 1 kHz
│ Controllers (PID) │ 8 kHz attitude, 100 Hz pos
│ Mixer + outputs │
│ Logging (uLog/.bin)│ to SD or via MAVLink
│ MAVLink telemetry │ over radio + USB
│ Failsafe state-mach│
└────────────────────┘Failsafes are non-negotiable: if R/C link is lost for >500 ms, auto-RTL (return to launch); if battery <20%, smart-land; if attitude excursion >75° while in stabilize mode, auto-recover or kill. These are tested mercilessly because the alternative is hardware in trees.
Real products
| Product | MCU | Notes |
|---|---|---|
| Holybro Pixhawk 6X | STM32H753 + STM32F103 IO MCU | Standard reference; multi-IMU redundancy |
| Holybro Pixhawk 6C | STM32H743 | Single-MCU, cost-optimized |
| CUAV V5+ / Nora+ | STM32H753 | Industrial-grade, popular in commercial UAS |
| Matek H743-WING | STM32H743 | Fixed-wing optimized, integrated PDB |
| Mateksys H743 SLIM | STM32H743 | Tiny FPV racing form factor |
| mRo X21 | STM32F765 (older) | Compact open-source design |
Newer 2024+ designs are starting to use STM32H7+ dual-core, Renesas RA8M1 (Cortex-M85), or NXP i.MX RT1170 — all aimed at running ML-based vision/obstacle-avoidance alongside the traditional flight stack.
Tradeoffs you make
- More CPU headroom = more features — vibration analysis, log rate, MAVLink streams, vision filters.
- More peripherals = more wiring complexity — every UART is a connector; every connector is a failure mode.
- Dual-core (H757) = simpler timing — M7 owns the fast loop, M4 owns logging + telemetry, neither preempts the other.
- Hard vs. soft failsafes — DSHOT bidirectional gives you actual motor RPM feedback, enabling smarter failsafes. Costs extra CPU.
See also
- Cortex-M7 — the dominant flight controller core.
- Cortex-M85 / M55 — where new designs are headed.
- Linker scripts — putting hot code in ITCM.
- DMA — IMU and DSHOT streaming.
- Timers & PWM — DSHOT generation.
- CAN — DroneCAN/UAVCAN bus.
- PX4 source and ArduPilot source (external).