Skip to content

feat(storage): auto-detect layout changes and re-initialize storage#765

Open
Raymond8196 wants to merge 1 commit intoHaoboGu:mainfrom
Raymond8196:feat/layout-hash-storage-pr
Open

feat(storage): auto-detect layout changes and re-initialize storage#765
Raymond8196 wants to merge 1 commit intoHaoboGu:mainfrom
Raymond8196:feat/layout-hash-storage-pr

Conversation

@Raymond8196
Copy link
Contributor

Summary
When users change layers, rows, cols, or encoder count in keyboard.toml and reflash, the old stored keymap in flash persists and causes incorrect behavior (e.g., Vial showing wrong layer count). Currently the only workaround is manually setting clear_storage = true for one flash cycle, which is error-prone and hard to discover.
This PR replaces the unused BUILD_HASH mechanism with a layout structure hash that automatically detects incompatible changes and re-initializes storage.

Changes

  • rmk/src/config/mod.rs: Add layout_hash: u32 field to StorageConfig (defaults to 0)
  • rmk-macro/src/codegen/chip/flash.rs: Compute FNV-1a hash of (rows, cols, layers, num_encoder) at compile time and pass it through StorageConfig
  • rmk/src/storage/mod.rs:
    • Rename LocalStorageConfig.build_hash to layout_hash
    • Enable the previously commented-out hash comparison in check_enable()
    • Add diagnostic log when layout hash mismatch is detected
    • Remove unused BUILD_HASH import

Design Decisions

  • Only structural dimensions are hashed (rows, cols, layers, num_encoder) — not keymap content. Changing a key binding within the same dimensions won't wipe Vial customizations. Users who want to force new defaults can still use clear_storage = true or clear_layout = true.
  • Backward compatible: use_rust examples use ..Default::default() which sets layout_hash: 0. On first boot after upgrade, the old build_hash value won't match, triggering a one-time re-initialization — correct migration behavior.
  • Why not fix BUILD_HASH? It included chrono::Local::now(), changing every build. A content-based hash of layout dimensions is the right granularity.
@github-actions
Copy link

Binary Size Report

use_config/nrf52832_ble

 text data bss dec hex	filename 313940 5104 33800 352844 5624c	rmk-nrf52832 
Diff
 FILE SIZE VM SIZE -------------- -------------- +0.0% +419 [ = ] 0 .debug_info +0.0% +97 [ = ] 0 .debug_line +0.1% +96 [ = ] 0 .debug_ranges +0.0% +12 +0.0% +12 .text [ = ] 0 +0.0% +8 .bss +0.1% +1 [ = ] 0 .defmt -7.8% -4 [ = ] 0 [Unmapped] -0.0% -8 [ = ] 0 .debug_aranges -0.0% -51 [ = ] 0 .strtab -0.2% -60 [ = ] 0 .debug_frame -0.1% -64 [ = ] 0 .symtab -0.0% -160 [ = ] 0 .debug_str -0.7% -264 -0.7% -264 .rodata -0.3% -1.53Ki [ = ] 0 .debug_loc -0.0% -1.52Ki -0.1% -244 TOTAL 

use_config/nrf52840_ble

 text data bss dec hex	filename 350424 5104 49232 404760 62d18	rmk-nrf52840 
Diff
 FILE SIZE VM SIZE -------------- -------------- +0.0% +491 [ = ] 0 .debug_info +0.0% +32 [ = ] 0 .symtab +0.0% +32 +0.0% +32 .text +0.0% +18 [ = ] 0 .strtab [ = ] 0 +0.0% +16 .bss +0.0% +16 [ = ] 0 .debug_aranges +0.1% +1 [ = ] 0 .defmt -0.0% -12 [ = ] 0 .debug_frame -40.6% -26 [ = ] 0 [Unmapped] -0.0% -147 [ = ] 0 .debug_line -0.0% -174 [ = ] 0 .debug_loc -0.6% -264 -0.6% -264 .rodata -0.1% -272 [ = ] 0 .debug_ranges -0.0% -747 [ = ] 0 .debug_str -0.0% -1.03Ki -0.1% -216 TOTAL 

use_config/nrf52840_ble_split

 text data bss dec hex	filename 429004 6428 45688 481120 75760	central text data bss dec hex	filename 276152 5792 26696 308640 4b5a0	peripheral 
Diff

