Abstract UART class for creating virtual UARTs? #9263
Replies: 8 comments 21 replies
-
This would also allow to use i2c UARTs and the like transparently. |
Beta Was this translation helpful? Give feedback.
-
I have exactly the same requirement today. I have created a library to handle the cmux protocol with MicroPython. It is working fine multiplexing the channels but trying to figure out how to emulate the UART for ppp. Did you find any solution for it? |
Beta Was this translation helpful? Give feedback.
-
I too have wanted to multiplex multiple streams over USB / UART and was thinking of using cmux to help. I'd be quite interested in seeing your library for this @ThinkTransit ! As a building block for this I created a python interface over the C ringbuffer to act as a controlled size fast/efficient version of bytesio with all the correct interfaces to work as a "real" python stream for things like asyncio.Streamwriter. I'm not sure about the PPP module but I know asyncio.Streamwriter relies on select behind the scenes which itself uses the C I know io.BytesIO also provides this functionality, however I don't think it's possible to subclass it, see here for related issue: #10402 But when I was trying to use my ringbuffer I would use two instances of it, one of them wrapped in a asyncio.Streamwriter and the other in asyncio.Streamreader and then pass them both to microwebsrv or similar as separate read/write streams like a "socket pair". I didn't think of usages like this where there's expected to be a single object like a UART which essentially has two streams behind the scenes. I'm really not sure if it's currently possible to emulate this sort of "stream pair" object in micropython, maybe I need to extend my ringbuffer class to support dual streams... |
Beta Was this translation helpful? Give feedback.
-
Oh, actually yes you can implement it completely in python! Here's an example: https://github.com/micropython/micropython/blob/master/examples/bluetooth/ble_uart_repl.py Essentially you need to subclass |
Beta Was this translation helpful? Give feedback.
-
The I weirdly needed almost the exact same thing at work yesterday, a mock UART for testing application code with. Similarly though what I actually needed wasn't a UART but a stream that could be passed into Looking into all this I see there's really no docs that go into detail about how this is made in practice, nor how to implement it in python... I'd like to write some, maybe later. I've updated my ringbuffer mr a bit and made this library to work with it: micropython/micropython-lib#907 That uses a bi-directional pair of ringbuffers to make an object that will work exactly like a virtual UART. But yeah, needs my ringbuffer pr. It's harder to emulate with BytesIO because you need to manage the read/write pointers manually with that like you have @nestorld The virtual UART class you've got might work correctly though if you change it to subclass |
Beta Was this translation helpful? Give feedback.
-
I've always wanted to do this, but unfortunately I haven't had the time. |
Beta Was this translation helpful? Give feedback.
-
network.PPP finally calls the following function to get the ppp data. Using python to override the write/read method is invalid. micropython/extmod/machine_uart.c STATIC const mp_stream_p_t uart_stream_p = {
.read = mp_machine_uart_read,
.write = mp_machine_uart_write,
.ioctl = mp_machine_uart_ioctl,
.is_text = false,
}; |
Beta Was this translation helpful? Give feedback.
-
Finally, I got it working! The key part is the protocol class used in line 194 of micropython/extmod/machine_uart.c, in the same section pointed by @lbuque:
and defined in micropython/py/stream.h:
and:
That is only present when the class is directly defined in C, and not adding the read/write/ioctl methods to a class in Python. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I want to create some virtual UARTs in micropython. Is there an abstract class I can extend or do I need to build something from the ground up?
The background to this is I want to try and implement UART multiplexing, where multiple UARTS can be used over a single physical UART. The data is sent in frames and addressed to the relevant virtual UART as outlined in a 3GPP standard. This is for communicating with modems where by one virtual UART can be used for AT commands and another for PPP traffic etc..
Ideally the virtual UARTs would be seamless so they would work with existing micropython modules like ppp and stream reader etc.
Any thoughts, crazy idea?
Beta Was this translation helpful? Give feedback.
All reactions