From e68b668c4d02b78cb28d72d9c2b52477c2ebeaad Mon Sep 17 00:00:00 2001 From: bateske Date: Thu, 8 Oct 2026 16:00:35 -0700 Subject: [PATCH] Libraries: link CHGfx, CHGame and CHSd from archives A developer using board package 0.3.0 for the sound engine and the buttons only, with their own display code, found every sketch that includes CHGame.h carrying CHGfx's 8 KB framebuffer, its chunk buffers and its SRAM converters. Arduino links a library's objects whole, and CHGfx.cpp's strong DMA1_Channel3_IRQHandler replaces the core's weak default, so the vector table keeps the handler and the handler keeps the framebuffer, drawing or not. dot_a_linkage=true in the three library.properties links each library from an archive, where an object is pulled in only when something calls into it. The audio-only sketch takes 352 B of static RAM instead of 9,712 B. The two hooks the libraries override (that handler, and osSystickHandler in Audio.cpp) sit in the same objects as gfx_begin() and audio::begin(), so a sketch that uses a feature always gets them. All 20 games' and 3 apps' release images are byte-identical with and without the flag; plain riscv-none-embed-ar indexes GCC 8's slim LTO objects, so the -Os -flto builds need no gcc-ar. The simulator does not read the flag. Recorded in board/CHANGELOG.md (Unreleased), platform/README.md, the CHGame README's RAM note and CHGame.h's header comment. Co-Authored-By: Claude Fable 5.1 --- platform/README.md | 16 ++++++++++++++++ platform/board/CHANGELOG.md | 13 +++++++++++++ .../arduino/CHGame/libraries/CHGame/README.md | 5 ++++- .../CHGame/libraries/CHGame/library.properties | 1 + .../arduino/CHGame/libraries/CHGame/src/CHGame.h | 5 ++++- .../CHGame/libraries/CHGfx/library.properties | 1 + .../CHGame/libraries/CHSd/library.properties | 1 + 7 files changed, 40 insertions(+), 2 deletions(-) diff --git a/platform/README.md b/platform/README.md index 42838166..84a7a268 100644 --- a/platform/README.md +++ b/platform/README.md @@ -211,6 +211,22 @@ list builds stayed byte-identical. Not yet run on a board. ## Changes since the copies were taken +- 2026-10-08: the three libraries link from archives (`dot_a_linkage=true` + in CHGfx's, CHGame's and CHSd's `library.properties`). A developer using + only `audio::` and the buttons, with their own display code, found every + sketch that includes `CHGame.h` carrying CHGfx's framebuffer: Arduino + links a library's objects whole, and the DMA interrupt handler in + `CHGfx.cpp` (a strong `DMA1_Channel3_IRQHandler` over the core's weak + one) keeps `gfx_fb`, the chunk buffers and the SRAM converters with it. + From an archive an object is linked only when something calls into it, + so that sketch is 352 B of RAM instead of 9,712 B, and the two hooks the + libraries override (that handler, and `osSystickHandler` in `Audio.cpp`) + sit in the same objects as `gfx_begin()` and `audio::begin()`, so a + sketch that uses the feature always gets them. Plain `riscv-none-embed-ar` + indexes GCC 8's slim LTO objects, so the `-Os -flto` builds need no + `gcc-ar`. All 23 examples' release images are byte-identical + (board/CHANGELOG.md, "Unreleased"). The simulator does not read the flag. + - 2026-10-07: an API reference for every library the board package ships. The public headers of CHGame, CHGfx, CHSd, SPI, Wire and EEPROM carry Doxygen comments (a brief, every parameter, the return value, and the diff --git a/platform/board/CHANGELOG.md b/platform/board/CHANGELOG.md index c1b56b16..a6987024 100644 --- a/platform/board/CHANGELOG.md +++ b/platform/board/CHANGELOG.md @@ -14,6 +14,19 @@ file as the GitHub release notes. function, class and constant of CHGame, CHGfx, CHSd, SPI, Wire and EEPROM, documented in their headers with Doxygen. +### Changed + +- **CHGfx, CHGame and CHSd link from archives** (`dot_a_linkage=true` in + their `library.properties`), so an object of theirs is linked only when + the sketch calls into it. Arduino otherwise links every object of an + included library whole, and CHGfx's DMA interrupt handler (its + `DMA1_Channel3_IRQHandler` replaces the core's weak default) kept the 8 KB + framebuffer, the 1 KB chunk buffers and the SRAM converters alive in any + sketch that included `CHGame.h`, drawing with it or not. A sketch that + uses `audio::` and `chgame_readButtons()` and draws through its own code + now takes 352 B of static RAM instead of 9,712 B. The 20 games' and the + 3 apps' release images are byte-identical. (Reported by a developer.) + ### Fixed - **EEPROM no longer writes the CH32X035's option bytes.** The library is diff --git a/platform/board/arduino/CHGame/libraries/CHGame/README.md b/platform/board/arduino/CHGame/libraries/CHGame/README.md index 1c65d859..67e5e813 100644 --- a/platform/board/arduino/CHGame/libraries/CHGame/README.md +++ b/platform/board/arduino/CHGame/libraries/CHGame/README.md @@ -99,7 +99,10 @@ include just the one it needs, e.g. ``. what fills it. Unused parts of the library cost nothing (link-time optimisation drops them). - **RAM is 18,416 B** for statics, plus a 2 KB stack. The framebuffer takes - 8 KB of it. + 8 KB of it when the sketch draws with CHGfx. A sketch that includes + `CHGame.h` for its sound, buttons or saves and draws through its own code + does not carry it: the libraries link from archives, so an object is + linked only when something calls into it. - **`static const` tables of 8 bytes or less** are copied into SRAM by this core's link script; sound steps use `AUDIO_STEPS` to stay in flash. - **Integer maths only.** Soft-float costs kilobytes and frame rate. diff --git a/platform/board/arduino/CHGame/libraries/CHGame/library.properties b/platform/board/arduino/CHGame/libraries/CHGame/library.properties index 17b035f9..554b72f9 100644 --- a/platform/board/arduino/CHGame/libraries/CHGame/library.properties +++ b/platform/board/arduino/CHGame/libraries/CHGame/library.properties @@ -9,3 +9,4 @@ url=https://github.com/bateske/CHGame architectures=ch32v includes=CHGame.h depends=CHGfx +dot_a_linkage=true diff --git a/platform/board/arduino/CHGame/libraries/CHGame/src/CHGame.h b/platform/board/arduino/CHGame/libraries/CHGame/src/CHGame.h index 8774a9bf..2c44df5c 100644 --- a/platform/board/arduino/CHGame/libraries/CHGame/src/CHGame.h +++ b/platform/board/arduino/CHGame/libraries/CHGame/src/CHGame.h @@ -21,7 +21,10 @@ /// | chgame/Debug.h | dbg:: the serial debug protocol the simulator and the tools drive a game through (CHGAME_DEBUG builds) | /// | chgame/Config.h | the library's build switches (CHGAME_DEBUG ...) | /// -/// The casino games in this library's examples are built from these. +/// The casino games in this library's examples are built from these. Only +/// what a sketch calls is linked: CHGfx's framebuffer and DMA handler come +/// with the first drawing call, not with the include, so a sketch that uses +/// this library for its sound, buttons or saves alone pays nothing for them. /// chgame/Sizzle.h (particles, banners, floating texts) is not included /// here: a game configures and compiles it itself. #pragma once diff --git a/platform/board/arduino/CHGame/libraries/CHGfx/library.properties b/platform/board/arduino/CHGame/libraries/CHGfx/library.properties index 29a7904d..1bee94c6 100644 --- a/platform/board/arduino/CHGame/libraries/CHGfx/library.properties +++ b/platform/board/arduino/CHGame/libraries/CHGfx/library.properties @@ -8,3 +8,4 @@ category=Display url=https://github.com/bateske/CHGame architectures=ch32v includes=CHGfx.h +dot_a_linkage=true diff --git a/platform/board/arduino/CHGame/libraries/CHSd/library.properties b/platform/board/arduino/CHGame/libraries/CHSd/library.properties index 1d4faa78..1d1fbf12 100644 --- a/platform/board/arduino/CHGame/libraries/CHSd/library.properties +++ b/platform/board/arduino/CHGame/libraries/CHSd/library.properties @@ -9,3 +9,4 @@ url=https://github.com/bateske/CHGame architectures=ch32v includes=Fat.h,SdSpi.h depends= +dot_a_linkage=true