Central Diff

 FILE SIZE VM SIZE -------------- -------------- +0.1% +535 [ = ] 0 .debug_loc +0.0% +174 [ = ] 0 .debug_info +0.1% +128 [ = ] 0 .debug_ranges +0.0% +12 [ = ] 0 .debug_line [ = ] 0 +0.0% +8 .bss -0.0% -4 -0.0% -4 .text -0.0% -16 [ = ] 0 .debug_aranges -34.5% -19 [ = ] 0 [Unmapped] -0.2% -76 [ = ] 0 .debug_frame -0.0% -78 [ = ] 0 .strtab -0.1% -128 [ = ] 0 .symtab -0.0% -176 [ = ] 0 .debug_str -0.6% -268 -0.6% -268 .rodata +0.0% +84 -0.1% -264 TOTAL 

Peripheral Diff

 FILE SIZE VM SIZE -------------- -------------- +0.0% +503 [ = ] 0 .debug_info +0.1% +243 [ = ] 0 .strtab +0.0% +237 [ = ] 0 .debug_str +0.2% +232 [ = ] 0 .debug_ranges +0.1% +96 [ = ] 0 .symtab +0.0% +93 [ = ] 0 .debug_line +0.1% +32 [ = ] 0 .debug_aranges +0.1% +32 [ = ] 0 .debug_frame +32% +13 [ = ] 0 [Unmapped] -0.0% -4 -0.0% -4 .text -0.8% -268 -0.8% -268 .rodata -0.1% -513 [ = ] 0 .debug_loc +0.0% +696 -0.1% -272 TOTAL 

use_rust/nrf52840_ble_split

 text data bss dec hex	filename 432184 6428 51408 490020 77a24	central text data bss dec hex	filename 274132 5232 25440 304804 4a6a4	peripheral 
Diff

Central Diff

 FILE SIZE VM SIZE -------------- -------------- +0.0% +511 [ = ] 0 .debug_info +0.0% +316 [ = ] 0 .debug_loc +0.1% +128 [ = ] 0 .symtab +0.0% +111 [ = ] 0 .strtab +0.0% +96 +0.0% +96 .text +0.0% +70 [ = ] 0 .debug_line +0.1% +52 [ = ] 0 .debug_frame +0.1% +48 [ = ] 0 .debug_aranges [ = ] 0 +0.0% +16 .bss +21% +10 [ = ] 0 [Unmapped] -0.0% -10 [ = ] 0 .debug_str -0.6% -268 -0.6% -268 .rodata -0.1% -320 [ = ] 0 .debug_ranges +0.0% +744 -0.0% -156 TOTAL 

Peripheral Diff

 FILE SIZE VM SIZE -------------- -------------- +0.0% +339 [ = ] 0 .debug_info +0.2% +288 [ = ] 0 .debug_ranges +0.0% +127 [ = ] 0 .debug_str +0.1% +118 [ = ] 0 .strtab +0.1% +116 [ = ] 0 .debug_line +0.0% +76 +0.0% +76 .text -4.5% -2 [ = ] 0 [Unmapped] -0.0% -8 [ = ] 0 .debug_aranges -0.2% -48 [ = ] 0 .debug_frame -0.1% -64 [ = ] 0 .symtab -0.8% -268 -0.8% -268 .rodata -0.1% -498 [ = ] 0 .debug_loc +0.0% +176 -0.1% -192 TOTAL 

use_config/pi_pico_w_ble

 text data bss dec hex	filename 595440 0 54784 650224 9ebf0	rmk-pi-pico-w 
Diff
 FILE SIZE VM SIZE -------------- -------------- +0.1% +224 [ = ] 0 .debug_ranges +0.0% +206 [ = ] 0 .debug_info +0.1% +112 [ = ] 0 .symtab [ = ] 0 +0.0% +16 .bss +19% +10 [ = ] 0 [Unmapped] -0.0% -6 [ = ] 0 .debug_line -0.1% -28 [ = ] 0 .debug_frame -0.0% -64 -0.0% -64 .text -0.0% -74 [ = ] 0 .strtab -0.0% -265 [ = ] 0 .debug_str -0.1% -268 -0.1% -268 .rodata -0.4% -3.33Ki [ = ] 0 .debug_loc -0.0% -3.48Ki -0.0% -316 TOTAL 

use_config/pi_pico_w_ble_split

 text data bss dec hex	filename 627260 0 61312 688572 a81bc	central text data bss dec hex	filename 493076 0 41924 535000 829d8	peripheral 
