Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

About the NVS Partition Generator (IDFGH-14513) #15279

Open
KaeLL opened this issue Jan 24, 2025 · 14 comments
Open

About the NVS Partition Generator (IDFGH-14513) #15279

KaeLL opened this issue Jan 24, 2025 · 14 comments
Assignees
Labels
Status: In Progress Work is in progress

Comments

@KaeLL
Copy link
Contributor

KaeLL commented Jan 24, 2025

Why is the minimum partition size 12KiB? And given the following csv

key,type,encoding,value
test,namespace,,
test,data,u32,0

With K pages, why are pages [1,K - 1] generated with status Full even though they're empty?

Demonstration below

After running nvs_partition_gen.py generate nvs.csv nvs.bin 32768...

nvs_tool.py -i -f text nvs.bin
Page no. 0, Status: Full, Version: 2, CRC32: b9ba2d84, Page address: 0x0
 Entry state bitmap: fa ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
 000. Written, Namespace Index: 000, Type: uint8_t   , Span: 001, Chunk Index: 255, CRC32: 7e817bfa | test : 1
 001. Written, Namespace Index: 001, Type: uint32_t  , Span: 001, Chunk Index: 255, CRC32:   c5d00d | test : 0
 002. Empty
 ...
 125. Empty

Page no. 1, Status: Full, Version: 2, CRC32: 389f48a3, Page address: 0x1000
 Entry state bitmap: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
 000. Empty
 ...
 125. Empty

Page no. 2, Status: Full, Version: 2, CRC32: 6081e18b, Page address: 0x2000
 Entry state bitmap: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
 000. Empty
 ...
 125. Empty

Page no. 3, Status: Full, Version: 2, CRC32: e1a484ac, Page address: 0x3000
 Entry state bitmap: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
 000. Empty
 ...
 125. Empty

Page no. 4, Status: Full, Version: 2, CRC32: d0bcb3db, Page address: 0x4000
 Entry state bitmap: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
 000. Empty
 ...
 125. Empty

Page no. 5, Status: Full, Version: 2, CRC32: 5199d6fc, Page address: 0x5000
 Entry state bitmap: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
 000. Empty
 ...
 125. Empty

Page no. 6, Status: Full, Version: 2, CRC32:  9877fd4, Page address: 0x6000
 Entry state bitmap: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
 000. Empty
 ...
 125. Empty

Page Empty, Page address: 0x7000
 Entry state bitmap: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
 000. Empty
 ...
 125. Empty


Page no. 0 	CRC32: OK
Page no. 1 	CRC32: OK
Page no. 2 	CRC32: OK
Page no. 3 	CRC32: OK
Page no. 4 	CRC32: OK
Page no. 5 	CRC32: OK
Page no. 6 	CRC32: OK
Page Empty

Pages 1 to 6 statuses is Full.

@espressif-bot espressif-bot added the Status: Opened Issue is new label Jan 24, 2025
@github-actions github-actions bot changed the title About the NVS Partition Generator About the NVS Partition Generator (IDFGH-14513) Jan 24, 2025
@chegewara
Copy link
Contributor

espressif/esp-idf-nvs-partition-gen#12

@KaeLL
Copy link
Contributor Author

KaeLL commented Jan 25, 2025

@adokitkat care to chime in?

@adokitkat
Copy link
Collaborator

adokitkat commented Jan 26, 2025

Hello, thank you both for the report. I will be taking a look at it this week. It doesn't seem to affect the NVS when it is loaded by ESP-IDF from what I know, that's why it was in lower priority.

Also minimum (not recommended) partition size should be 4kiB? EDIT: It is 12kiB (3 pages), 4kiB is a size of 1 page.

@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Opened Issue is new labels Jan 26, 2025
@chegewara
Copy link
Contributor

Hi,
How is it possible it does not affect if full page can't be written anymore with new data? It is no longer useful.
In such case most of nvs partition is useless.

@igrr
Copy link
Member

igrr commented Jan 26, 2025

