Feature Request – Compile-Time Register-Level Code Generation for STM32CubeMX / CubeMX2
Dear STMicroelectronics Development Team,
I would like to suggest a feature that could significantly improve STM32CubeMX and STM32CubeMX2, particularly for embedded projects with limited Flash memory and strict performance requirements.
Current Situation
When configuring peripherals such as GPIO, timers, ADC, UART, SPI, etc., CubeMX typically generates initialization code using HAL or LL functions.
Although these libraries provide a convenient and structured programming interface, the generated initialization code can introduce considerable overhead.
In many cases, the hardware configuration is completely static and known at compile time. However, the generated code may still involve multiple function calls, intermediate structures, parameter assignments, and runtime operations just to write a few fixed values into hardware registers.
For example, configuring a GPIO port might ultimately require only a few register writes with constant values. Yet the generated initialization code can be considerably larger than the actual hardware configuration requires.
This becomes particularly problematic in memory-constrained applications, where even initialization code contributes to Flash consumption.
Proposed Feature: Direct Register-Level Code Generation
I suggest adding an optional code-generation backend that converts the selected CubeMX configuration directly into optimized register-level initialization code.
Instead of generating HAL/LL initialization functions, CubeMX could calculate all required register values during code generation and produce a minimal C implementation using constant values.
For example, instead of generating multiple HAL calls and configuration structures, the output could be equivalent to:
void GPIO_Init(void)
{
RCC->AHB2ENR |= 0x00000001UL;
GPIOA->MODER = 0x........UL;
GPIOA->OTYPER = 0x........UL;
GPIOA->OSPEEDR = 0x........UL;
GPIOA->PUPDR = 0x........UL;
GPIOA->AFR[0] = 0x........UL;
}The actual values would be calculated by CubeMX based on the user's configuration.
With constant values and suitable compiler optimization, the resulting assembly could be reduced to a very small number of direct register-write instructions, without unnecessary runtime calculations or function calls.
Suggested Implementation
Rather than replacing HAL or LL, this could be offered as an additional code-generation option:
-
HAL-based generation (existing functionality).
-
LL-based generation (existing functionality).
-
Direct Register-Level generation (new option).
The new option should:
-
Calculate register values during code generation, not at runtime.
-
Generate direct register writes using compile-time constants.
-
Avoid unnecessary initialization structures and function calls.
-
Generate only the registers and operations required by the selected configuration.
-
Respect register-specific behavior, including reserved bits, write-one-to-clear flags, and required initialization sequences.
-
Support all applicable STM32 families, not just newly introduced families.
Ideally, users should be able to select this generation method independently for each peripheral.
Expected Benefits
-
Significantly reduced initialization code size.
-
Lower Flash consumption.
-
Faster system startup.
-
Reduced runtime overhead.
-
No dependency on HAL or LL for the generated initialization code.
-
Better suitability for resource-constrained embedded applications.
-
Greater control over the final machine code.
An Additional Benefit
CubeMX already has all the necessary information about pin assignments, clock configuration, peripheral modes, and register settings.
Therefore, it should be possible to calculate the final register values internally without requiring the user to manually inspect generated code, debug initialization functions, or extract register values.
This would also reduce human errors associated with manually translating HAL configurations into register-level code.
I believe this feature would be valuable not only for advanced embedded developers but also for applications where code size, startup time, and execution efficiency are critical.
Thank you for considering this suggestion.
Best regards
