Hello everyone! This is my first post on the forum and it is about the NVS pagesize.
A bit of context, I am developing an application that has the following parts: LoRaWAN stack, BLE GATT services, Power Management, UART, I2C and NVS.
To this I need to add DFU through BLE using SMP and MCUboot.
All this using VSCode with NCS 2.1.0 and Zephyr 3.1.99.
The thing is that the nRF52832 has 512Kb of flash and it is a bit tight in flash space to reach 2 image-slots, the MCUboot and a Storage partition. So I used a "pm_static.yml" to change a bit the sizes of each part like the following:
app: address: 0xc200 end_address: 0x45000 region: flash_primary size: 0x38e00 mcuboot: address: 0x0 end_address: 0xc000 placement: before: - mcuboot_primary region: flash_primary size: 0xc000 mcuboot_pad: address: 0xc000 end_address: 0xc200 placement: align: start: 0x1000 before: - mcuboot_primary_app region: flash_primary size: 0x200 mcuboot_primary: address: 0xc000 end_address: 0x45000 orig_span: &id001 - app - mcuboot_pad region: flash_primary sharers: 0x1 size: 0x39000 span: *id001 mcuboot_primary_app: address: 0xc200 end_address: 0x45000 orig_span: &id002 - app region: flash_primary size: 0x38e00 span: *id002 mcuboot_secondary: address: 0x45000 end_address: 0x7e000 placement: after: - mcuboot_primary align: start: 0x1000 region: flash_primary share_size: - mcuboot_primary size: 0x39000 nvs_storage: address: 0x7e000 end_address: 0x80000 placement: align: start: 0x1000 before: - end region: flash_primary size: 0x2000 sram_primary: address: 0x20000000 end_address: 0x20010000 region: sram_primary size: 0x10000
The original (default by the partition manager) storage partition size is 0x6000 (24Kb), wich is a lot more than my application really needs.
So I tried to lower this partition size to 0x1000 (4Kb) and give 10Kb to each image-slot (or mcuboot_primary and mcuboot_secondary, as this is their name). In doing so I started to see an error in the initialization of the NVS like this:
invalid address 0x00080ff8:8
This means that the NVS is trying to enter somewhere outside of the flash space. This is because the pagesize has a size of 4Kb wich is equal to the sector_size, and the problem is that the NVS sector_count has to be minimum 2.
Investigating in the documentation I have found the following: NVS Documentation
Where it explicitly says: "the pagesize is determined by the hardware".
So, where does all of this collide....
When initializing the NVS it makes a comparison between the sector_size and the pagesize:
/* check that sector size is a multiple of pagesize */
rc = flash_get_page_info_by_offs(fs->flash_device, fs->offset, &info);
if (rc) {
LOG_ERR("Unable to get page info");
return -EINVAL;
}
if (!fs->sector_size || fs->sector_size % info.size) {
LOG_ERR("Invalid sector size");
return -EINVAL;
}
If the pagesize is always 4Kb (definde "by hardware") and cannot be changed, sector_size needs to be equal to pagesize and sector_count needs to be minimum of 2 so the storage partition is as small as possible leaving more room for the application images.
As I showed in the first code snippet of the "pm_static.yml" at the moment the storage partition has a size of 8Kb and the application images have a size of 228Kb. And this is what the compiler drops as error:
c:/ncs/toolchains/v2.1.0/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/10.3.0/../../../../arm-zephyr-eabi/bin/ld.exe: region `FLASH' overflowed by 796 bytes
So finally my question is this:
Is there a way to reduce the "pagesize" to something like 1Kb? which is a lot for what my application actually uses from the NVS.
Or maybe I'm approaching this from the wrong angle?
Any comments are welcome!!