Deploying Neural Networks to Microcontrollers: The Hardware Reality

Training a deep neural network on a workstation with multiple gigabytes of VRAM is straightforward. Getting that same model to run on an STM32 board with 256 KB of SRAM and 1 MB of Flash memory is where most engineering projects run into trouble.

Desktop models rely on dynamic memory allocation, 32-bit floating-point math, and large runtime libraries. Microcontrollers cannot handle those overheads. MATLAB provides a direct path from a trained dlnetwork object to bare-metal C code through Embedded Coder and the CMSIS-NN library. Here is the process for configuring and flashing an inference pipeline to an STM32 board.

Prerequisites & Toolboxes

Make sure you have these packages installed from the MATLAB Add-On Explorer:

  • MATLAB & Simulink
  • Deep Learning Toolbox
  • MATLAB Coder & Embedded Coder
  • Embedded Coder Support Package for STMicroelectronics STM32 Processors
  • Deep Learning Toolbox Support Package for ARM Cortex-M Processors

Step 1: Build or Import a Target-Friendly Network

Heavy models like ResNet-50 or YOLOv8 will not fit inside standard microcontrollers. For STM32 devices (such as the STM32F4, F7, or H7 series), stick to shallow 1D CNNs for vibration signals, or lightweight 2D architectures like MobileNetV2 with reduced width multipliers.

% Load your trained network
load('motor_fault_classifier.mat', 'trainedNet');

% Check parameter count and memory foot-print
analyzeNetwork(trainedNet);

Step 2: Create the Inference Entry-Point Function

MATLAB Coder requires a standalone MATLAB function that takes sensor inputs and returns class predictions or regression scores.

function prediction = predict_fault(sensorInput)
%#codegen

persistent net;
if empty(net)
    net = coder.loadDeepLearningNetwork('motor_fault_classifier.mat');
end

prediction = predict(net, sensorInput);
end

Step 3: Configure Code Generation for STM32 and CMSIS-NN

Set up a code generation configuration object. Specify an ARM target and select CMSIS-NN to use ARM's optimized vector kernels instead of generic C math.

% Create code generation config for a static library
cfg = coder.config('lib');
cfg.TargetLang = 'C';
cfg.GenCodeOnly = true;

% Configure deep learning code generation for ARM Cortex-M
dlcfg = coder.DeepLearningConfig('arm-cortex');
dlcfg.ArmArchitecture = 'armv7e-m'; % Adjust for your core (e.g., M4/M7)
dlcfg.ArmComputeVersion = 'CMSIS-NN';
cfg.DeepLearningConfig = dlcfg;

% Define fixed-size input data types (e.g., 128 sensor samples)
inputType = coder.typeof(single(0), [1 128 1]);

% Run code generation
codegen -config cfg predict_fault -args {inputType} -report

Step 4: Integrate Generated C Files into STM32CubeIDE

Once codegen completes, open the output codegen/lib/predict_fault/ directory:

  1. Copy the generated .c and .h files into your STM32CubeIDE project's Core/Src and Core/Inc folders.
  2. Include the ARM CMSIS-NN library in your GCC build path.
  3. In main.c, call predict_fault_initialize() once inside the peripheral initialization sequence.
  4. Feed real ADC or accelerometer values directly into predict_fault(inputBuffer, &output) inside your main processing loop or DMA callback.
Need help deploying your custom model? Contact our engineering team at MATLABSolutions for model quantization, peripheral driver mapping, and verified HIL testing on STM32 boards.