dakejahl opened a new issue, #20244: URL: https://github.com/apache/nuttx/issues/20244
### Is your feature request related to a problem? Please describe. On STM32H7, `stm32_dmachannel()` hands out the first free stream on the requested controller and returns NULL when none are left. The DMAMUX allocators in `common/stm32` and the H5 GPDMA driver work the same way. Nothing checks at build time how many streams a configuration can hold at once, so a board that enables DMA on more peripherals than a controller has streams builds cleanly and fails at run time, depending on start order: - Of the serial drivers on these parts, only H5's checks the handle (it returns `-EBUSY`). On H7, `up_dma_setup()` passes it straight to `stm32_dmasetup()`, which dereferences it. - The H7 SPI driver only `DEBUGASSERT`s the handle. Its comment says `stm32_dmachannel()` blocks until a stream is free, which is F4/F7 behavior. - Whichever driver asks last loses. A UART that is opened only in some configurations (a telemetry or GPS port) can take the last stream and break a driver that worked on the bench. Downstream in PX4 this has shown up as a board boot-looping with DMA on three UARTs, and as RC input dying once DShot telemetry took a stream (PX4/PX4-Autopilot#26112, PX4/PX4-Autopilot#24573, PX4/PX4-Autopilot#24920). Each time, the fix was turning off UART DMA by hand. Boards track the budget in comments, and the comments drift. ### Describe the solution you'd like 1. A compile-time budget per DMA controller. Every input is already an integer macro: the `CONFIG_*` DMA enables, the board's `DMAMAP_*` values, and `DMAMAP_CONTROLLER()`. A per-family header can sum the streams each enabled driver holds (serial RX/TX, SPI RX/TX, ADC, DAC, QSPI) per controller and `#error` when a sum exceeds the controller's stream count. No runtime cost and no API change. 2. A `board.h` hook, e.g. `BOARD_DMA1_NRESERVED`, for streams allocated by board or out-of-tree code, and the per-controller sums exported as macros so out-of-tree code can add its own consumers to the check. PX4 allocates DMA outside NuttX for DShot and for its IO coprocessor link. 3. Drivers return `-EBUSY` from setup when `stm32_dmachannel()` returns NULL, as the H5 serial driver already does, instead of dereferencing it. This is independent of 1 and 2 and can land first. The count is conservative: a UART with DMA enabled counts even if nothing opens it, because whether it opens is usually runtime configuration. A board that deliberately overcommits needs an opt-out, so a Kconfig option could make the check a warning instead of an error. I can do the H7 implementation if this direction is acceptable. The same approach applies to the other DMAMUX families and would fit in `arch/arm/src/common/stm32` alongside the STM32 port unification (#19004). ### Describe alternatives you've considered - Recording the owner in `stm32_dmachannel()` and dumping per-controller usage through procfs. Useful for debugging, but it still finds the problem only at run time. - Encoding a fixed stream in `DMAMAP_*` on DMAMUX parts, as on F4/F7. This makes allocation deterministic, but changes the map encoding and the allocator, and still needs a check that no two consumers share a stream. - Falling back to interrupt-driven I/O when allocation fails. The H7 serial DMA ops assume a valid handle and the per-port DMA channel fields are `const`, so this is a larger change than failing the open. ### Verification - [X] I have verified before submitting the report. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
