Repository navigation
RingIO is limited to 64kB #16560
Copy link
Copy link
Open
Labels
enhancementFeature requests, new feature implementationsFeature requests, new feature implementationspy-coreRelates to py/ directory in sourceRelates to py/ directory in source
Description
Activity
- addedenhancementFeature requests, new feature implementationsFeature requests, new feature implementations
on Jan 9, 2025 stephanelsmith commented
on Jan 29, 2025 SponsorContributorMore actionsJust jumping into RingIO, already want to make mega ringIO buffers for sampling adc!
The cheapest way to achieve that could be something like this:
diff --git i/py/ringbuf.c w/py/ringbuf.c index 5f77271a0..0f43194f5 100644 --- i/py/ringbuf.c +++ w/py/ringbuf.c @@ -42,7 +42,7 @@ int ringbuf_peek16(ringbuf_t *r) { if (r->iget == r->iput) { return -1; } - uint32_t iget_a = r->iget + 1; + ringbuf_size_overflow_t iget_a = r->iget + 1; if (iget_a == r->size) { iget_a = 0; } @@ -52,15 +52,15 @@ int ringbuf_peek16(ringbuf_t *r) { return (r->buf[r->iget] << 8) | (r->buf[iget_a]); } -int ringbuf_put16(ringbuf_t *r, uint16_t v) { - uint32_t iput_a = r->iput + 1; +int ringbuf_put16(ringbuf_t *r, ringbuf_size_t v) { + ringbuf_size_overflow_t iput_a = r->iput + 1; if (iput_a == r->size) { iput_a = 0; } if (iput_a == r->iget) { return -1; } - uint32_t iput_b = iput_a + 1; + ringbuf_size_overflow_t iput_b = iput_a + 1; if (iput_b == r->size) { iput_b = 0; } diff --git i/py/ringbuf.h w/py/ringbuf.h index d3c0f4601..96faeb917 100644 --- i/py/ringbuf.h +++ w/py/ringbuf.h @@ -32,11 +32,18 @@ #include "py/mpconfig.h" +#ifndef ringbuf_size_t +#define ringbuf_size_t uint16_t +#endif +#ifndef ringbuf_size_overflow_t +#define ringbuf_size_overflow_t uint32_t +#endif + typedef struct _ringbuf_t { uint8_t *buf; - uint16_t size; - uint16_t iget; - uint16_t iput; + ringbuf_size_t size; + ringbuf_size_t iget; + ringbuf_size_t iput; } ringbuf_t; // Static initialization: @@ -75,7 +82,7 @@ static inline int ringbuf_peek(ringbuf_t *r) { } static inline int ringbuf_put(ringbuf_t *r, uint8_t v) { - uint32_t iput_new = r->iput + 1; + ringbuf_size_overflow_t iput_new = r->iput + 1; if (iput_new >= r->size) { iput_new = 0; } @@ -98,8 +105,8 @@ static inline size_t ringbuf_avail(ringbuf_t *r) { static inline void ringbuf_memcpy_get_internal(ringbuf_t *r, uint8_t *data, size_t data_len) { // No bounds / space checking is performed here so ensure available size is checked before running this // otherwise data loss or buffer overflow can occur. - uint32_t iget = r->iget; - uint32_t iget_a = (iget + data_len) % r->size; + ringbuf_size_overflow_t iget = r->iget; + ringbuf_size_overflow_t iget_a = (iget + data_len) % r->size; uint8_t *datap = data; if (iget_a < iget) { // Copy part of the data from the space left at the end of the buffer @@ -114,8 +121,8 @@ static inline void ringbuf_memcpy_get_internal(ringbuf_t *r, uint8_t *data, size static inline void ringbuf_memcpy_put_internal(ringbuf_t *r, const uint8_t *data, size_t data_len) { // No bounds / space checking is performed here so ensure free size is checked before running this // otherwise data loss or buffer overflow can occur. - uint32_t iput = r->iput; - uint32_t iput_a = (iput + data_len) % r->size; + ringbuf_size_overflow_t iput = r->iput; + ringbuf_size_overflow_t iput_a = (iput + data_len) % r->size; const uint8_t *datap = data; if (iput_a < iput) { // Copy part of the data to the end of the buffer @@ -130,7 +137,7 @@ static inline void ringbuf_memcpy_put_internal(ringbuf_t *r, const uint8_t *data // Note: big-endian. No-op if not enough room available for both bytes. int ringbuf_get16(ringbuf_t *r); int ringbuf_peek16(ringbuf_t *r); -int ringbuf_put16(ringbuf_t *r, uint16_t v); +int ringbuf_put16(ringbuf_t *r, ringbuf_size_t v); int ringbuf_get_bytes(ringbuf_t *r, uint8_t *data, size_t data_len); int ringbuf_put_bytes(ringbuf_t *r, const uint8_t *data, size_t data_len);
Not sure if this should end up in core or not, though.
- addedpy-coreRelates to py/ directory in sourceRelates to py/ directory in source
on May 26, 2026
Metadata
Metadata
Assignees
Labels
enhancementFeature requests, new feature implementationsFeature requests, new feature implementationspy-coreRelates to py/ directory in sourceRelates to py/ directory in source
Description
Discussion: #9458 (comment)
Currently RingIO is limited to creating ring buffers of 64kB by the use of the following
uint16_tvariables inringbuf.h:The suggestion is to change these to
uint32_tto allow for >64kB ringbuffers. This would only be useful in ports with more than 64kB of heap available, so it may be worthwhile having different versions for different ports.Or maybe the extra 6 bytes is acceptable across all ports for the sake of simplicity/consistency?
I note that other structures (like bytearray) don't have a 64kB limit, so this would seem to be some sort of precedent for changing the limit.
Code Size
This change would add 6 bytes to RAM usage whenever RingIO is invoked
Implementation
I hope the MicroPython maintainers or community will implement this feature
Code of Conduct
Yes, I agree