ruuvi.drivers.c ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
Loading...
Searching...
No Matches
ruuvi_interface_flash_test.c
Go to the documentation of this file.
2#if RUUVI_RUN_TESTS
4#include "ruuvi_driver_test.h"
8#include <stdbool.h>
9#include <string.h>
22#define F_BIG_RECORD_SIZE 0x900U
23#define F_TEST_PAGE 0x0002U
24#define F_TEST_RECORD 0x0001U
25static const char __attribute__ ( (aligned (4))) f_data1[] = "Flash test data 1";
26static const char __attribute__ ( (aligned (4))) f_data2[] = "Flash test data 2";
27static uint32_t boot_count = 0;
28
38static bool ri_flash_init_test (const rd_test_print_fp printfp)
39{
40 rd_status_t err_code = RD_SUCCESS;
41 bool status = false;
42 printfp ("\"init\":");
43 err_code = ri_flash_init();
44
45 if (RD_SUCCESS != err_code)
46 {
47 status = true;
50 }
51 else
52 {
53 err_code = ri_flash_init();
54
55 if (RD_ERROR_INVALID_STATE != err_code)
56 {
57 status = true;
58 }
59 }
60
61 err_code |= ri_flash_record_get (APP_FLASH_LOG_FILE, APP_FLASH_LOG_BOOT_COUNTER_RECORD,
62 sizeof (uint32_t), &boot_count);
63
64 if (status)
65 {
66 printfp ("\"fail\",\r\n");
67 }
68 else
69 {
70 printfp ("\"pass\",\r\n");
71 }
72
73 return status;
74}
75
88static bool ri_flash_uninit_test (const rd_test_print_fp printfp)
89{
90 rd_status_t err_code = RD_SUCCESS;
91 bool status = false;
92 printfp ("\"uninit\":");
93 err_code = ri_flash_uninit();
94
95 if (RD_SUCCESS != err_code)
96 {
97 status = true;
98 }
99 else
100 {
101 err_code = ri_flash_init();
102 err_code |= ri_flash_uninit();
103 err_code = ri_flash_init();
104
105 if (RD_SUCCESS != err_code)
106 {
107 status = true;
108 }
109 }
110
111 if (status)
112 {
113 printfp ("\"fail\",\r\n");
114 }
115 else
116 {
117 printfp ("\"pass\",\r\n");
118 }
119
120 return status;
121}
122
129static bool ri_flash_store_test (const rd_test_print_fp printfp)
130{
131 rd_status_t err_code = RD_SUCCESS;
132 bool status = false;
133 printfp ("\"store\":");
134 err_code = ri_flash_uninit();
135 err_code = ri_flash_record_set (F_TEST_PAGE, F_TEST_RECORD, sizeof (f_data1), f_data1);
136
137 if (RD_SUCCESS == err_code)
138 {
139 status = true;
140 }
141 else
142 {
143 err_code = ri_flash_init();
144 err_code |= ri_flash_record_set (F_TEST_PAGE, F_TEST_RECORD, sizeof (f_data1), f_data1);
145 err_code |= ri_flash_record_set (F_TEST_PAGE, F_TEST_RECORD, sizeof (f_data2), f_data2);
146
147 if (RD_SUCCESS != err_code)
148 {
149 status = true;
150 }
151 else
152 {
153 err_code |= ri_flash_record_set (F_TEST_PAGE, F_TEST_RECORD, UINT16_MAX, f_data2);
154
155 if (RD_ERROR_DATA_SIZE != err_code)
156 {
157 status = true;
158 }
159 }
160 }
161
162 if (status)
163 {
164 printfp ("\"fail\",\r\n");
165 }
166 else
167 {
168 printfp ("\"pass\",\r\n");
169 }
170
171 return status;
172}
173
180static bool ri_flash_load_test (const rd_test_print_fp printfp)
181{
182 rd_status_t err_code = RD_SUCCESS;
183 bool status = false;
184 // Ensure we can align into 4-byte boundary.
185 char load_buffer[sizeof (f_data2) + 4] = {0};
186 printfp ("\"load\":");
187 err_code = ri_flash_uninit();
188 err_code |= ri_flash_record_get (F_TEST_PAGE, F_TEST_RECORD, sizeof (f_data1),
189 load_buffer);
190
191 if (RD_SUCCESS == err_code)
192 {
193 status = true;
194 }
195 else
196 {
197 err_code = ri_flash_init();
198 err_code |= ri_flash_record_get (F_TEST_PAGE, F_TEST_RECORD, sizeof (load_buffer),
199 load_buffer);
200
201 if (RD_SUCCESS != err_code
202 || strcmp (f_data2, load_buffer))
203 {
204 status = true;
205 }
206 }
207
208 if (status)
209 {
210 printfp ("\"fail\",\r\n");
211 }
212 else
213 {
214 printfp ("\"pass\",\r\n");
215 }
216
217 return status;
218}
219
226static bool ri_flash_delete_test (const rd_test_print_fp printfp)
227{
228 rd_status_t err_code = RD_SUCCESS;
229 bool status = false;
230 // Ensure we can align into 4-byte boundary.
231 char load_buffer[sizeof (f_data2) + 4] = {0};
232 printfp ("\"free\":");
233 err_code = ri_flash_uninit();
234 err_code |= ri_flash_record_delete (F_TEST_PAGE, F_TEST_RECORD);
235
236 if (RD_SUCCESS == err_code)
237 {
238 status = true;
239 }
240 else
241 {
242 err_code = ri_flash_init();
243 err_code |= ri_flash_record_delete (F_TEST_PAGE, F_TEST_RECORD);
244
245 if (RD_SUCCESS != err_code)
246 {
247 status = true;
248 }
249 else
250 {
251 err_code |= ri_flash_record_get (F_TEST_PAGE, F_TEST_RECORD, sizeof (load_buffer),
252 load_buffer);
253
254 if (RD_ERROR_NOT_FOUND != err_code)
255 {
256 status = true;
257 }
258 }
259 }
260
261 if (status)
262 {
263 printfp ("\"fail\",\r\n");
264 }
265 else
266 {
267 printfp ("\"pass\",\r\n");
268 }
269
270 (void) ri_flash_uninit();
271 return status;
272}
273
283static bool ri_flash_gc_size_busy_test (const rd_test_print_fp printfp)
284{
285 rd_status_t err_code = RD_SUCCESS;
286 bool status = false;
287 printfp ("\"gc\":");
288 err_code = ri_flash_uninit();
289 err_code |= ri_flash_gc_run();
290
291 if (RD_SUCCESS == err_code)
292 {
293 status = true;
294 }
295 else
296 {
297 err_code = ri_flash_init();
298 size_t size;
299
300 // Test that checking free size works
301 do
302 {
303 while (ri_flash_is_busy()) {};
304
305 err_code = ri_flash_record_set (F_TEST_PAGE, F_TEST_RECORD, sizeof (f_data1), f_data1);
306
307 err_code |= ri_flash_free_size_get (&size);
308 } while ( ( (F_BIG_RECORD_SIZE < size) && (RD_SUCCESS == err_code))
309
310 || (RD_ERROR_BUSY == err_code));
311
312 // Test that garbage collection works
313 err_code = ri_flash_gc_run();
314
315 while (ri_flash_is_busy()) {};
316
317 err_code |= ri_flash_free_size_get (&size);
318
319 if ( (RD_SUCCESS != err_code) || (F_BIG_RECORD_SIZE > size))
320 {
321 status = true;
322 }
323 }
324
325 if (status)
326 {
327 printfp ("\"fail\"\r\n");
328 }
329 else
330 {
331 printfp ("\"pass\"\r\n");
332 }
333
334 err_code |= ri_flash_record_set (APP_FLASH_LOG_FILE, APP_FLASH_LOG_BOOT_COUNTER_RECORD,
335 sizeof (uint32_t), &boot_count);
336 err_code = ri_flash_uninit();
337 return status;
338}
339
347{
348 bool status = false;
349 printfp ("\"flash\":{\r\n");
350 status |= ri_flash_init_test (printfp);
351 status |= ri_flash_uninit_test (printfp);
352 status |= ri_flash_store_test (printfp);
353 status |= ri_flash_load_test (printfp);
354 status |= ri_flash_delete_test (printfp);
355 status |= ri_flash_gc_size_busy_test (printfp);
356 printfp ("},\r\n");
357 return status;
358}
359
360/* @} */
361#endif
uint32_t rd_status_t
bitfield for representing errors
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_DATA_SIZE
Invalid Data size.
#define RD_ERROR_NOT_FOUND
Not found.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
#define RD_ERROR_BUSY
Busy.
rd_status_t ri_flash_gc_run(void)
Run garbage collection.
bool ri_flash_run_integration_test(const rd_test_print_fp printfp)
Run all flash tests.
bool ri_flash_is_busy()
Check if flash is busy.
rd_status_t ri_flash_uninit(void)
Unintialize flash. After uninitialization only initialization can be used.
void ri_flash_purge(void)
Purge flash.
rd_status_t ri_flash_record_set(const uint32_t page_id, const uint32_t record_id, const size_t data_size, const void *const data)
Set data to record in page.
rd_status_t ri_flash_init(void)
rd_status_t ri_flash_record_delete(const uint32_t file_id, const uint32_t record_id)
Mark a record for deletion.
rd_status_t ri_flash_free_size_get(size_t *size)
Get total size of free flash.
rd_status_t ri_flash_record_get(const uint32_t page_id, const uint32_t record_id, const size_t data_size, void *const data)
Get data from record in page.
void(* rd_test_print_fp)(const char *const msg)
function pointer to print test information
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
Functions for testing drivers.
Interface functions to persistent flash storage.
void ri_power_reset(void)
Reset IC.