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!!