-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
ports SAMD and RP2: Fix allocation of UART buffers. #16884
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Code size report:
|
Slight tangent but the extra byte ringbuf uses for "tracking" (I had to dig to find out what on earth that was for) really makes a royal mess of this code. (Even bigger tangent) It also suggests some invocations of micropython/ports/esp8266/modespnow.c Line 183 in 3823aeb
|
It this a comment about the +/-1 byte is tedious (which I agree), or are you saying that the code is wrong? Edit: There have always been complaints by users, that they get a buffer size of N-1, when N was requested. |
I think it's right, but at a glance it's not easy to tell. The unrelated esp example looks wrong, but the whole thing is so contrived it's difficult to reason about. |
78bc092
to
50698ce
Compare
That said there's right and then there's correct. I don't think: Also any code that tries to consume a (I appreciate you've inherited this wart 😬) |
Technically it looks correct to me. The symbols Edit: I could have used another variable in the UART object with the buffer lengths, but wanted to avoid these extra RAM bytes to be consumed. |
Aha that's the piece of the puzzle I was missing. Thank you. |
FWIW the "other" kind of ringbuffer that avoids the tracking byte is used & discussed in a couple of places and is quite elegant, but comes with a restriction that the size must be a x^2, ie 16, 32, 64, 128 etc. You can no longer have an arbitrary size.
On a related note, I did add the +1 behind the scenes in #9458 when the user requests a 16byte buffer it'll allocate a 17byte array for use to avoid the confusion. If the user passes in a pre-allocated buffer though this isn't possible, so they get -1 size. I tried to address this in the docs on the function. It turns out though the +1 is kinda inefficient in many cases, due to the gc allocation blocks in micropython. If the user asks for 16byte and get given a 17byte buffer behind the scenes, well micropython will have allocated two blocks in gc which are typically 16byte blocks - so 32bytes will be consumed for that 16/17byte ringbuffer. Implementation details... |
50698ce
to
d140327
Compare
I added separate symbols holding the API related size of rxbuf and txbuf instead of using the size data field of the ring buffer. For RP2, this is simply a better coding style. For SAMD this is as well needed because depending on the setting for bits a data item uses 1 or 2 bytes in the ring buffer. Then the separate rxbuf and txbuf size symbols are not affected by the bits size. |
Thank you, and agreed. Soooo much easier to get my head 'round should I ever end up spelunking this code for bugs (fingers crossed). Looks like that's ~+16 bytes over the original fix. |
The buffer was be reset on every call to uart.init(). If no sizes were given, the buffer was set to the default size 256. That made problems e.g. with PPP. This commit fixes it, keeping the buffer size if not deliberately changed and allocating new buffers only if the size was changed. Signed-off-by: robert-hh <[email protected]>
The buffer was be reset on every call to uart.init(). If no sizes were given, the buffer was set to the default size 256. That made problems e.g. with PPP. This commit fixes it, keeping the buffer size if not deliberately changed and allocating new buffers only if the size was changed. Cater for changes of the bits value, which requires a change to the buffer size. Signed-off-by: robert-hh <[email protected]>
Signed-off-by: robert-hh <[email protected]>
d140327
to
4dfee50
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fix looks good, thanks!
(I split out the samd loopback bug fix to a separate commit.)
Thank you very much. |
Summary
The UART buffers were reset on every call to uart.init(). If no sizes were given, the buffers ere set to the default size 256. That made problems e.g. with PPP.
This PR fixes it, keeping the buffer size if not deliberately changed and allocating new buffers only if the size was changed.
Fix a subtle problem of the SAMD port where the board would lock up in same UART loopback mode, if rxbuf is full and not emptied. Then sending of the data does not complete.
Testing