Diff

Central Diff

 FILE SIZE VM SIZE -------------- -------------- +0.0% +311 [ = ] 0 .debug_loc +0.3% +240 [ = ] 0 .symtab +0.0% +205 [ = ] 0 .debug_info +0.0% +51 [ = ] 0 .debug_line +0.0% +36 +0.0% +36 .text [ = ] 0 +0.0% +16 .bss +12% +6 [ = ] 0 [Unmapped] -0.1% -28 [ = ] 0 .debug_frame -0.0% -42 [ = ] 0 .strtab -0.1% -248 [ = ] 0 .debug_ranges -0.1% -264 -0.1% -264 .rodata -0.0% -411 [ = ] 0 .debug_str -0.0% -144 -0.0% -212 TOTAL 

Peripheral Diff

 FILE SIZE VM SIZE -------------- -------------- +0.1% +683 [ = ] 0 .debug_loc +0.0% +495 [ = ] 0 .debug_info +0.1% +210 [ = ] 0 .strtab +0.0% +190 [ = ] 0 .debug_str +0.3% +144 [ = ] 0 .symtab +0.0% +106 [ = ] 0 .debug_line +0.0% +68 +0.0% +68 .text +0.0% +8 [ = ] 0 .debug_aranges +7.3% +4 [ = ] 0 [Unmapped] -0.1% -264 -0.1% -264 .rodata +0.0% +1.61Ki -0.0% -196 TOTAL 

use_rust/pi_pico_w_ble_split

 text data bss dec hex	filename 628072 0 61632 689704 a8628	central text data bss dec hex	filename 493576 0 41924 535500 82bcc	peripheral 
Diff

Central Diff

 FILE SIZE VM SIZE -------------- -------------- +0.1% +1.10Ki [ = ] 0 .debug_loc +0.0% +391 [ = ] 0 .debug_info +0.2% +384 [ = ] 0 .debug_ranges +0.1% +224 +0.1% +224 .text +0.2% +176 [ = ] 0 .symtab [ = ] 0 +0.0% +16 .bss +20% +12 [ = ] 0 [Unmapped] -0.0% -15 [ = ] 0 .debug_line -0.1% -28 [ = ] 0 .debug_frame -0.0% -54 [ = ] 0 .strtab -0.0% -265 [ = ] 0 .debug_str -0.1% -268 -0.1% -268 .rodata +0.0% +1.65Ki -0.0% -28 TOTAL 

Peripheral Diff

 FILE SIZE VM SIZE -------------- -------------- +0.0% +496 [ = ] 0 .debug_info +0.1% +405 [ = ] 0 .debug_loc +0.0% +190 [ = ] 0 .debug_str +0.1% +180 [ = ] 0 .strtab +0.0% +88 +0.0% +88 .text +0.0% +12 [ = ] 0 .debug_line +0.0% +8 [ = ] 0 .debug_aranges -26.3% -15 [ = ] 0 [Unmapped] -0.0% -16 [ = ] 0 .symtab -0.1% -264 -0.1% -264 .rodata -0.3% -504 [ = ] 0 .debug_ranges +0.0% +580 -0.0% -176 TOTAL 

use_config/rp2040

 text data bss dec hex	filename 133788 0 15844 149632 24880	rmk-rp2040 
Diff
 FILE SIZE VM SIZE -------------- -------------- +0.3% +956 [ = ] 0 .debug_loc +0.0% +459 [ = ] 0 .debug_info +0.3% +208 [ = ] 0 .debug_ranges +0.1% +195 [ = ] 0 .debug_line +0.1% +148 +0.1% +148 .text +0.1% +63 [ = ] 0 .strtab [ = ] 0 +0.1% +16 .bss +31% +12 [ = ] 0 [Unmapped] +0.1% +8 [ = ] 0 .debug_aranges +0.0% +4 [ = ] 0 .debug_frame +0.6% +2 [ = ] 0 .defmt -0.0% -16 [ = ] 0 .symtab -0.0% -99 [ = ] 0 .debug_str -1.5% -260 -1.5% -260 .rodata +0.1% +1.64Ki -0.1% -96 TOTAL 

use_config/rp2040_split

 text data bss dec hex	filename 145364 0 16872 162236 279bc	central text data bss dec hex	filename 23568 56 2492 26116 6604	peripheral 
Diff

