| /* |
| * Copyright (c) 2017-2020 Nordic Semiconductor ASA |
| * Copyright (c) 2015 Runtime Inc |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| |
| #include "fcb_test.h" |
| #include <zephyr/storage/flash_map.h> |
| #include <zephyr/drivers/flash.h> |
| #include <zephyr/device.h> |
| |
| struct fcb test_fcb; |
| uint8_t fcb_test_erase_value; |
| |
| #if defined(CONFIG_SOC_SERIES_STM32H7X) |
| #define SECTOR_SIZE 0x20000 /* 128K */ |
| #else |
| #define SECTOR_SIZE 0x4000 /* 16K */ |
| #endif |
| |
| /* Sectors for FCB are defined far from application code |
| * area. This test suite is the non bootable application so 1. image slot is |
| * suitable for it. |
| */ |
| struct flash_sector test_fcb_sector[] = { |
| [0] = { |
| .fs_off = 0, |
| .fs_size = SECTOR_SIZE |
| }, |
| [1] = { |
| .fs_off = SECTOR_SIZE, |
| .fs_size = SECTOR_SIZE |
| }, |
| [2] = { |
| .fs_off = 2 * SECTOR_SIZE, |
| .fs_size = SECTOR_SIZE |
| }, |
| [3] = { |
| .fs_off = 3 * SECTOR_SIZE, |
| .fs_size = SECTOR_SIZE |
| } |
| }; |
| |
| |
| void test_fcb_wipe(void) |
| { |
| int i; |
| int rc; |
| const struct flash_area *fap; |
| |
| rc = flash_area_open(TEST_FCB_FLASH_AREA_ID, &fap); |
| zassert_true(rc == 0, "flash area open call failure"); |
| |
| for (i = 0; i < ARRAY_SIZE(test_fcb_sector); i++) { |
| rc = flash_area_erase(fap, test_fcb_sector[i].fs_off, |
| test_fcb_sector[i].fs_size); |
| zassert_true(rc == 0, "erase call failure"); |
| } |
| } |
| |
| int fcb_test_empty_walk_cb(struct fcb_entry_ctx *entry_ctx, void *arg) |
| { |
| zassert_unreachable("fcb_test_empty_walk_cb"); |
| return 0; |
| } |
| |
| uint8_t fcb_test_append_data(int msg_len, int off) |
| { |
| return (msg_len ^ off); |
| } |
| |
| int fcb_test_data_walk_cb(struct fcb_entry_ctx *entry_ctx, void *arg) |
| { |
| uint16_t len; |
| uint8_t test_data[128]; |
| int rc; |
| int i; |
| int *var_cnt = (int *)arg; |
| |
| len = entry_ctx->loc.fe_data_len; |
| |
| zassert_true(len == *var_cnt, ""); |
| |
| rc = flash_area_read(entry_ctx->fap, |
| FCB_ENTRY_FA_DATA_OFF(entry_ctx->loc), |
| test_data, len); |
| zassert_true(rc == 0, "read call failure"); |
| |
| for (i = 0; i < len; i++) { |
| zassert_true(test_data[i] == fcb_test_append_data(len, i), |
| "fcb_test_append_data redout misrepresentation"); |
| } |
| (*var_cnt)++; |
| return 0; |
| } |
| |
| int fcb_test_cnt_elems_cb(struct fcb_entry_ctx *entry_ctx, void *arg) |
| { |
| struct append_arg *aa = (struct append_arg *)arg; |
| int idx; |
| |
| idx = entry_ctx->loc.fe_sector - &test_fcb_sector[0]; |
| aa->elem_cnts[idx]++; |
| return 0; |
| } |
| |
| void fcb_tc_pretest(int sectors) |
| { |
| struct fcb *fcb; |
| int rc = 0; |
| |
| test_fcb_wipe(); |
| fcb = &test_fcb; |
| (void)memset(fcb, 0, sizeof(*fcb)); |
| fcb->f_erase_value = fcb_test_erase_value; |
| fcb->f_sector_cnt = sectors; |
| fcb->f_sectors = test_fcb_sector; /* XXX */ |
| |
| rc = 0; |
| rc = fcb_init(TEST_FCB_FLASH_AREA_ID, fcb); |
| if (rc != 0) { |
| printf("%s rc == %xm, %d\n", __func__, rc, rc); |
| zassert_true(rc == 0, "fbc initialization failure"); |
| } |
| } |
| |
| static void fcb_pretest_2_sectors(void *data) |
| { |
| fcb_tc_pretest(2); |
| } |
| |
| static void fcb_pretest_4_sectors(void *data) |
| { |
| fcb_tc_pretest(4); |
| } |
| |
| /* |
| * This actually is not a test; the function gets erase value from flash |
| * parameters, of the flash device that is used by tests, and stores it in |
| * global fcb_test_erase_value. |
| */ |
| ZTEST(fcb_test_without_set, test_get_flash_erase_value) |
| { |
| const struct flash_area *fa; |
| const struct flash_parameters *fp; |
| const struct device *dev; |
| int rc = 0; |
| |
| rc = flash_area_open(TEST_FCB_FLASH_AREA_ID, &fa); |
| zassert_equal(rc, 0, "Failed top open flash area"); |
| |
| dev = fa->fa_dev; |
| flash_area_close(fa); |
| |
| zassert_true(dev != NULL, "Failed to obtain device"); |
| |
| fp = flash_get_parameters(dev); |
| zassert_true(fp != NULL, "Failed to get flash device parameters"); |
| |
| fcb_test_erase_value = fp->erase_value; |
| } |
| |
| ZTEST_SUITE(fcb_test_without_set, NULL, NULL, NULL, NULL, NULL); |
| ZTEST_SUITE(fcb_test_with_2sectors_set, NULL, NULL, fcb_pretest_2_sectors, NULL, NULL); |
| ZTEST_SUITE(fcb_test_with_4sectors_set, NULL, NULL, fcb_pretest_4_sectors, NULL, NULL); |