Just a note, the main use case for NVS partition generator is to create partitions with factory-programmed data or settings. Such factory settings partitions typically should never be written to, since if the partition gets corrupted, factory data may be lost. Therefore we weren't carefully testing this scenario when the generated NVS partition is further written to. And as @adokitkat mentioned, this bug didn't affect the case when the partition is read-only.

@chegewara
Copy link
Contributor

chegewara commented Jan 26, 2025

I understand that point of view, but factory settings may also be just a set of default values which can be changed by user.
In that case do we need separate nvs partition and to make code more complicated to select between default and user values?

Thanks

PS the partition still may be corrupted, because data can be altered, only problem is the empty pages are not usable

@adokitkat
Copy link
Collaborator

No, this is a bug in Python implementation of NVS partition generator and will be fixed.

@igrr
Copy link
Member

igrr commented Jan 26, 2025

In that case do we need separate nvs partition and to make code more complicated to select between default and user values?

Regardless of fixing this bug I think this (keeping values changed by the user in a separate partition) would be much more robust. If the partition gets corrupted, the device can still be factory reset and will maintain at least the factory defaults. If you start modifying the factory-programmed data directly, you risk not being able to recover the defaults should the partition get corrupted.

@chegewara
Copy link
Contributor

chegewara commented Jan 26, 2025

And now i understand why there was no response in my issue for 2 months.
It is not a bug/issue, the problem is i dont know what espressif team thought designing it and i am using it wrong.

@adokitkat
Copy link
Collaborator

adokitkat commented Jan 26, 2025