Central Diff

 FILE SIZE VM SIZE -------------- -------------- +0.0% +382 [ = ] 0 .debug_info +0.1% +180 +0.1% +180 .text +0.1% +155 [ = ] 0 .debug_line +0.1% +80 [ = ] 0 .debug_ranges +0.1% +70 [ = ] 0 .strtab [ = ] 0 +0.1% +16 .bss +0.0% +16 [ = ] 0 .symtab +26% +12 [ = ] 0 [Unmapped] +0.0% +8 [ = ] 0 .debug_aranges +0.0% +4 [ = ] 0 .debug_frame +0.5% +2 [ = ] 0 .defmt -0.0% -91 [ = ] 0 .debug_str -1.3% -260 -1.3% -260 .rodata -0.1% -302 [ = ] 0 .debug_loc +0.0% +256 -0.0% -64 TOTAL 

Peripheral Diff

 FILE SIZE VM SIZE -------------- -------------- +0.0% +207 [ = ] 0 .debug_str +0.0% +36 [ = ] 0 .debug_info +0.1% +8 [ = ] 0 .debug_aranges +2.4% +1 [ = ] 0 [Unmapped] +0.0% +252 [ = ] 0 TOTAL 

use_rust/rp2040_split

 text data bss dec hex	filename 143960 0 16476 160436 272b4	central text data bss dec hex	filename 24288 56 2756 27100 69dc	peripheral 
Diff

Central Diff

 FILE SIZE VM SIZE -------------- -------------- +0.0% +343 [ = ] 0 .debug_info +0.2% +136 [ = ] 0 .debug_ranges +0.1% +132 +0.1% +132 .text +0.1% +117 [ = ] 0 .debug_line +0.1% +82 [ = ] 0 .strtab +0.2% +80 [ = ] 0 .symtab [ = ] 0 +0.1% +16 .bss +0.0% +8 [ = ] 0 .debug_aranges +9.4% +5 [ = ] 0 [Unmapped] +0.0% +4 [ = ] 0 .debug_frame +0.5% +2 [ = ] 0 .defmt -0.0% -91 [ = ] 0 .debug_str -0.1% -198 [ = ] 0 .debug_loc -1.3% -260 -1.3% -260 .rodata +0.0% +360 -0.1% -112 TOTAL 

Peripheral Diff

 FILE SIZE VM SIZE -------------- -------------- +0.0% +207 [ = ] 0 .debug_str +0.0% +36 [ = ] 0 .debug_info +0.1% +8 [ = ] 0 .debug_aranges +1.8% +1 [ = ] 0 [Unmapped] +0.0% +252 [ = ] 0 TOTAL 

use_config/stm32f1

 text data bss dec hex	filename 55840 24 8064 63928 f9b8	rmk-stm32f1 
Diff
 FILE SIZE VM SIZE -------------- -------------- [ = ] 0 [ = ] 0 TOTAL 

use_config/stm32f4

 text data bss dec hex	filename 134416 320 16564 151300 24f04	rmk-stm32f4 
Diff
 FILE SIZE VM SIZE -------------- -------------- +0.0% +296 [ = ] 0 .debug_info +0.3% +112 [ = ] 0 .symtab +0.2% +52 [ = ] 0 .debug_frame +0.2% +40 [ = ] 0 .debug_aranges +0.0% +36 [ = ] 0 .debug_loc [ = ] 0 +0.1% +16 .bss +23% +12 [ = ] 0 [Unmapped] +0.2% +1 [ = ] 0 .defmt -0.0% -3 [ = ] 0 .strtab -0.2% -144 [ = ] 0 .debug_ranges -0.1% -146 [ = ] 0 .debug_line -0.1% -168 -0.1% -168 .text -0.0% -224 [ = ] 0 .debug_str -1.4% -260 -1.4% -260 .rodata -0.0% -396 -0.3% -412 TOTAL 

use_config/stm32h7

 text data bss dec hex	filename 96696 264 10676 107636 1a474	rmk-stm32h7 
Diff
 FILE SIZE VM SIZE -------------- -------------- [ = ] 0 [ = ] 0 TOTAL 
@HaoboGu
Copy link
Owner

HaoboGu commented Mar 15, 2026

This doesn't solve the issue. It's rare that the col/row/num_layer/num_encoder changes, what's more common is to update the keymap/config. Currently if the layout changes, the keyboard will auto re-initialize the storage and reboot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants