QUERY · ISSUE
OpenMV Feature: Multi-level init/deinit system
enhancement
Description
We think it might help us with missing init/deinit issues that we have to deal with after every update, plus it's a good overall cleanup.
https://github.com/micropython/micropython/pull/18424
Code Size
No response
Implementation
I hope the MicroPython maintainers or community will implement this feature
Code of Conduct
Yes, I agree
CANDIDATE · PULL REQUEST
py/runtime: Multi-Level Init/Deinit System for Embedded Ports (RFC/PoC).
py-core
Summary
This PR introduces a multi-level initialization and deinitialization system for embedded MicroPython ports. The system uses GNU linker sections to automatically collect and order init/deinit function pointers, eliminating the need to manually maintain initialization sequences in main.c.
Example usage:
MP_INIT_REGISTER(driver, 00, timer_init0);
MP_DEINIT_REGISTER(driver, 00, timer_deinit);
...
// Calls all your init functions
mp_init_run_level(MP_INIT_DRIVER);
Key Benefits
- Makes init order dependencies (or lack thereof) explicit and consistent across ports.
- Optional via config: Ports can keep their old init/deinit behavior.
- Allows ordering init/deinit functions within a level, so can easily replicate exact current behavior.
- Modules/drivers can register their init/deinit. Alternatively, we could extern & register all init/deinit functions in a port-specific file (e.g.,
stm32/mpinit_register.c), allowing ports even more flexibility and customization, but this kinda defeats the consistency point. - Improves readability: replace 100s of duplicate lines with a few calls.
- New ports get correct initialization automatically.
- New driver/service/etc.. won't require updating
main.cin every port that uses it.
Testing
Didn't do any actual testing, since this is just an RFC/PoC, but here's what one section looks like:
grep "\.mp_init_driver\." build-*/firmware.map
*(SORT_BY_NAME(.mp_init_driver.*))
.mp_init_driver.00.readline_init0
.mp_init_driver.01.pin_init0
.mp_init_driver.02.extint_init0
.mp_init_driver.03.timer_init0
.mp_init_driver.05.pyb_usb_init0
.mp_init_driver.09.servo_init
Challenges and risks
- There's no common linker script between boards, let alone ports, so to enable this in stm32 port, for example, we'd have to go through every board and make sure its linker script includes the common script.
- Very few init functions accept args, we could either make their state/arg extern/global, add wrappers or just call them manually.
- This is a big change that may break things, however, not every port needs to enable it. So we could start small, then migrate more and more ports.