Why Run CNNs on Cortex-M Processors?

ARM Cortex-M cores power millions of edge sensors, industrial controllers, and medical wearables. Running 1D or 2D Convolutional Neural Networks directly on these chips eliminates continuous cloud transmission, reduces latency, and protects user data privacy.

To run a CNN on a microcontroller efficiently, you need specialized kernel libraries. ARM provides CMSIS-NN, a collection of low-level software kernels designed to maximize computational throughput on Cortex-M processor cores.

Hardware Sizing Guidelines

ARM Core DSP / SIMD Support Suitable CNN Workloads
Cortex-M0+ / M3 None Shallow 1D CNNs (1K - 10K parameters)
Cortex-M4 / M33 Single-cycle DSP & SIMD Audio keyword spotting, anomaly detection (10K - 100K parameters)
Cortex-M7 / M55 Dual-issue DSP / Helium Vector Small 2D vision models, spectrogram classification (100K - 500K parameters)

Building a Cortex-Friendly CNN Topology

Avoid standard dense layers with large parameter counts. Use pooling early and limit filter counts.

layers = [
    imageInputLayer([28 28 1], 'Normalization', 'none', 'Name', 'in')
    
    convolution2dLayer(3, 8, 'Padding', 'same', 'Name', 'conv1')
    batchNormalizationLayer('Name', 'bn1')
    reluLayer('Name', 'relu1')
    maxPooling2dLayer(2, 'Stride', 2, 'Name', 'pool1')
    
    convolution2dLayer(3, 16, 'Padding', 'same', 'Name', 'conv2')
    batchNormalizationLayer('Name', 'bn2')
    reluLayer('Name', 'relu2')
    globalAveragePooling2dLayer('Name', 'gap')
    
    fullyConnectedLayer(4, 'Name', 'fc')
    softmaxLayer('Name', 'prob')
    classificationLayer('Name', 'out')
];

Automated Code Generation with CMSIS-NN

Use MATLAB Coder with the ARM Cortex-M Deep Learning Support Package to generate optimized code targeting CMSIS-NN primitives.

cfg = coder.config('lib');
cfg.TargetLang = 'C';

% Target CMSIS-NN libraries
dlcfg = coder.DeepLearningConfig('arm-cortex');
dlcfg.ArmArchitecture = 'armv7e-m';
dlcfg.ArmComputeVersion = 'CMSIS-NN';
cfg.DeepLearningConfig = dlcfg;

% Generate C source code
codegen -config cfg run_model -args {coder.typeof(single(0), [28 28 1])}

The resulting code calls optimized routines such as arm_convolve_HWC_q7_basic and arm_maxpool_q7_HWC, taking full advantage of the chip's SIMD instructions.

Need help sizing or optimizing a CNN for ARM Cortex-M? Talk to the engineering consultants at MATLABSolutions for tailored architecture design and on-target memory profiling.