Skip to content

Change Adafruit Register libraries to use a library wide shared buffer - #63

Merged
tannewt merged 3 commits into
adafruit:mainfrom
grgrant:move-to-module-level-alloc
Aug 18, 2026
Merged

Change Adafruit Register libraries to use a library wide shared buffer#63
tannewt merged 3 commits into
adafruit:mainfrom
grgrant:move-to-module-level-alloc

Conversation

@grgrant

@grgrant grgrant commented Aug 12, 2026

Copy link
Copy Markdown

@tannewt asked me to explore the possibility of a shared module wide buffer to reduce the memory footprint of the use of many register descriptors in a driver library. I also tried allocate on first use and it didn't make any improvement. The class-wide and module-wide shared buffer had the same improvement. I think module-wide would show improvement if any library used more than one non-inheritied class (like Struct and UnaryStruct) -- ROBits inherits RWBits. I'm not using any libraries that use both Struct and UnaryStruct.

I just want to say upfront that the savings was not as much as I had hoped for in libraries like MAX1704x, BMP5xx and TMP117. I'm perfectly OK if you want to just approve PR #62 which changes i2c_struct.UnaryStruct to allocate on init like all the other libraries. None of these are a must merge.

This module wide buffer change supercedes #62 and moves all buffers to a single bytearray buffer extended to the largest needed by the various register accessors.

Here are the measured savings I found:

I2C Struct/Bit(s)

Class Current Module Buffer Saving
UnaryStruct 74* 58 22%
RO/WBits 116 84 28%
RO/WBit 90 58 36%

Register Struct/Bit(s)

Class Instance Module Buffer Saving
UnaryStruct 80 48 40%
RO/WBits 154 112 27%
RO/WBit 96 64 33%

I've been running these versions on 4-5 of my temperature/humidity/CO2 sensors using MAX1704x and TMP117 (i2c_struct/Bit(s)) and also BMP5xx (register_Bit(s)) for about a week with no issues.

Also tagging @FoamyGuy as he was the author of the register_Struct/Bits versions

@tannewt tannewt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One reorganization suggestion. I do think the slower execution is worth the saved memory.

Comment thread adafruit_register/i2c_bit.py Outdated
@grgrant
grgrant marked this pull request as draft August 15, 2026 20:48
@grgrant

grgrant commented Aug 15, 2026

Copy link
Copy Markdown
Author

@tannewt

Instead of putting this in each file, put it in __init__.py and import it in each. That way all of these files will share it and the implementation will only be in one place.

Done. I've tested this library for three days with 3-TMP117/119s, 2-BMP5xx, 3-MAX1704x and 1 DS3231 (for the bcd libraries). I don't have anything that uses i2c_struct_array.

If CircuitPython ever goes multi-threaded the shared buffer might cause an issue

Edit: While working with another library I realized I should have used mem.alloc rather than mem_free to compare library growth. So numbers below are redone to be more correct.

New AdafruitRegister footprint savings for libraries

Here are the savings over the currently deployed production version of the library:

library prd new lib wide Savings
BMP5xx 15488 14720 768
TMP117 12832 12816 16
MAX1704x 9952 9936 16
DS3231 9056 8928 128

Footprint measurement methodology

In most cases even if the prod/new values changed the savings stayed the same. I'm using prod and new library files compiled with the same mpy-cross-macos-10.2.1-arm64. I also found that I needed to disable everything settings.toml, boot.py, repl.py and code.py and reboot the MCU from time to time to get the most consistent numbers. I used the following snippet (changed for each library) pasted to REPL and then did a soft reset between -- unless the number was really weird and then I'd do a microcontroller.reset.

# Fixed version to use gc.mem_alloc()
# BMP5xx
import gc
gc.collect()
b=gc.mem_alloc()
import adafruit_bmp5xx
gc.collect()
a=gc.mem_alloc()
b-a

Old mem_free wrong numbers for posterity

Interesting that the savings were the same except for TMP117.

library prd new lib wide Savings
BMP5xx 24416 23648 768
TMP117 21824 21760 64
MAX1704x 2096 2080 16
DS3231 1104 976 128

@grgrant
grgrant marked this pull request as ready for review August 15, 2026 23:17
@grgrant grgrant changed the title Change Adafruit Register libraries to do module wide allocation of byte array Change Adafruit Register libraries to use a library wide shared buffer Aug 15, 2026
@grgrant
grgrant requested a review from tannewt August 17, 2026 03:13
@tannewt

tannewt commented Aug 17, 2026

Copy link
Copy Markdown
Member

I don't see the new changes. I suspect you forgot to push them.

@grgrant

grgrant commented Aug 17, 2026

Copy link
Copy Markdown
Author

@tannewt

I don't see the new changes. I suspect you forgot to push them.

I pushed them on Friday and then briefly changed to draft while I did some memory footprint anomaly checks. Then I changed it back to ready for review. Here is the link from above of the Friday Push: 17117b0

I did a second push -- that appeared empty -- today and got a new CI set of tests.

@tannewt tannewt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@tannewt
tannewt merged commit 04051d2 into adafruit:main Aug 18, 2026
1 check passed
@grgrant
grgrant deleted the move-to-module-level-alloc branch August 19, 2026 00:54
adafruit-adabot pushed a commit to adafruit/Adafruit_CircuitPython_Bundle that referenced this pull request Sep 9, 2026
Updating https://github.com/adafruit/Adafruit_CircuitPython_Register to 1.13.0 from 1.12.1:
  > Merge pull request adafruit/Adafruit_CircuitPython_Register#63 from grgrant/move-to-module-level-alloc

Updating https://github.com/adafruit/Adafruit_CircuitPython_Bundle/circuitpython_library_list.md to NA from NA:
  > Added the following libraries: Adafruit_CircuitPython_TMF8801
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants