1 /*
2 * Copyright (c) 2019 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /*
8 * This test is designed to be run using flash-simulator which provide
9 * functionality for flash property customization and emulating errors in
10 * flash opperation in parallel to regular flash API.
11 * Test should be run on qemu_x86 target.
12 */
13
14 #ifndef CONFIG_BOARD_QEMU_X86
15 #error "Run on qemu_x86 only"
16 #endif
17
18 #include <stdio.h>
19 #include <string.h>
20 #include <ztest.h>
21
22 #include <drivers/flash.h>
23 #include <storage/flash_map.h>
24 #include <stats/stats.h>
25 #include <sys/crc.h>
26 #include <fs/nvs.h>
27 #include "nvs_priv.h"
28
29 #define TEST_FLASH_AREA_STORAGE_OFFSET FLASH_AREA_OFFSET(storage)
30 #define TEST_DATA_ID 1
31 #define TEST_SECTOR_COUNT 5U
32
33 static struct nvs_fs fs;
34 struct stats_hdr *sim_stats;
35 struct stats_hdr *sim_thresholds;
36
setup(void)37 void setup(void)
38 {
39 sim_stats = stats_group_find("flash_sim_stats");
40 sim_thresholds = stats_group_find("flash_sim_thresholds");
41
42 /* Verify if NVS is initialized. */
43 if (fs.sector_count != 0) {
44 int err;
45
46 err = nvs_clear(&fs);
47 zassert_true(err == 0, "nvs_clear call failure: %d", err);
48 }
49 }
50
teardown(void)51 void teardown(void)
52 {
53 if (sim_stats) {
54 stats_reset(sim_stats);
55 }
56 if (sim_thresholds) {
57 stats_reset(sim_thresholds);
58 }
59 }
60
test_nvs_init(void)61 void test_nvs_init(void)
62 {
63 int err;
64 const struct flash_area *fa;
65 struct flash_pages_info info;
66
67 err = flash_area_open(FLASH_AREA_ID(storage), &fa);
68 zassert_true(err == 0, "flash_area_open() fail: %d", err);
69
70 fs.offset = TEST_FLASH_AREA_STORAGE_OFFSET;
71 err = flash_get_page_info_by_offs(flash_area_get_device(fa), fs.offset,
72 &info);
73 zassert_true(err == 0, "Unable to get page info: %d", err);
74
75 fs.sector_size = info.size;
76 fs.sector_count = TEST_SECTOR_COUNT;
77
78 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
79 zassert_true(err == 0, "nvs_init call failure: %d", err);
80 }
81
execute_long_pattern_write(uint16_t id)82 static void execute_long_pattern_write(uint16_t id)
83 {
84 char rd_buf[512];
85 char wr_buf[512];
86 char pattern[] = {0xDE, 0xAD, 0xBE, 0xEF};
87 size_t len;
88
89 len = nvs_read(&fs, id, rd_buf, sizeof(rd_buf));
90 zassert_true(len == -ENOENT, "nvs_read unexpected failure: %d", len);
91
92 BUILD_ASSERT((sizeof(wr_buf) % sizeof(pattern)) == 0);
93 for (int i = 0; i < sizeof(wr_buf); i += sizeof(pattern)) {
94 memcpy(wr_buf + i, pattern, sizeof(pattern));
95 }
96
97 len = nvs_write(&fs, id, wr_buf, sizeof(wr_buf));
98 zassert_true(len == sizeof(wr_buf), "nvs_write failed: %d", len);
99
100 len = nvs_read(&fs, id, rd_buf, sizeof(rd_buf));
101 zassert_true(len == sizeof(rd_buf), "nvs_read unexpected failure: %d",
102 len);
103 zassert_mem_equal(wr_buf, rd_buf, sizeof(rd_buf),
104 "RD buff should be equal to the WR buff");
105 }
106
test_nvs_write(void)107 void test_nvs_write(void)
108 {
109 int err;
110
111 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
112 zassert_true(err == 0, "nvs_init call failure: %d", err);
113
114 execute_long_pattern_write(TEST_DATA_ID);
115 }
116
flash_sim_write_calls_find(struct stats_hdr * hdr,void * arg,const char * name,uint16_t off)117 static int flash_sim_write_calls_find(struct stats_hdr *hdr, void *arg,
118 const char *name, uint16_t off)
119 {
120 if (!strcmp(name, "flash_write_calls")) {
121 uint32_t **flash_write_stat = (uint32_t **) arg;
122 *flash_write_stat = (uint32_t *)((uint8_t *)hdr + off);
123 }
124
125 return 0;
126 }
127
flash_sim_max_write_calls_find(struct stats_hdr * hdr,void * arg,const char * name,uint16_t off)128 static int flash_sim_max_write_calls_find(struct stats_hdr *hdr, void *arg,
129 const char *name, uint16_t off)
130 {
131 if (!strcmp(name, "max_write_calls")) {
132 uint32_t **max_write_calls = (uint32_t **) arg;
133 *max_write_calls = (uint32_t *)((uint8_t *)hdr + off);
134 }
135
136 return 0;
137 }
138
test_nvs_corrupted_write(void)139 void test_nvs_corrupted_write(void)
140 {
141 int err;
142 size_t len;
143 char rd_buf[512];
144 char wr_buf_1[512];
145 char wr_buf_2[512];
146 char pattern_1[] = {0xDE, 0xAD, 0xBE, 0xEF};
147 char pattern_2[] = {0x03, 0xAA, 0x85, 0x6F};
148 uint32_t *flash_write_stat;
149 uint32_t *flash_max_write_calls;
150
151 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
152 zassert_true(err == 0, "nvs_init call failure: %d", err);
153
154 err = nvs_read(&fs, TEST_DATA_ID, rd_buf, sizeof(rd_buf));
155 zassert_true(err == -ENOENT, "nvs_read unexpected failure: %d", err);
156
157 BUILD_ASSERT((sizeof(wr_buf_1) % sizeof(pattern_1)) == 0);
158 for (int i = 0; i < sizeof(wr_buf_1); i += sizeof(pattern_1)) {
159 memcpy(wr_buf_1 + i, pattern_1, sizeof(pattern_1));
160 }
161
162 len = nvs_write(&fs, TEST_DATA_ID, wr_buf_1, sizeof(wr_buf_1));
163 zassert_true(len == sizeof(wr_buf_1), "nvs_write failed: %d", len);
164
165 len = nvs_read(&fs, TEST_DATA_ID, rd_buf, sizeof(rd_buf));
166 zassert_true(len == sizeof(rd_buf), "nvs_read unexpected failure: %d",
167 len);
168 zassert_mem_equal(wr_buf_1, rd_buf, sizeof(rd_buf),
169 "RD buff should be equal to the first WR buff");
170
171 BUILD_ASSERT((sizeof(wr_buf_2) % sizeof(pattern_2)) == 0);
172 for (int i = 0; i < sizeof(wr_buf_2); i += sizeof(pattern_2)) {
173 memcpy(wr_buf_2 + i, pattern_2, sizeof(pattern_2));
174 }
175
176 /* Set the maximum number of writes that the flash simulator can
177 * execute.
178 */
179 stats_walk(sim_thresholds, flash_sim_max_write_calls_find,
180 &flash_max_write_calls);
181 stats_walk(sim_stats, flash_sim_write_calls_find, &flash_write_stat);
182
183 *flash_max_write_calls = *flash_write_stat - 1;
184 *flash_write_stat = 0;
185
186 /* Flash simulator will lose part of the data at the end of this write.
187 * This should simulate power down during flash write. The written data
188 * are corrupted at this point and should be discarded by the NVS.
189 */
190 len = nvs_write(&fs, TEST_DATA_ID, wr_buf_2, sizeof(wr_buf_2));
191 zassert_true(len == sizeof(wr_buf_2), "nvs_write failed: %d", len);
192
193 /* Reinitialize the NVS. */
194 memset(&fs, 0, sizeof(fs));
195 test_nvs_init();
196
197 len = nvs_read(&fs, TEST_DATA_ID, rd_buf, sizeof(rd_buf));
198 zassert_true(len == sizeof(rd_buf), "nvs_read unexpected failure: %d",
199 len);
200 zassert_true(memcmp(wr_buf_2, rd_buf, sizeof(rd_buf)) != 0,
201 "RD buff should not be equal to the second WR buff because of "
202 "corrupted write operation");
203 zassert_mem_equal(wr_buf_1, rd_buf, sizeof(rd_buf),
204 "RD buff should be equal to the first WR buff because subsequent "
205 "write operation has failed");
206 }
207
test_nvs_gc(void)208 void test_nvs_gc(void)
209 {
210 int err;
211 int len;
212 uint8_t buf[32];
213 uint8_t rd_buf[32];
214
215 const uint16_t max_id = 10;
216 /* 25th write will trigger GC. */
217 const uint16_t max_writes = 26;
218
219 fs.sector_count = 2;
220
221 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
222 zassert_true(err == 0, "nvs_init call failure: %d", err);
223
224 for (uint16_t i = 0; i < max_writes; i++) {
225 uint8_t id = (i % max_id);
226 uint8_t id_data = id + max_id * (i / max_id);
227
228 memset(buf, id_data, sizeof(buf));
229
230 len = nvs_write(&fs, id, buf, sizeof(buf));
231 zassert_true(len == sizeof(buf), "nvs_write failed: %d", len);
232 }
233
234 for (uint16_t id = 0; id < max_id; id++) {
235 len = nvs_read(&fs, id, rd_buf, sizeof(buf));
236 zassert_true(len == sizeof(rd_buf),
237 "nvs_read unexpected failure: %d", len);
238
239 for (uint16_t i = 0; i < sizeof(rd_buf); i++) {
240 rd_buf[i] = rd_buf[i] % max_id;
241 buf[i] = id;
242 }
243 zassert_mem_equal(buf, rd_buf, sizeof(rd_buf),
244 "RD buff should be equal to the WR buff");
245
246 }
247
248 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
249 zassert_true(err == 0, "nvs_init call failure: %d", err);
250
251 for (uint16_t id = 0; id < max_id; id++) {
252 len = nvs_read(&fs, id, rd_buf, sizeof(buf));
253 zassert_true(len == sizeof(rd_buf),
254 "nvs_read unexpected failure: %d", len);
255
256 for (uint16_t i = 0; i < sizeof(rd_buf); i++) {
257 rd_buf[i] = rd_buf[i] % max_id;
258 buf[i] = id;
259 }
260 zassert_mem_equal(buf, rd_buf, sizeof(rd_buf),
261 "RD buff should be equal to the WR buff");
262
263 }
264 }
265
write_content(uint16_t max_id,uint16_t begin,uint16_t end,struct nvs_fs * fs)266 static void write_content(uint16_t max_id, uint16_t begin, uint16_t end,
267 struct nvs_fs *fs)
268 {
269 uint8_t buf[32];
270 ssize_t len;
271
272 for (uint16_t i = begin; i < end; i++) {
273 uint8_t id = (i % max_id);
274 uint8_t id_data = id + max_id * (i / max_id);
275
276 memset(buf, id_data, sizeof(buf));
277
278 len = nvs_write(fs, id, buf, sizeof(buf));
279 zassert_true(len == sizeof(buf), "nvs_write failed: %d", len);
280 }
281 }
282
check_content(uint16_t max_id,struct nvs_fs * fs)283 static void check_content(uint16_t max_id, struct nvs_fs *fs)
284 {
285 uint8_t rd_buf[32];
286 uint8_t buf[32];
287 ssize_t len;
288
289 for (uint16_t id = 0; id < max_id; id++) {
290 len = nvs_read(fs, id, rd_buf, sizeof(buf));
291 zassert_true(len == sizeof(rd_buf),
292 "nvs_read unexpected failure: %d", len);
293
294 for (uint16_t i = 0; i < ARRAY_SIZE(rd_buf); i++) {
295 rd_buf[i] = rd_buf[i] % max_id;
296 buf[i] = id;
297 }
298 zassert_mem_equal(buf, rd_buf, sizeof(rd_buf),
299 "RD buff should be equal to the WR buff");
300
301 }
302 }
303
304 /**
305 * Full round of GC over 3 sectors
306 */
test_nvs_gc_3sectors(void)307 void test_nvs_gc_3sectors(void)
308 {
309 int err;
310
311 const uint16_t max_id = 10;
312 /* 50th write will trigger 1st GC. */
313 const uint16_t max_writes = 51;
314 /* 75th write will trigger 2st GC. */
315 const uint16_t max_writes_2 = 51 + 25;
316 /* 100th write will trigger 3st GC. */
317 const uint16_t max_writes_3 = 51 + 25 + 25;
318 /* 125th write will trigger 4st GC. */
319 const uint16_t max_writes_4 = 51 + 25 + 25 + 25;
320
321 fs.sector_count = 3;
322
323 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
324 zassert_true(err == 0, "nvs_init call failure: %d", err);
325 zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 0,
326 "unexpected write sector");
327
328 /* Trigger 1st GC */
329 write_content(max_id, 0, max_writes, &fs);
330
331 /* sector sequence: empty,closed, write */
332 zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 2,
333 "unexpected write sector");
334 check_content(max_id, &fs);
335
336 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
337 zassert_true(err == 0, "nvs_init call failure: %d", err);
338
339 zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 2,
340 "unexpected write sector");
341 check_content(max_id, &fs);
342
343 /* Trigger 2nd GC */
344 write_content(max_id, max_writes, max_writes_2, &fs);
345
346 /* sector sequence: write, empty, closed */
347 zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 0,
348 "unexpected write sector");
349 check_content(max_id, &fs);
350
351 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
352 zassert_true(err == 0, "nvs_init call failure: %d", err);
353
354 zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 0,
355 "unexpected write sector");
356 check_content(max_id, &fs);
357
358 /* Trigger 3rd GC */
359 write_content(max_id, max_writes_2, max_writes_3, &fs);
360
361 /* sector sequence: closed, write, empty */
362 zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 1,
363 "unexpected write sector");
364 check_content(max_id, &fs);
365
366 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
367 zassert_true(err == 0, "nvs_init call failure: %d", err);
368
369 zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 1,
370 "unexpected write sector");
371 check_content(max_id, &fs);
372
373 /* Trigger 4th GC */
374 write_content(max_id, max_writes_3, max_writes_4, &fs);
375
376 /* sector sequence: empty,closed, write */
377 zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 2,
378 "unexpected write sector");
379 check_content(max_id, &fs);
380
381 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
382 zassert_true(err == 0, "nvs_init call failure: %d", err);
383
384 zassert_equal(fs.ate_wra >> ADDR_SECT_SHIFT, 2,
385 "unexpected write sector");
386 check_content(max_id, &fs);
387 }
388
flash_sim_erase_calls_find(struct stats_hdr * hdr,void * arg,const char * name,uint16_t off)389 static int flash_sim_erase_calls_find(struct stats_hdr *hdr, void *arg,
390 const char *name, uint16_t off)
391 {
392 if (!strcmp(name, "flash_erase_calls")) {
393 uint32_t **flash_erase_stat = (uint32_t **) arg;
394 *flash_erase_stat = (uint32_t *)((uint8_t *)hdr + off);
395 }
396
397 return 0;
398 }
399
flash_sim_max_erase_calls_find(struct stats_hdr * hdr,void * arg,const char * name,uint16_t off)400 static int flash_sim_max_erase_calls_find(struct stats_hdr *hdr, void *arg,
401 const char *name, uint16_t off)
402 {
403 if (!strcmp(name, "max_erase_calls")) {
404 uint32_t **max_erase_calls = (uint32_t **) arg;
405 *max_erase_calls = (uint32_t *)((uint8_t *)hdr + off);
406 }
407
408 return 0;
409 }
410
flash_sim_max_len_find(struct stats_hdr * hdr,void * arg,const char * name,uint16_t off)411 static int flash_sim_max_len_find(struct stats_hdr *hdr, void *arg,
412 const char *name, uint16_t off)
413 {
414 if (!strcmp(name, "max_len")) {
415 uint32_t **max_len = (uint32_t **) arg;
416 *max_len = (uint32_t *)((uint8_t *)hdr + off);
417 }
418
419 return 0;
420 }
421
test_nvs_corrupted_sector_close_operation(void)422 void test_nvs_corrupted_sector_close_operation(void)
423 {
424 int err;
425 int len;
426 uint8_t buf[32];
427 uint32_t *flash_write_stat;
428 uint32_t *flash_erase_stat;
429 uint32_t *flash_max_write_calls;
430 uint32_t *flash_max_erase_calls;
431 uint32_t *flash_max_len;
432
433 const uint16_t max_id = 10;
434 /* 25th write will trigger GC. */
435 const uint16_t max_writes = 26;
436
437 /* Get the address of simulator parameters. */
438 stats_walk(sim_thresholds, flash_sim_max_write_calls_find,
439 &flash_max_write_calls);
440 stats_walk(sim_thresholds, flash_sim_max_erase_calls_find,
441 &flash_max_erase_calls);
442 stats_walk(sim_thresholds, flash_sim_max_len_find,
443 &flash_max_len);
444 stats_walk(sim_stats, flash_sim_write_calls_find, &flash_write_stat);
445 stats_walk(sim_stats, flash_sim_erase_calls_find, &flash_erase_stat);
446
447 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
448 zassert_true(err == 0, "nvs_init call failure: %d", err);
449
450 for (uint16_t i = 0; i < max_writes; i++) {
451 uint8_t id = (i % max_id);
452 uint8_t id_data = id + max_id * (i / max_id);
453
454 memset(buf, id_data, sizeof(buf));
455
456 if (i == max_writes - 1) {
457 /* Reset stats. */
458 *flash_write_stat = 0;
459 *flash_erase_stat = 0;
460
461 /* Block write calls and simulate power down during
462 * sector closing operation, so only a part of a NVS
463 * closing ate will be written.
464 */
465 *flash_max_write_calls = 1;
466 *flash_max_erase_calls = 1;
467 *flash_max_len = 4;
468 }
469
470 len = nvs_write(&fs, id, buf, sizeof(buf));
471 zassert_true(len == sizeof(buf), "nvs_write failed: %d", len);
472 }
473
474 /* Make the flash simulator functional again. */
475 *flash_max_write_calls = 0;
476 *flash_max_erase_calls = 0;
477 *flash_max_len = 0;
478
479 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
480 zassert_true(err == 0, "nvs_init call failure: %d", err);
481
482 check_content(max_id, &fs);
483
484 /* Ensure that the NVS is able to store new content. */
485 execute_long_pattern_write(max_id);
486 }
487
488 /**
489 * @brief Test case when storage become full, so only deletion is possible.
490 */
test_nvs_full_sector(void)491 void test_nvs_full_sector(void)
492 {
493 int err;
494 ssize_t len;
495 uint16_t filling_id = 0;
496 uint16_t i, data_read;
497
498 fs.sector_count = 3;
499
500 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
501 zassert_true(err == 0, "nvs_init call failure: %d", err);
502
503 while (1) {
504 len = nvs_write(&fs, filling_id, &filling_id,
505 sizeof(filling_id));
506 if (len == -ENOSPC) {
507 break;
508 }
509 zassert_true(len == sizeof(filling_id), "nvs_write failed: %d",
510 len);
511 filling_id++;
512 }
513
514 /* check whether can delete whatever from full storage */
515 err = nvs_delete(&fs, 1);
516 zassert_true(err == 0, "nvs_delete call failure: %d", err);
517
518 /* the last sector is full now, test re-initialization */
519 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
520 zassert_true(err == 0, "nvs_init call failure: %d", err);
521
522 len = nvs_write(&fs, filling_id, &filling_id, sizeof(filling_id));
523 zassert_true(len == sizeof(filling_id), "nvs_write failed: %d", len);
524
525 /* sanitycheck on NVS content */
526 for (i = 0; i <= filling_id; i++) {
527 len = nvs_read(&fs, i, &data_read, sizeof(data_read));
528 if (i == 1) {
529 zassert_true(len == -ENOENT,
530 "nvs_read shouldn't found the entry: %d",
531 len);
532 } else {
533 zassert_true(len == sizeof(data_read),
534 "nvs_read failed: %d", i, len);
535 zassert_equal(data_read, i,
536 "read unexpected data: %d instead of %d",
537 data_read, i);
538 }
539 }
540 }
541
test_delete(void)542 void test_delete(void)
543 {
544 int err;
545 ssize_t len;
546 uint16_t filling_id, data_read;
547 uint32_t ate_wra, data_wra;
548
549 fs.sector_count = 3;
550
551 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
552 zassert_true(err == 0, "nvs_init call failure: %d", err);
553
554 for (filling_id = 0; filling_id < 10; filling_id++) {
555 len = nvs_write(&fs, filling_id, &filling_id,
556 sizeof(filling_id));
557
558 zassert_true(len == sizeof(filling_id), "nvs_write failed: %d",
559 len);
560
561 if (filling_id != 0) {
562 continue;
563 }
564
565 /* delete the first entry while it is the most recent one */
566 err = nvs_delete(&fs, filling_id);
567 zassert_true(err == 0, "nvs_delete call failure: %d", err);
568
569 len = nvs_read(&fs, filling_id, &data_read, sizeof(data_read));
570 zassert_true(len == -ENOENT,
571 "nvs_read shouldn't found the entry: %d", len);
572 }
573
574 /* delete existing entry */
575 err = nvs_delete(&fs, 1);
576 zassert_true(err == 0, "nvs_delete call failure: %d", err);
577
578 len = nvs_read(&fs, 1, &data_read, sizeof(data_read));
579 zassert_true(len == -ENOENT, "nvs_read shouldn't found the entry: %d",
580 len);
581
582 ate_wra = fs.ate_wra;
583 data_wra = fs.data_wra;
584
585 /* delete already deleted entry */
586 err = nvs_delete(&fs, 1);
587 zassert_true(err == 0, "nvs_delete call failure: %d", err);
588 zassert_true(ate_wra == fs.ate_wra && data_wra == fs.data_wra,
589 "delete already deleted entry should not make"
590 " any footprint in the storage");
591
592 /* delete nonexisting entry */
593 err = nvs_delete(&fs, filling_id);
594 zassert_true(err == 0, "nvs_delete call failure: %d", err);
595 zassert_true(ate_wra == fs.ate_wra && data_wra == fs.data_wra,
596 "delete nonexistent entry should not make"
597 " any footprint in the storage");
598 }
599
600 /*
601 * Test that garbage-collection can recover all ate's even when the last ate,
602 * ie close_ate, is corrupt. In this test the close_ate is set to point to the
603 * last ate at -5. A valid ate is however present at -6. Since the close_ate
604 * has an invalid crc8, the offset should not be used and a recover of the
605 * last ate should be done instead.
606 */
test_nvs_gc_corrupt_close_ate(void)607 void test_nvs_gc_corrupt_close_ate(void)
608 {
609 struct nvs_ate ate, close_ate;
610 const struct device *flash_dev;
611 uint32_t data;
612 ssize_t len;
613 int err;
614
615 flash_dev = device_get_binding(DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
616 zassert_true(flash_dev != NULL, "device_get_binding failure");
617
618 close_ate.id = 0xffff;
619 close_ate.offset = fs.sector_size - sizeof(struct nvs_ate) * 5;
620 close_ate.len = 0;
621 close_ate.crc8 = 0xff; /* Incorrect crc8 */
622
623 ate.id = 0x1;
624 ate.offset = 0;
625 ate.len = sizeof(data);
626 ate.crc8 = crc8_ccitt(0xff, &ate,
627 offsetof(struct nvs_ate, crc8));
628
629 /* Mark sector 0 as closed */
630 err = flash_write(flash_dev, fs.offset + fs.sector_size -
631 sizeof(struct nvs_ate), &close_ate,
632 sizeof(close_ate));
633 zassert_true(err == 0, "flash_write failed: %d", err);
634
635 /* Write valid ate at -6 */
636 err = flash_write(flash_dev, fs.offset + fs.sector_size -
637 sizeof(struct nvs_ate) * 6, &ate, sizeof(ate));
638 zassert_true(err == 0, "flash_write failed: %d", err);
639
640 /* Write data for previous ate */
641 data = 0xaa55aa55;
642 err = flash_write(flash_dev, fs.offset, &data, sizeof(data));
643 zassert_true(err == 0, "flash_write failed: %d", err);
644
645 /* Mark sector 1 as closed */
646 err = flash_write(flash_dev, fs.offset + (2 * fs.sector_size) -
647 sizeof(struct nvs_ate), &close_ate,
648 sizeof(close_ate));
649 zassert_true(err == 0, "flash_write failed: %d", err);
650
651 fs.sector_count = 3;
652
653 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
654 zassert_true(err == 0, "nvs_init call failure: %d", err);
655
656 data = 0;
657 len = nvs_read(&fs, 1, &data, sizeof(data));
658 zassert_true(len == sizeof(data),
659 "nvs_read should have read %d bytes", sizeof(data));
660 zassert_true(data == 0xaa55aa55, "unexpected value %d", data);
661 }
662
663 /*
664 * Test that garbage-collection correctly handles corrupt ate's.
665 */
test_nvs_gc_corrupt_ate(void)666 void test_nvs_gc_corrupt_ate(void)
667 {
668 struct nvs_ate corrupt_ate, close_ate;
669 const struct device *flash_dev;
670 int err;
671
672 flash_dev = device_get_binding(DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
673 zassert_true(flash_dev != NULL, "device_get_binding failure");
674
675 close_ate.id = 0xffff;
676 close_ate.offset = fs.sector_size / 2;
677 close_ate.len = 0;
678 close_ate.crc8 = crc8_ccitt(0xff, &close_ate,
679 offsetof(struct nvs_ate, crc8));
680
681 corrupt_ate.id = 0xdead;
682 corrupt_ate.offset = 0;
683 corrupt_ate.len = 20;
684 corrupt_ate.crc8 = 0xff; /* Incorrect crc8 */
685
686 /* Mark sector 0 as closed */
687 err = flash_write(flash_dev, fs.offset + fs.sector_size -
688 sizeof(struct nvs_ate), &close_ate,
689 sizeof(close_ate));
690 zassert_true(err == 0, "flash_write failed: %d", err);
691
692 /* Write a corrupt ate */
693 err = flash_write(flash_dev, fs.offset + (fs.sector_size / 2),
694 &corrupt_ate, sizeof(corrupt_ate));
695 zassert_true(err == 0, "flash_write failed: %d", err);
696
697 /* Mark sector 1 as closed */
698 err = flash_write(flash_dev, fs.offset + (2 * fs.sector_size) -
699 sizeof(struct nvs_ate), &close_ate,
700 sizeof(close_ate));
701 zassert_true(err == 0, "flash_write failed: %d", err);
702
703 fs.sector_count = 3;
704
705 err = nvs_init(&fs, DT_CHOSEN_ZEPHYR_FLASH_CONTROLLER_LABEL);
706 zassert_true(err == 0, "nvs_init call failure: %d", err);
707 }
708
test_main(void)709 void test_main(void)
710 {
711 ztest_test_suite(test_nvs,
712 ztest_unit_test_setup_teardown(test_nvs_init, setup,
713 teardown),
714 ztest_unit_test_setup_teardown(test_nvs_write, setup,
715 teardown),
716 ztest_unit_test_setup_teardown(
717 test_nvs_corrupted_write, setup, teardown),
718 ztest_unit_test_setup_teardown(
719 test_nvs_gc, setup, teardown),
720 ztest_unit_test_setup_teardown(
721 test_nvs_gc_3sectors, setup, teardown),
722 ztest_unit_test_setup_teardown(
723 test_nvs_corrupted_sector_close_operation,
724 setup, teardown),
725 ztest_unit_test_setup_teardown(test_nvs_full_sector,
726 setup, teardown),
727 ztest_unit_test_setup_teardown(test_delete, setup,
728 teardown),
729 ztest_unit_test_setup_teardown(
730 test_nvs_gc_corrupt_close_ate, setup, teardown),
731 ztest_unit_test_setup_teardown(
732 test_nvs_gc_corrupt_ate, setup, teardown)
733 );
734
735 ztest_run_test_suite(test_nvs);
736 }
737