cesanta / mongoose-os

Mongoose OS - an IoT Firmware Development Framework. Supported microcontrollers: ESP32, ESP8266, CC3220, CC3200, STM32F4, STM32L4, STM32F7. Amazon AWS IoT, Microsoft Azure, Google IoT Core integrated. Code in C or JavaScript.
https://mongoose-os.com
Other
2.48k stars 430 forks source link

Advanced features for mgos_uart_read(); #547

Closed Harvie closed 3 years ago

Harvie commented 3 years ago

I've modified mgos_uart read in such way that it can do following new stuff:

1.) Peek into the buffer without removing data from it 2.) Read data at the end rather than at the beginning.

use case: I am implementing driver for complex serial protocol, which highly benefits from having such features. otherwise i would need to regulary copy all the data to another buffer and do the same thing there.

rojer commented 3 years ago

sorry, i don't think this belongs in the UART API. transfer data into your buffer and then do advanced processing there.

Harvie commented 3 years ago

I've generalized the code, so it can be usefull for more people than just me. What i actualy need is to be able to read the latest byte received by the uart for needs of colision detection and bus arbitration... copying all the data out of input buffer in colision detection handling code would be very ugly solution in my opinion. I will have to copy the data to external buffer anyway for packets to be parsed, but i need to handle bus on time without copying unknown amounts of data during the arbitration phase. Can we please discuss this further?

Also note that this kind of API is not very uncommon. Eg.: https://www.arduino.cc/reference/en/language/functions/communication/serial/peek/

Harvie commented 3 years ago

I know this might sound kinda weird, but i was thinking about it a lot and i believe it actually makes sense to have such feature.

rojer commented 3 years ago

i still don't think this needs to be in an api. just slurp the data into your own buffer and process it however you see fit.

Harvie commented 3 years ago

Thing is the collision detection of the ebus protocol requires me to check received byte after sending each byte to see if i got it back. (RX and TX lines are tied together and several devices can transmit at once). So if i don't see my TX byte in RX buffer immediately, i have to stop the transmission and try to resend later. While keeping up with precise timing. I don't want to do unnecesarry data copying after each byte i send as this is possibility to screw the timing if there are some other data in the buffer...

Harvie commented 3 years ago

Possibly even causing dynamic allocation to kick in during the transmission...

DrBomb commented 3 years ago

You can access the mbuffers directly anyways. You could just implement the tools you just did on your own library and call it a day

kzyapkov commented 3 years ago

what @DrBomb said

Harvie commented 3 years ago

You can access the mbuffers directly anyways

@DrBomb are these exported so i can access them from other modules? can i consider this a stable api?

rojer commented 3 years ago

yeah, you shouldn't be poking at internal mbufs, this interface is not guaranteed.

Harvie commented 3 years ago

That is why i initialy proposed API which can be guaranteed...

rojer commented 3 years ago

there's no need, imo. copy data out into your buffer. mbuf (there's even a helper for it) or otherwise, and then do whatever you want with it. trying to reuse internal buffers or push more logic into the driver is an optimization that is premature in this case, given that the data rate is usually pretty low, so the extra copy is no big deal.

Harvie commented 3 years ago

I've just found that there is overlap in requirements of the bus i use and rs485 bus, which is already supported by esp-idf:

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/uart.html#overview-of-rs485-specific-communication-options

I need to supress loopback and be able to receive status of collision detection per-byte. eg.:

if i TX some byte, i need to discard that byte from RX buffer and if different byte was received instead the TX byte i need to raise collision flag in some variable... That should be possible in esp-idf, we just need to make it accessible through mongoose uart.