Removing a CubeMX Peripheral Can Remove Its User Code Container
A CubeMX user-code section can survive regeneration while its surrounding peripheral remains enabled, then disappear when that peripheral’s generated file is removed. Before disabling an interface, check what the project has stored inside its generated source files. The important review is the removed-file list, not simply whether the surviving files retained their user sections.
This article uses STM32CubeMX UM1718 Rev 51, May 2026, and a hypothetical project that generates peripheral initialization into separate source/header pairs. The proposed checks have not been executed in CubeMX or on a target.
Distinguish section preservation from file retention
UM1718 section 4.11.2 describes two separate settings: preservation of user sections in generated files, and deletion of previously generated files no longer needed by the configuration. Its example removes the UART source/header pair when that peripheral is disabled. Preservation also has a stated scope; it is not a general backup service for every manually added or template-generated file.
That combination creates a specific maintenance question: does a required application function live inside a file whose continued existence depends on a peripheral selection? A comment marker tells a generator where user text belongs. It does not express that the product still needs that text after the generated container becomes unnecessary.
For example, suppose a hypothetical usart.c contains both UART initialization and a user-section function that formats diagnostic messages for several transports. Retiring the UART does not necessarily retire the formatter. If the formatter’s only source copy is in that generated container, the peripheral change has become an application-code retention problem.
Inventory responsibilities before disabling the interface
Start from the reviewed project revision and preserve a recoverable copy. Inspect the generated source and header associated with the peripheral. List the user-added functions, variables, includes, callback implementations, and public declarations there. Then classify each item by the requirement it serves, rather than by the filename where it happens to reside.
Some items truly belong to the removed interface, such as its receive-buffer management. Others may be shared services or compatibility wrappers. For each surviving responsibility, identify a new application-owned source location and the generated interfaces it still consumes. Move the implementation deliberately and update its declaration and build membership together.
Check call sites as well as definitions. A retained function that is no longer invoked is still a functional regression. Conversely, a deleted helper with no remaining references might produce a successful link while removing an entire optional behavior. The compiler can report certain inconsistencies; it cannot decide whether the removed service was still a product requirement.

Original deletion-boundary diagram. The exact generated filenames depend on the project.
Review the complete generation diff
Make the peripheral change in a disposable development copy. Before generating, record the separate-file setting, user-code preservation setting, and obsolete-file deletion setting. These choices define what the experiment is meant to establish. Do not rely on a colleague’s remembered defaults or a screenshot from another project.
After generation, compare added, modified, and removed paths. Read every removed source/header that previously contained user code. For modified files, inspect interrupt registrations, initialization call sites, handle references, and declarations affected by the interface removal. Keep unrelated configuration changes out of this pass so the reason for each deletion remains understandable.
An intentionally retained obsolete file also needs a decision. Disabling deletion may keep the text available, but it can leave dead initialization, conflicting definitions, or misleading code in the build. Treat retention as a recovery aid while ownership is repaired, not as proof that the configuration and application now agree.
Check both disappearance and restoration
Use two separate acceptance cases. First, the interface-disabled configuration should compile without the obsolete peripheral dependency while preserving the shared behavior that remains required. Second, if the product supports enabling that interface again, regenerate the enabled configuration and check that there is one intended implementation of each moved function and callback.
The second case catches a subtle repair mistake: copying a function into an application file while leaving another generated or restored definition behind. Review the source list and symbols rather than resolving a duplicate definition with arbitrary exclusions. The repository should make the correct owner obvious to the next engineer.
Where practical, exercise the retained service through its remaining transport or test harness. A successful formatter unit test cannot verify a board interface, but it can show that an interface removal did not erase unrelated formatting behavior. State the evidence narrowly and keep board-level acceptance separate.
Hand over the removal rule
Include the reviewed configuration change, removed-file inventory, relocated implementations, and expected disabled/enabled behavior in the change record. A useful review question is: which application responsibility was preserved, which was intentionally removed, and where is each decision visible?
Finish with a fresh generation of the accepted configuration and a clean firmware build. This is a proposed gate, not a passed result. Its purpose is specific: retiring a CubeMX peripheral should retire only that peripheral’s responsibilities, without accidentally deleting the sole container for application logic the product still needs.