Skip to content

fix: use offsetof for config checksum CRC range#329

Open
zekaizer wants to merge 1 commit into
hrvach:mainfrom
zekaizer:fix/config-crc-padding
Open

fix: use offsetof for config checksum CRC range#329
zekaizer wants to merge 1 commit into
hrvach:mainfrom
zekaizer:fix/config-crc-padding

Conversation

@zekaizer
Copy link
Copy Markdown

Summary

  • Use offsetof(config_t, checksum) instead of sizeof(config_t) - sizeof(uint32_t) to compute the CRC range in load_config() and save_config()

Problem

sizeof(config_t) - sizeof(uint32_t) assumes checksum occupies the last 4 bytes of the struct with no trailing padding. This holds today on ARM Cortex-M0+ because the current config_t layout happens to have 4-byte alignment.

However, screensaver_t contains uint64_t fields (idle_time_us, max_time_us), which give output_t an 8-byte alignment requirement on some ABIs. If config_t is extended with fields that break the current alignment (e.g., adding uint8_t fields before checksum), the compiler inserts tail padding after checksum, making sizeof(config_t) - 4 > offsetof(config_t, checksum).

When this happens, the CRC range includes the checksum field itself (and padding bytes), causing load_config() to always fail validation and silently reset config to defaults on every boot — even after a successful save_config().

Fix

Replace sizeof(config_t) - sizeof(uint32_t) with offsetof(config_t, checksum), which always computes the exact byte range before the checksum field regardless of struct padding.

Testing

Verified on RP2040 hardware (DeskHop PCB v1.1):

  • save_config() → flash verify OK → simulated load_config() CRC matches
  • Config persists across reboots

Test plan

  • Firmware builds without warnings on arm-none-eabi-gcc
  • Config save/load verified on hardware
  • No functional change for current upstream config_t layout (offsetof == sizeof - 4)

🤖 Generated with Claude Code

sizeof(config_t) - sizeof(uint32_t) does not reliably point
to the checksum field when the compiler adds tail padding
(e.g., due to uint64_t alignment in output_t). This causes
CRC mismatch on load, silently resetting config to defaults.

Use offsetof(config_t, checksum) to compute the exact CRC
range regardless of struct padding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

1 participant