[{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003e\u003cspan\u003eMany of TinyUSB's targets are small parts where the USB stack shares limited flash and RAM with the application. Every byte TinyUSB uses is a byte the user can't.\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan\u003eThat makes memory footprint a core concern for the project, and a hard one to keep track of. A change in a shared driver might add 80 bytes on one port and 400 on another, and nobody builds every board locally before opening a PR. Without tooling, growth can pile up unnoticed across hundreds of boards, and tracking down where it came from means digging through map files and rebuilding old commits.\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan\u003eMemBrowse gives TinyUSB visibility into its memory footprint on every commit, so these changes are caught in the PR instead of weeks later. When something does grow, you can see exactly where the bytes went, which makes memory footprint investigation a breeze.\u003c/span\u003e\u003c/p\u003e\n\u003ch2\u003e\u003cspan\u003eWhat MemBrowse does\u003c/span\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cspan\u003eMemBrowse runs as a step in your CI, on GitHub Actions or GitLab CI. After each build it reads the ELF, the linker script (for memory region limits) and optionally the map file (to attribute symbols to libraries). Each pull request gets a memory report comment showing how flash and RAM changed per target. Each target gets a history on the dashboard. Any change can be broken down by memory region, section and symbol, so you can see exactly what a commit added or removed and where it came from.\u003c/span\u003e\u003c/p\u003e\n\u003ch2\u003e\u003cspan\u003eHow TinyUSB uses it\u003c/span\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cspan\u003eTinyUSB's GitHub Actions workflow already builds every example for every board. MemBrowse runs on all of those builds, more than 2,100 of them, and posts a memory report on each PR.\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n        \u003ch2\u003e\u003cspan\u003eExample: TinyUSB PR #3574\u003c/span\u003e\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://github.com/hathach/tinyusb/pull/3574\"\u003e\u003cspan\u003ePR #3574\u003c/span\u003e\u003c/a\u003e\u003cspan\u003e added board support for Nordic's new nRF54LM20 DK. The title only mentions the new board, but part of the change landed in code shared with other Nordic boards.\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003e\u003cspan\u003eThe MemBrowse report on the PR showed the effect. Eight of the ten biggest changes were examples on the Adafruit CLUE, an existing board built on Nordic's older nRF52840. Each grew by about 1.4 KB of flash and 136 bytes of RAM, up to 21% on the board_test example.\u003c/span\u003e\u003c/p\u003e\n      \n\n\n\n\n\n","metadata":{}},{"element_type":"image_url","content":"https://membrowse.com/screenshots/1_pr3574_report.png","metadata":{"alt":"TinyUSB PR3574 MemBrowse report","caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n        \u003cp\u003e\u003cstrong id=\"docs-internal-guid-29f23f21-7fff-bbae-2c7e-d9030585fdf1\"\u003e\u003cspan\u003eThe build diff view shows why. The PR added UART receive support to the shared nRF board code: 14 new symbols such as nrfx_uarte_rx_buffer_set and nrfx_uarte_rx_abort, plus a 64-byte receive FIFO and a 64-byte transmit cache in RAM.\u003c/span\u003e\u003c/strong\u003e\u003c/p\u003e\n      \n\n\n\n","metadata":{}},{"element_type":"image_url","content":"https://membrowse.com/screenshots/2_pr3574_symbols.png","metadata":{"alt":"MemBrowse - commit diff page","caption":""}},{"element_type":"text","content":"\n  \n  \n        \u003cp\u003e\u003cstrong id=\"docs-internal-guid-69e2ef77-7fff-bef2-0e85-e85793471500\"\u003e\u003cspan\u003eThe dashboard shows the same change over time. On the CLUE's audio_4_channel_mic example, the flash line has a single jump of 1.40 KB at commit 3cfe7a0, the merge of PR #3574. Clicking that point leads straight to the symbol breakdown above.\u003c/span\u003e\u003c/strong\u003e\u003c/p\u003e\n      \n\n","metadata":{}},{"element_type":"image_url","content":"https://membrowse.com/screenshots/3_clue_history.png","metadata":{"alt":"TinyUSB MemBrowse memory trend page","caption":""}},{"element_type":"text","content":"\n        \u003cp\u003e\u003cspan\u003eThe growth may well have been intended. Either way, it was visible in the PR before the merge, and it stays on record afterwards, down to the function.\u003c/span\u003e\u003c/p\u003e\n\u003ch2\u003e\u003cspan\u003eTry it\u003c/span\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cspan\u003eMemBrowse is free for public repos and works with GitHub Actions and GitLab CI.\u003c/span\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan\u003eTinyUSB dashboard: \u003c/span\u003e\u003ca href=\"https://membrowse.com/public/hathach/tinyusb\"\u003e\u003cspan\u003ehttps://membrowse.com/public/hathach/tinyusb\u003c/span\u003e\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cspan\u003eGitHub Action: \u003c/span\u003e\u003ca href=\"https://github.com/membrowse/membrowse-action\"\u003e\u003cspan\u003ehttps://github.com/membrowse/membrowse-action\u003c/span\u003e\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://membrowse.com\"\u003e\u003cspan\u003emembrowse.com\u003c/span\u003e\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n      ","metadata":{}}]