blob: d9da0a191927e3d6860b2d30e23c684a8faa8905 [file] [log] [blame]
/*
* Copyright (c) 2022 Vestas Wind Systems A/S
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/drivers/eeprom.h>
#include <zephyr/drivers/eeprom/eeprom_fake.h>
#include <zephyr/fff.h>
#include <zephyr/shell/shell.h>
#include <zephyr/shell/shell_dummy.h>
#include <zephyr/sys/util.h>
#include <zephyr/ztest.h>
#define FAKE_EEPROM_NAME DEVICE_DT_NAME(DT_NODELABEL(fake_eeprom))
/* Global variables */
static const struct device *const fake_eeprom_dev = DEVICE_DT_GET(DT_NODELABEL(fake_eeprom));
static uint8_t data_capture[CONFIG_EEPROM_SHELL_BUFFER_SIZE];
DEFINE_FFF_GLOBALS;
static int eeprom_shell_test_write_capture_data(const struct device *dev, off_t offset,
const void *data, size_t len)
{
ARG_UNUSED(dev);
ARG_UNUSED(offset);
zassert_true(len <= sizeof(data_capture));
memcpy(&data_capture, data, MIN(sizeof(data_capture), len));
return 0;
}
static int eeprom_shell_test_read_captured_data(const struct device *dev, off_t offset,
void *data, size_t len)
{
ARG_UNUSED(dev);
ARG_UNUSED(offset);
zassert_true(len <= sizeof(data_capture));
memcpy(data, &data_capture, MIN(sizeof(data_capture), len));
return 0;
}
ZTEST(eeprom_shell, test_eeprom_write)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
const uint8_t expected[] = { 0x11, 0x22, 0x33, 0x44, 0xaa, 0xbb, 0xcc, 0xdd };
int err;
/* This test relies on the EEPROM shell using a buffer size of at least 8 bytes */
BUILD_ASSERT(CONFIG_EEPROM_SHELL_BUFFER_SIZE >= 8);
/* Setup data capture to satisfy EEPROM shell verification read-back */
fake_eeprom_write_fake.custom_fake = eeprom_shell_test_write_capture_data;
fake_eeprom_read_fake.custom_fake = eeprom_shell_test_read_captured_data;
err = shell_execute_cmd(sh, "eeprom write " FAKE_EEPROM_NAME
" 8 0x11 0x22 0x33 0x44 0xaa 0xbb 0xcc 0xdd");
zassert_ok(err, "failed to execute shell command (err %d)", err);
/* The EEPROM shell will write the bytes ... */
zassert_equal(fake_eeprom_write_fake.call_count, 1);
zassert_equal(fake_eeprom_write_fake.arg0_val, fake_eeprom_dev);
zassert_equal(fake_eeprom_write_fake.arg1_val, 8);
zassert_not_null(fake_eeprom_write_fake.arg2_val);
zassert_equal(fake_eeprom_write_fake.arg3_val, 8);
/* ... and verify the written bytes by reading them back */
zassert_equal(fake_eeprom_read_fake.call_count, 1);
zassert_equal(fake_eeprom_read_fake.arg0_val, fake_eeprom_dev);
zassert_equal(fake_eeprom_read_fake.arg1_val, 8);
zassert_not_null(fake_eeprom_read_fake.arg2_val);
zassert_equal(fake_eeprom_write_fake.arg3_val, 8);
/* Verify data values parsed and written correctly */
zassert_mem_equal(&data_capture, &expected, sizeof(expected));
}
ZTEST(eeprom_shell, test_eeprom_write_failed_verification)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
int err;
err = shell_execute_cmd(sh, "eeprom write " FAKE_EEPROM_NAME " 0 0xaa 0x55");
zassert_true(err < 0, "shell command should have failed (err %d)", err);
/* The EEPROM shell will write the bytes ... */
zassert_equal(fake_eeprom_write_fake.call_count, 1);
zassert_equal(fake_eeprom_write_fake.arg0_val, fake_eeprom_dev);
zassert_equal(fake_eeprom_write_fake.arg1_val, 0);
zassert_not_null(fake_eeprom_write_fake.arg2_val);
zassert_equal(fake_eeprom_write_fake.arg3_val, 2);
/* ... and attempt to verify the written bytes by reading them back */
zassert_equal(fake_eeprom_read_fake.call_count, 1);
zassert_equal(fake_eeprom_read_fake.arg0_val, fake_eeprom_dev);
zassert_equal(fake_eeprom_read_fake.arg1_val, 0);
zassert_not_null(fake_eeprom_read_fake.arg2_val);
zassert_equal(fake_eeprom_write_fake.arg3_val, 2);
}
ZTEST(eeprom_shell, test_eeprom_read)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
int err;
/* This test relies on the shell hexdumping 16 bytes per line */
BUILD_ASSERT(SHELL_HEXDUMP_BYTES_IN_LINE == 16);
/* The EEPROM shell will split this read into two calls to eeprom_read() */
err = shell_execute_cmd(sh, "eeprom read " FAKE_EEPROM_NAME " 8 32");
zassert_ok(err, "failed to execute shell command (err %d)", err);
zassert_equal(fake_eeprom_read_fake.call_count, 2);
/* 1st read */
zassert_equal(fake_eeprom_read_fake.arg0_history[0], fake_eeprom_dev);
zassert_equal(fake_eeprom_read_fake.arg1_history[0], 8);
zassert_not_null(fake_eeprom_read_fake.arg2_history[0]);
zassert_equal(fake_eeprom_read_fake.arg3_history[0], SHELL_HEXDUMP_BYTES_IN_LINE);
/* 2nd read */
zassert_equal(fake_eeprom_read_fake.arg0_history[1], fake_eeprom_dev);
zassert_equal(fake_eeprom_read_fake.arg1_history[1], 8 + SHELL_HEXDUMP_BYTES_IN_LINE);
zassert_not_null(fake_eeprom_read_fake.arg2_history[1]);
zassert_equal(fake_eeprom_read_fake.arg3_history[1], SHELL_HEXDUMP_BYTES_IN_LINE);
}
ZTEST(eeprom_shell, test_eeprom_size)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
int err;
err = shell_execute_cmd(sh, "eeprom size " FAKE_EEPROM_NAME);
zassert_ok(err, "failed to execute shell command (err %d)", err);
zassert_equal(fake_eeprom_size_fake.call_count, 1);
zassert_equal(fake_eeprom_size_fake.arg0_val, fake_eeprom_dev);
}
ZTEST(eeprom_shell, test_eeprom_fill)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
const uint8_t expected[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa };
int err;
/* This test relies on the EEPROM shell using a buffer size of at least 8 bytes */
BUILD_ASSERT(CONFIG_EEPROM_SHELL_BUFFER_SIZE >= 8);
/* Setup data capture to satisfy EEPROM shell verification read-back */
fake_eeprom_write_fake.custom_fake = eeprom_shell_test_write_capture_data;
fake_eeprom_read_fake.custom_fake = eeprom_shell_test_read_captured_data;
err = shell_execute_cmd(sh, "eeprom fill " FAKE_EEPROM_NAME
" 16 8 0xaa");
zassert_ok(err, "failed to execute shell command (err %d)", err);
/* The EEPROM shell will write the bytes ... */
zassert_equal(fake_eeprom_write_fake.call_count, 1);
zassert_equal(fake_eeprom_write_fake.arg0_val, fake_eeprom_dev);
zassert_equal(fake_eeprom_write_fake.arg1_val, 16);
zassert_not_null(fake_eeprom_write_fake.arg2_val);
zassert_equal(fake_eeprom_write_fake.arg3_val, 8);
/* ... and verify the written bytes by reading them back */
zassert_equal(fake_eeprom_read_fake.call_count, 1);
zassert_equal(fake_eeprom_read_fake.arg0_val, fake_eeprom_dev);
zassert_equal(fake_eeprom_read_fake.arg1_val, 16);
zassert_not_null(fake_eeprom_read_fake.arg2_val);
zassert_equal(fake_eeprom_write_fake.arg3_val, 8);
/* Verify data values parsed and written correctly */
zassert_mem_equal(&data_capture, &expected, sizeof(expected));
}
static void eeprom_shell_before(void *fixture)
{
ARG_UNUSED(fixture);
memset(&data_capture, 0, sizeof(data_capture));
}
static void *eeprom_shell_setup(void)
{
const struct shell *sh = shell_backend_dummy_get_ptr();
zassert_true(device_is_ready(fake_eeprom_dev));
/* Verify that the EEPROM size is as expected by the tests */
zassert_equal(KB(8), eeprom_get_size(fake_eeprom_dev));
/* Wait for the initialization of the shell dummy backend. */
WAIT_FOR(shell_ready(sh), 20000, k_msleep(1));
zassert_true(shell_ready(sh), "timed out waiting for dummy shell backend");
return NULL;
}
ZTEST_SUITE(eeprom_shell, NULL, eeprom_shell_setup, eeprom_shell_before, NULL, NULL);