rust-exercises icon indicating copy to clipboard operation
rust-exercises copied to clipboard

Add buffered UART exercise

Open jonathanpallant opened this issue 10 months ago • 2 comments

I'd like to see an exercise for building a fully buffered, interrupt-driven UART, as an extension to the UART exercise.

We should probably do this on a Cortex-M target, as interrupt handling on Cortex-R is not as well handled (the interrupt controllers aren't standardised, and we don't have good drivers for them).

  1. Make a blocking UART (existing exercise)
  2. Make it global (needs to be Mutex<RefCell<Option<Uart>>>)
  3. Give it a one-byte buffer (an Option<u8>) and make it interrupt driven.
  4. Replace the Option<u8> with some kind of heapless queue
  5. Use a bbqueue and DMA the data into the UART rather than copying a byte at a time
  6. Set up a second UART

QEMU probably makes sense (assuming the simulated UART has working interrupts and FIFO and DMA)

jonathanpallant avatar Jan 13 '25 16:01 jonathanpallant

MPS3-AN505 (Cortex-M33) apparently has a PL081 DMA controller and five CMSDK UARTs

MPS3-AN536 (Dual Cortex-R52) should also work

jonathanpallant avatar Jan 13 '25 16:01 jonathanpallant

QEMU doesn't do flow control though (although I think that's OK): https://github.com/qemu/qemu/blob/e8aa7fdcddfc8589bdc7c973a052e76e8f999455/hw/char/cmsdk-apb-uart.c#L344

jonathanpallant avatar Jan 13 '25 16:01 jonathanpallant

We have https://rust-exercises.ferrous-systems.com/latest/book/realtime-v8r-uart to make the UART global, and we have https://github.com/ferrous-systems/rust-training/tree/main/example-code/qemu-common/src/cmsdk_uart, which walks through the various implementations. That's probably enough.

jonathanpallant avatar May 20 '25 10:05 jonathanpallant