1 /*
2 * Copyright (c) 2017-2023 Nordic Semiconductor ASA
3 * Copyright (c) 2015 Runtime Inc
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <stdio.h>
9 #include <string.h>
10
11 #include "fcb_test.h"
12 #include <zephyr/storage/flash_map.h>
13 #include <zephyr/drivers/flash.h>
14 #include <zephyr/device.h>
15
16 struct fcb test_fcb = {0};
17 struct fcb test_fcb_crc_disabled = { .f_flags = FCB_FLAGS_CRC_DISABLED };
18
19 uint8_t fcb_test_erase_value;
20
21 #if defined(CONFIG_SOC_SERIES_STM32H7X)
22 #define SECTOR_SIZE 0x20000 /* 128K */
23 #else
24 #define SECTOR_SIZE 0x4000 /* 16K */
25 #endif
26
27 /* Sectors for FCB are defined far from application code
28 * area. This test suite is the non bootable application so 1. image slot is
29 * suitable for it.
30 */
31 struct flash_sector test_fcb_sector[] = {
32 [0] = {
33 .fs_off = 0,
34 .fs_size = SECTOR_SIZE
35 },
36 [1] = {
37 .fs_off = SECTOR_SIZE,
38 .fs_size = SECTOR_SIZE
39 },
40 [2] = {
41 .fs_off = 2 * SECTOR_SIZE,
42 .fs_size = SECTOR_SIZE
43 },
44 [3] = {
45 .fs_off = 3 * SECTOR_SIZE,
46 .fs_size = SECTOR_SIZE
47 }
48 };
49
50
test_fcb_wipe(void)51 void test_fcb_wipe(void)
52 {
53 int i;
54 int rc;
55 const struct flash_area *fap;
56
57 rc = flash_area_open(TEST_FCB_FLASH_AREA_ID, &fap);
58 zassert_true(rc == 0, "flash area open call failure");
59
60 for (i = 0; i < ARRAY_SIZE(test_fcb_sector); i++) {
61 rc = flash_area_flatten(fap, test_fcb_sector[i].fs_off,
62 test_fcb_sector[i].fs_size);
63 zassert_true(rc == 0, "erase call failure");
64 }
65 }
66
fcb_test_empty_walk_cb(struct fcb_entry_ctx * entry_ctx,void * arg)67 int fcb_test_empty_walk_cb(struct fcb_entry_ctx *entry_ctx, void *arg)
68 {
69 zassert_unreachable("fcb_test_empty_walk_cb");
70 return 0;
71 }
72
fcb_test_append_data(int msg_len,int off)73 uint8_t fcb_test_append_data(int msg_len, int off)
74 {
75 return (msg_len ^ off);
76 }
77
fcb_test_data_walk_cb(struct fcb_entry_ctx * entry_ctx,void * arg)78 int fcb_test_data_walk_cb(struct fcb_entry_ctx *entry_ctx, void *arg)
79 {
80 uint16_t len;
81 uint8_t test_data[128];
82 int rc;
83 int i;
84 int *var_cnt = (int *)arg;
85
86 len = entry_ctx->loc.fe_data_len;
87
88 zassert_true(len == *var_cnt, "");
89
90 rc = flash_area_read(entry_ctx->fap,
91 FCB_ENTRY_FA_DATA_OFF(entry_ctx->loc),
92 test_data, len);
93 zassert_true(rc == 0, "read call failure");
94
95 for (i = 0; i < len; i++) {
96 zassert_true(test_data[i] == fcb_test_append_data(len, i),
97 "fcb_test_append_data redout misrepresentation");
98 }
99 (*var_cnt)++;
100 return 0;
101 }
102
fcb_test_cnt_elems_cb(struct fcb_entry_ctx * entry_ctx,void * arg)103 int fcb_test_cnt_elems_cb(struct fcb_entry_ctx *entry_ctx, void *arg)
104 {
105 struct append_arg *aa = (struct append_arg *)arg;
106 int idx;
107
108 idx = entry_ctx->loc.fe_sector - &test_fcb_sector[0];
109 aa->elem_cnts[idx]++;
110 return 0;
111 }
112
fcb_tc_pretest(int sectors,struct fcb * _fcb)113 void fcb_tc_pretest(int sectors, struct fcb *_fcb)
114 {
115 int rc = 0;
116
117 test_fcb_wipe();
118 _fcb->f_erase_value = fcb_test_erase_value;
119 _fcb->f_sector_cnt = sectors;
120 _fcb->f_sectors = test_fcb_sector; /* XXX */
121
122 rc = 0;
123 rc = fcb_init(TEST_FCB_FLASH_AREA_ID, _fcb);
124 if (rc != 0) {
125 printf("%s rc == %xm, %d\n", __func__, rc, rc);
126 zassert_true(rc == 0, "fbc initialization failure");
127 }
128 }
129
fcb_pretest_2_sectors(void * data)130 static void fcb_pretest_2_sectors(void *data)
131 {
132 fcb_tc_pretest(2, &test_fcb);
133 }
134
fcb_pretest_4_sectors(void * data)135 static void fcb_pretest_4_sectors(void *data)
136 {
137 fcb_tc_pretest(4, &test_fcb);
138 }
139
fcb_pretest_crc_disabled(void * data)140 static void fcb_pretest_crc_disabled(void *data)
141 {
142 fcb_tc_pretest(2, &test_fcb_crc_disabled);
143 }
144
145 /*
146 * This actually is not a test; the function gets erase value from flash
147 * parameters, of the flash device that is used by tests, and stores it in
148 * global fcb_test_erase_value.
149 */
ZTEST(fcb_test_without_set,test_get_flash_erase_value)150 ZTEST(fcb_test_without_set, test_get_flash_erase_value)
151 {
152 const struct flash_area *fa;
153 const struct flash_parameters *fp;
154 const struct device *dev;
155 int rc = 0;
156
157 rc = flash_area_open(TEST_FCB_FLASH_AREA_ID, &fa);
158 zassert_equal(rc, 0, "Failed top open flash area");
159
160 dev = fa->fa_dev;
161 flash_area_close(fa);
162
163 zassert_true(dev != NULL, "Failed to obtain device");
164
165 fp = flash_get_parameters(dev);
166 zassert_true(fp != NULL, "Failed to get flash device parameters");
167
168 fcb_test_erase_value = fp->erase_value;
169 }
170
171 ZTEST_SUITE(fcb_test_without_set, NULL, NULL, NULL, NULL, NULL);
172 ZTEST_SUITE(fcb_test_with_2sectors_set, NULL, NULL, fcb_pretest_2_sectors, NULL, NULL);
173 ZTEST_SUITE(fcb_test_with_4sectors_set, NULL, NULL, fcb_pretest_4_sectors, NULL, NULL);
174
175 ZTEST_SUITE(fcb_test_crc_disabled, NULL, NULL, fcb_pretest_crc_disabled, NULL, NULL);
176