I modified nvsgen example, filled about 200 entires and this is the output from nvs_tool.py - ESP-IDF actually does use those pages marked as full (btw see their bitmaps are all ff, meaning they're empty), it just skips the first page which is marked full as well (it should be marked as active).

I think it doesn't matter much because it should still be able to use the unavailable free space in the first page when all other pages will be full in reality, it should move the content to another empty page making it active, while erasing the first full page - as you can see the 2nd page is now page 6 and properly used.

It is still a bug but it doesn't seem to affect the real capacity, that's why I said it was lower priority.

NVS tool output
> ./nvs_tool.py ~/esp/esp-idf/examples/storage/nvsgen/nvs3.img
Page no. 0, Status: Full, Version: 2, CRC32: b9ba2d84, Page address: 0x0
 Entry state bitmap: aa a8 aa fa ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 000. Written, Namespace Index: 000, Type: uint8_t   , Span: 001, Chunk Index: 255, CRC32:  750a909 | storage : 1
 001. Written, Namespace Index: 001, Type: uint8_t   , Span: 001, Chunk Index: 255, CRC32: 4351d44d | u8_key : 255
 002. Written, Namespace Index: 001, Type: int8_t    , Span: 001, Chunk Index: 255, CRC32: ac3521f8 | i8_key : -128
 003. Written, Namespace Index: 001, Type: uint16_t  , Span: 001, Chunk Index: 255, CRC32: 92787c98 | u16_key : 65535
 004. Erased , Namespace Index: 001, Type: uint32_t  , Span: 001, Chunk Index: 255, CRC32: 9f1661b6 | u32_key : 4294967295
 005. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 2e39873b | i32_key : -2147483648
 006. Written, Namespace Index: 001, Type: string    , Span: 008, Chunk Index: 255, CRC32: 7c05630a | str_key : Size=222, CRC32=8f66953b
      0x000  4c 6f 72 65 6d 20 69 70 73 75 6d 20 64 6f 6c 6f  72 20 73 69 74 20 61 6d 65 74 2c 20 63 6f 6e 73  Lorem ipsum dolo r sit amet, cons
      0x020  65 63 74 65 74 75 72 20 61 64 69 70 69 73 63 69  6e 67 20 65 6c 69 74 2e 0a 46 75 73 63 65 20 71  ectetur adipisci ng elit..Fusce q
      0x040  75 69 73 20 72 69 73 75 73 20 6a 75 73 74 6f 2e  0a 53 75 73 70 65 6e 64 69 73 73 65 20 65 67 65  uis risus justo. .Suspendisse ege
      0x060  73 74 61 73 20 69 6e 20 6e 69 73 69 20 73 69 74  20 61 6d 65 74 20 61 75 63 74 6f 72 2e 0a 50 65  stas in nisi sit  amet auctor..Pe
      0x080  6c 6c 65 6e 74 65 73 71 75 65 20 72 68 6f 6e 63  75 73 20 64 69 63 74 75 6d 20 73 6f 64 61 6c 65  llentesque rhonc us dictum sodale
      0x0a0  73 2e 0a 49 6e 20 6a 75 73 74 6f 20 65 72 61 74  2c 20 76 69 76 65 72 72 61 20 61 74 20 69 6e 74  s..In justo erat , viverra at int
      0x0c0  65 72 64 75 6d 20 65 67 65 74 2c 20 69 6e 74 65  72 64 75 6d 20 76 65 6c 20 64 75 69 2e 00 ff ff  erdum eget, inte rdum vel dui..ÿÿ
 014. Empty
 ...
 125. Empty

Page no. 6, Status: Active, Version: 2, CRC32:  9877fd4, Page address: 0x1000
 Entry state bitmap: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa ff ff ff ff ff ff ff ff ff ff ff ff ff
 000. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: ab7a8780 | new_key_124 : 42
 001. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 367566f6 | new_key_125 : 42
 002. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 4a14432d | new_key_126 : 42
 003. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: d71ba25b | new_key_127 : 42
 004. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 818f16ad | new_key_128 : 42
 005. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 1c80f7db | new_key_129 : 42
 006. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  b2dd373 | new_key_130 : 42
 007. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 96223205 | new_key_131 : 42
 008. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: ea4317de | new_key_132 : 42
 009. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 774cf6a8 | new_key_133 : 42
 010. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 12815c68 | new_key_134 : 42
 011. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 8f8ebd1e | new_key_135 : 42
 012. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: f3ef98c5 | new_key_136 : 42
 013. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 6ee079b3 | new_key_137 : 42
 014. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 3874cd45 | new_key_138 : 42
 015. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: a57b2c33 | new_key_139 : 42
 016. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 902cdc69 | new_key_140 : 42
 017. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  d233d1f | new_key_141 : 42
 018. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 714218c4 | new_key_142 : 42
 019. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: ec4df9b2 | new_key_143 : 42
 020. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 89805372 | new_key_144 : 42
 021. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 148fb204 | new_key_145 : 42
 022. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 68ee97df | new_key_146 : 42
 023. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: f5e176a9 | new_key_147 : 42
 024. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: a375c25f | new_key_148 : 42
 025. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 3e7a2329 | new_key_149 : 42
 026. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 29d70781 | new_key_150 : 42
 027. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: b4d8e6f7 | new_key_151 : 42
 028. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: c8b9c32c | new_key_152 : 42
 029. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 55b6225a | new_key_153 : 42
 030. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 307b889a | new_key_154 : 42
 031. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: ad7469ec | new_key_155 : 42
 032. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: d1154c37 | new_key_156 : 42
 033. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 4c1aad41 | new_key_157 : 42
 034. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 1a8e19b7 | new_key_158 : 42
 035. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 8781f8c1 | new_key_159 : 42
 036. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 38aa6df8 | new_key_160 : 42
 037. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: a5a58c8e | new_key_161 : 42
 038. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: d9c4a955 | new_key_162 : 42
 039. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 44cb4823 | new_key_163 : 42
 040. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 2106e2e3 | new_key_164 : 42
 041. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: bc090395 | new_key_165 : 42
 042. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: c068264e | new_key_166 : 42
 043. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 5d67c738 | new_key_167 : 42
 044. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  bf373ce | new_key_168 : 42
 045. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 96fc92b8 | new_key_169 : 42
 046. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 8151b610 | new_key_170 : 42
 047. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 1c5e5766 | new_key_171 : 42
 048. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 603f72bd | new_key_172 : 42
 049. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: fd3093cb | new_key_173 : 42
 050. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 98fd390b | new_key_174 : 42
 051. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  5f2d87d | new_key_175 : 42
 052. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 7993fda6 | new_key_176 : 42
 053. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: e49c1cd0 | new_key_177 : 42
 054. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: b208a826 | new_key_178 : 42
 055. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 2f074950 | new_key_179 : 42
 056. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: d5d9758d | new_key_180 : 42
 057. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 48d694fb | new_key_181 : 42
 058. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 34b7b120 | new_key_182 : 42
 059. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: a9b85056 | new_key_183 : 42
 060. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: cc75fa96 | new_key_184 : 42
 061. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 517a1be0 | new_key_185 : 42
 062. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 2d1b3e3b | new_key_186 : 42
 063. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: b014df4d | new_key_187 : 42
 064. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: e6806bbb | new_key_188 : 42
 065. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 7b8f8acd | new_key_189 : 42
 066. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 6c22ae65 | new_key_190 : 42
 067. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: f12d4f13 | new_key_191 : 42
 068. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 8d4c6ac8 | new_key_192 : 42
 069. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 10438bbe | new_key_193 : 42
 070. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 758e217e | new_key_194 : 42
 071. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: e881c008 | new_key_195 : 42
 072. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 94e0e5d3 | new_key_196 : 42
 073. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  9ef04a5 | new_key_197 : 42
 074. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 5f7bb053 | new_key_198 : 42
 075. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: c2745125 | new_key_199 : 42
 076. Empty
 ...
 125. Empty

Page Empty, Page address: 0x2000
 Entry state bitmap: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 000. Empty
 ...
 125. Empty

Page no. 3, Status: Full, Version: 2, CRC32: e1a484ac, Page address: 0x3000
 Entry state bitmap: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 000. Empty
 ...
 125. Empty

Page no. 4, Status: Full, Version: 2, CRC32: d0bcb3db, Page address: 0x4000
 Entry state bitmap: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 000. Empty
 ...
 125. Empty

Page no. 5, Status: Full, Version: 2, CRC32: 5199d6fc, Page address: 0x5000
 Entry state bitmap: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa fa
 000. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: aec44741 | new_key : 42
 001. Written, Namespace Index: 001, Type: uint32_t  , Span: 001, Chunk Index: 255, CRC32: f4f1cce6 | u32_key : 123
 002. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: d349cdfe | new_key_0 : 42
 003. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 7d215c6f | new_key_1 : 42
 004. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 54e9e89d | new_key_2 : 42
 005. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: fa81790c | new_key_3 : 42
 006. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  7788179 | new_key_4 : 42
 007. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: a91010e8 | new_key_5 : 42
 008. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 80d8a41a | new_key_6 : 42
 009. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 2eb0358b | new_key_7 : 42
 010. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: a05a52b1 | new_key_8 : 42
 011. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  e32c320 | new_key_9 : 42
 012. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: b186fdbe | new_key_10 : 42
 013. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  87d2656 | new_key_11 : 42
 014. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 19004c2f | new_key_12 : 42
 015. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: a0fb97c7 | new_key_13 : 42
 016. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 3bfa98dd | new_key_14 : 42
 017. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 82014335 | new_key_15 : 42
 018. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 937c294c | new_key_16 : 42
 019. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 2a87f2a4 | new_key_17 : 42
 020. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 7e0f3139 | new_key_18 : 42
 021. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: c7f4ead1 | new_key_19 : 42
 022. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 984e494c | new_key_20 : 42
 023. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 21b592a4 | new_key_21 : 42
 024. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 30c8f8dd | new_key_22 : 42
 025. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 89332335 | new_key_23 : 42
 026. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 12322c2f | new_key_24 : 42
 027. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: abc9f7c7 | new_key_25 : 42
 028. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: bab49dbe | new_key_26 : 42
 029. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  34f4656 | new_key_27 : 42
 030. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 57c785cb | new_key_28 : 42
 031. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: ee3c5e23 | new_key_29 : 42
 032. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 3626d8dd | new_key_30 : 42
 033. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 8fdd0335 | new_key_31 : 42
 034. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 9ea0694c | new_key_32 : 42
 035. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 275bb2a4 | new_key_33 : 42
 036. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: bc5abdbe | new_key_34 : 42
 037. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  5a16656 | new_key_35 : 42
 038. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 14dc0c2f | new_key_36 : 42
 039. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: ad27d7c7 | new_key_37 : 42
 040. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: f9af145a | new_key_38 : 42
 041. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 4054cfb2 | new_key_39 : 42
 042. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: cbdf20a8 | new_key_40 : 42
 043. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 7224fb40 | new_key_41 : 42
 044. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 63599139 | new_key_42 : 42
 045. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: daa24ad1 | new_key_43 : 42
 046. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 41a345cb | new_key_44 : 42
 047. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: f8589e23 | new_key_45 : 42
 048. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: e925f45a | new_key_46 : 42
 049. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 50de2fb2 | new_key_47 : 42
 050. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  456ec2f | new_key_48 : 42
 051. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: bdad37c7 | new_key_49 : 42
 052. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 65b7b139 | new_key_50 : 42
 053. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: dc4c6ad1 | new_key_51 : 42
 054. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: cd3100a8 | new_key_52 : 42
 055. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 74cadb40 | new_key_53 : 42
 056. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: efcbd45a | new_key_54 : 42
 057. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 56300fb2 | new_key_55 : 42
 058. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 474d65cb | new_key_56 : 42
 059. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: feb6be23 | new_key_57 : 42
 060. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: aa3e7dbe | new_key_58 : 42
 061. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 13c5a656 | new_key_59 : 42
 062. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 4c7f05cb | new_key_60 : 42
 063. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: f584de23 | new_key_61 : 42
 064. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: e4f9b45a | new_key_62 : 42
 065. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 5d026fb2 | new_key_63 : 42
 066. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: c60360a8 | new_key_64 : 42
 067. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 7ff8bb40 | new_key_65 : 42
 068. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 6e85d139 | new_key_66 : 42
 069. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: d77e0ad1 | new_key_67 : 42
 070. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 83f6c94c | new_key_68 : 42
 071. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 3a0d12a4 | new_key_69 : 42
 072. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: e217945a | new_key_70 : 42
 073. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 5bec4fb2 | new_key_71 : 42
 074. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 4a9125cb | new_key_72 : 42
 075. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: f36afe23 | new_key_73 : 42
 076. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 686bf139 | new_key_74 : 42
 077. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: d1902ad1 | new_key_75 : 42
 078. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: c0ed40a8 | new_key_76 : 42
 079. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 79169b40 | new_key_77 : 42
 080. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 2d9e58dd | new_key_78 : 42
 081. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 94658335 | new_key_79 : 42
 082. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 6cfdf360 | new_key_80 : 42
 083. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: d5062888 | new_key_81 : 42
 084. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: c47b42f1 | new_key_82 : 42
 085. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 7d809919 | new_key_83 : 42
 086. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: e6819603 | new_key_84 : 42
 087. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 5f7a4deb | new_key_85 : 42
 088. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 4e072792 | new_key_86 : 42
 089. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: f7fcfc7a | new_key_87 : 42
 090. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: a3743fe7 | new_key_88 : 42
 091. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 1a8fe40f | new_key_89 : 42
 092. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: c29562f1 | new_key_90 : 42
 093. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 7b6eb919 | new_key_91 : 42
 094. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 6a13d360 | new_key_92 : 42
 095. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: d3e80888 | new_key_93 : 42
 096. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 48e90792 | new_key_94 : 42
 097. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: f112dc7a | new_key_95 : 42
 098. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: e06fb603 | new_key_96 : 42
 099. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 59946deb | new_key_97 : 42
 100. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  d1cae76 | new_key_98 : 42
 101. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: b4e7759e | new_key_99 : 42
 102. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 1a50b90a | new_key_100 : 42
 103. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 875f587c | new_key_101 : 42
 104. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: fb3e7da7 | new_key_102 : 42
 105. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 66319cd1 | new_key_103 : 42
 106. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  3fc3611 | new_key_104 : 42
 107. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 9ef3d767 | new_key_105 : 42
 108. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: e292f2bc | new_key_106 : 42
 109. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 7f9d13ca | new_key_107 : 42
 110. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 2909a73c | new_key_108 : 42
 111. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: b406464a | new_key_109 : 42
 112. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: a3ab62e2 | new_key_110 : 42
 113. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 3ea48394 | new_key_111 : 42
 114. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 42c5a64f | new_key_112 : 42
 115. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: dfca4739 | new_key_113 : 42
 116. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: ba07edf9 | new_key_114 : 42
 117. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 27080c8f | new_key_115 : 42
 118. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 5b692954 | new_key_116 : 42
 119. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: c666c822 | new_key_117 : 42
 120. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 90f27cd4 | new_key_118 : 42
 121. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32:  dfd9da2 | new_key_119 : 42
 122. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: b2d6089b | new_key_120 : 42
 123. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 2fd9e9ed | new_key_121 : 42
 124. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: 53b8cc36 | new_key_122 : 42
 125. Written, Namespace Index: 001, Type: int32_t   , Span: 001, Chunk Index: 255, CRC32: ceb72d40 | new_key_123 : 42

@KaeLL
Copy link
Contributor Author

KaeLL commented Jan 27, 2025

@adokitkat glad that got cleared up. But I didn't get the question about the minimum size. Was it rhetorical?

@igrr Interesting. My use case is both to provide defaults as well as factory data, all on the same partition to avoid waste, without much concern for reliability beyond the physical one of the flash itself, which the wear leveling is supposed to mitigate the risks of. This leads me to several questions: how effective is the wear leveling? And now that your brought it up, what else could cause NVS partitions to get corrupted? If possible, how to avoid it? And must partitions be erased when nvs_flash_init returns ESP_ERR_NVS_{NEW_VERSION_FOUND,NO_FREE_PAGES}? Why?

@adokitkat
Copy link
Collaborator

Sorry, I made a mistake about the size and it isn't 4kiB. It really is 12kiB meaning 0x3000 in hexadecimal, which means 3 pages.

@rrtandler
Copy link
Collaborator

rrtandler commented Jan 27, 2025

@KaeLL - the minimum NVS partition size answer is driven by the states of NVS pages on initialisation. In regular case, there is typically one page "active", several pages "full" and several pages "free". For correct initialisation, there has to be at least one free page available in the pool of pages. If the power is interrupted during the moment, when the NVS library writes the data and has to "compress" some of full pages, there may be one page temporarily marked as "freeing". This process might be interrupted i.e. by power-loss event. Then, during subsequent initialisation, there would be 2 pages present in states 'active' and 'freeing' and as there is a requirement to have at least one 'free' page, the minimal number of NVS pages is 3.

To your question related to the wear levelling - the wear levelling is triggered at the moment, when there are all pages except the 2 (one currently active and one deliberately kept free) marked as full.
Side note: Full means that the data in the page has been written up to the last entry (32byte block) of its 4kB size. Regardless, whether some or even all records are still "written" or already marked as "erased".
When NVS needs to write additional data and there are no free pages but the one reserved, the pool of full pages is searched for the candidate page for free space reclaim. The one with biggest potential free space (with highest number of entries marked as erased) is chosen. The useful data of that page is moved (and written one after another) to the spare free page and after the copying finishes, the page states of 3 pages involved change the following way:

  1. previously "active" page becomes "full" (because there was no free space available for the data to be written)
  2. the candidate "full" page becomes, after physical flash erase, spare "free"
  3. the spare "free "page is, after receiving all the active records from the candidate page as "active".
    Note: During the copying the page 2. is marked as "freeing"

The typical situation that makes NVS partition corrupted is the unstable power supply during erase or write operation. One of other situations is the use of firmware compiled with the NVS library code not understanding the newer NVS version i.e. the fallback to original firmware during the OTA, after the new firmware already did some changes in the NVS parition. That might explain, why we allow to specify the NVS version in the NVS partition generator and why we recommend to use the factory defaults in the R/O partition.

@KaeLL
Copy link
Contributor Author

KaeLL commented Jan 31, 2025

Thanks for the answers and explanation, @rrtandler. I'm not acquainted enough with storage systems to fully grasp your explanation, but I think I got the gist of it.
I guess this issue can be closed, then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: In Progress Work is in progress
Projects
None yet
Development

No branches or pull requests

7 participants