Replies: 6 comments 20 replies
-
Thanks for working on this. A central registry for reserving DMA channels is a good idea to allow disparate drivers to work together. However, I worry that a useful DMA abstraction isn't worth the complexity. For example, your proposed API doesn't cover
In particular, your go-wspr example doesn't seem to fit your API because it uses control block chaining of DMA channels. Even if the API was sufficient, go-wspr is already platform-specific (because of pio) so won't gain much from a generic DMA API. I propose adding just the central channel registry and add efficient bulk transfer API to each device (I2C, UART etc.) and driver, backed by the platform's DMA. That's a smaller API, and can serve as inspiration for a generic DMA abstraction later on.
I'm not convinced by this argument. Goroutines are supposed to be lightweight enough that APIs can block and let the caller decide whether to introduce concurrency through extra goroutines and channel. With an async API you need a way to expose interrupt-based waiting, otherwise the IsBusy+Gosched loop probably (much of) eats the efficiency gains of using DMA in the first place. |
Beta Was this translation helpful? Give feedback.
-
It may be that it is out of scope to have three levels of control block chaining as in go-wspr, but it does seem worthwhile exposing enough power to implement a ping-pong buffering scheme. The pacing is also pretty important. Not sure how easy that is to abstract. In the meantime, even go-wspr would have benefited from an arbiter. The structures returned could well have supported some simple copy operations, but I would still want a pointer to the underlying registers in that structure somehow. The arbiter I used was copied pretty much verbatim from the PIO library. So should that be the first step? |
Beta Was this translation helpful? Give feedback.
-
Regarding a more advanced API, I can definitely see the difficulty in generalizing the special purpose capabilities of platforms like the Pico but aside from fast memory to memory copies, I don't see much way to make use of DMA without at least pacing and progress indicators and probably some kind of completion indicator. The completion indicator is pretty easy to made idiomatic if we just provide a channel that closes when the operation completes or a callback, but I don't see any way to handle the more advanced capabilities since they so often depend on using DMA to transfer control blocks. |
Beta Was this translation helpful? Give feedback.
-
How do you fit the nRF52xxx etc DMA API in this proposal? They do not have a central DMA peripheral, instead every peripheral has some registers where you can set the buffer start, buffer size, etc. I don't see how the proposed API could work for those chips. |
Beta Was this translation helpful? Give feedback.
-
Here is a different API, that I've implemented for two different chips and have made to work with a driver (st7789) and shown to actually work in the real world. (The code is old now, I'd need to rebase it quite a bit to make work again): #3985 Why do we need such a complex API when a simple |
Beta Was this translation helpful? Give feedback.
-
If we do end up going the
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Background
TinyGo has long had non-standard DMA APIs for interacting with peripherals on MCUs. One example which has received attention recently is the implementation on the PIO library here:
Due to these current events I have begun researching DMA APIs by asking my coworkers about DMA (many thanks to @ydnatag) and finding out interesting things about Linux's DMA API which is documented here:
Proposal details
While having a DMA engine like Linux's would be useful I believe it is too early to work our way into something of the sort. I'd argue we can eventually get there (if we really want that) by building a common low level DMA channel API that is shared in part by Linux's DMA Engine. A couple things about the API:
dma_request_channel
. This is how piolib also does it and it seems to have worked for our users. Below is an API for a lightweight DMAArbiter implementation much like the one in piolib.DMAScatterGatherConfig
type and corresponding function callProposed DMA Channel API
Proposed DMA channel Arbiter API
@tdunning @aykevl @deadprogram
Beta Was this translation helpful? Give feedback.
All reactions