How to store config file on microcontroller?
You treat the “config file” as a small block of non-volatile data and give it a safe place + a simple protocol, rather than literally thinking “files on a PC”. Here’s a practical way to do it.
1. Decide where to store the config
Depending on your MCU and how big the config is:
-
Internal EEPROM (AVR, some STM8, some STM32, PIC, etc.)
-
Easiest: byte-wise writes, survives reset and power off.
-
Great for a few bytes to a few kB (baud rate, calibration constants, flags…).
-
-
Internal Flash (most Cortex-M, ESP32, etc.)
-
Use one or more flash pages/sectors reserved for config.
-
You must erase a whole page before rewriting; limited erase cycles (often 10k–100k).
-
Common for MCUs without EEPROM (STM32, nRF, etc.).
-
-
External non-volatile memory
-
I²C/SPI EEPROM/FRAM/Flash if you need more space or don’t want to wear out internal flash.
-
FRAM is great when you want many writes (wear basically not a problem).
-
-
SD card / filesystem
-
Overkill for tiny configs but nice if you want human-editable text/JSON.
-
Needs a FAT/exFAT or littlefs library and a bigger MCU.
-
For typical small configs (<< 1kB): internal EEPROM or a dedicated flash page is the sweet spot.
2. Design a simple config “schema”
Think of your config as a small struct with a header:
Why the header is important:
-
magic – lets you detect “there’s actually config here” vs erased memory.
-
version – lets you change the struct in future firmware and still handle old configs.
-
length – sanity check, and can help if you add future fields.
-
crc – detect corruption (power loss mid-write, noise, etc.).
3. Overall flow at startup
Pseudo-logic your firmware should follow:
And to save:
nvm_read / nvm_write / nvm_erase_sectorare your platform-specific functions
(HAL drivers, EEPROM library, or direct register code).
4. Flash vs EEPROM specifics
If you use internal EEPROM
-
You can usually write byte-by-byte or word-by-word.
-
But: limited write cycles → don’t save on every little change.
-
Strategy:
-
Only call
config_save()when user changes something or from a “settings” menu. -
Optionally rotate location (“wear leveling”) when writing frequently.
-
Example (Arduino AVR):
If you use internal Flash (no EEPROM)
-
Pick one page (or two for safety) close to the end of flash and never put code there.
-
Flash rules:
-
Erase sets all bits to 1.
-
You can only change 1 → 0 by writing.
-
To go back to 1, you must erase the whole page.
-
-
Typical pattern:
-
erase page → write whole config structwhenever saving. -
To avoid frequent erases, you can:
-
Buffer changes in RAM and only save occasionally.
-
Use two slots and ping-pong between them:
-
Write new config to slot B, mark it valid.
-
Next time, write to slot A, etc.
-
On boot, pick the most recent valid slot.
-
-
-
5. Make it robust against power loss
You don’t want a half-written config to brick your settings. Easy tricks:
-
Two copies / ping-pong
-
Slot A & slot B.
-
Each has its own header, CRC, and maybe a “sequence number”.
-
When saving:
-
Find the older slot.
-
Erase & write the new config there, with
sequence++.
-
-
On boot:
-
Check both slots; pick the one with valid CRC and highest sequence.
-
-
-
Validity flag written last
-
Keep
magicor avalidfield as the last thing written. -
On read: if CRC is OK but
validis unset, treat as invalid.
-
With these patterns, a power cut during save just leaves you with the previous valid config.
6. If config should be human-editable (text, JSON…)
Sometimes you want a config that a user edits on PC:
-
Add an SD card or USB mass storage.
-
Use a text format (INI/JSON) and a file system (FAT, littlefs, etc.).
-
On boot:
-
Try to open
/config.txtor/config.json -
Parse it and fill your
Configstruct. -
If missing or invalid → defaults and (optionally) regenerate the file.
-
This is heavier (code size, RAM, libraries) but nice for complex systems like ESP32, STM32 with RTOS, etc.
7. Summary: a “template” you can adapt
-
Pick storage: EEPROM, flash page, or external NVM.
-
Define a Config struct with
magic + version + length + crc + payload. -
On boot:
read → validate → fallback to defaults if invalid. -
On change:
config_save()that rewrites the struct to NVM, respecting flash/EEPROM rules. -
For reliability: use two slots / ping-pong and CRC to survive power loss.
.jpg)
评论
发表评论