diff --git a/tests/mtd_flashpage/Makefile b/tests/mtd_flashpage/Makefile new file mode 100644 index 0000000000..4ebfdfb69b --- /dev/null +++ b/tests/mtd_flashpage/Makefile @@ -0,0 +1,6 @@ +include ../Makefile.tests_common + +USEMODULE += mtd_flashpage +USEMODULE += embunit + +include $(RIOTBASE)/Makefile.include diff --git a/tests/mtd_flashpage/main.c b/tests/mtd_flashpage/main.c new file mode 100644 index 0000000000..6361829443 --- /dev/null +++ b/tests/mtd_flashpage/main.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2016 OTA keys S.A. + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @{ + * + * @file + */ +#include +#include + +#include "embUnit.h" + +#include "mtd.h" +#include "mtd_flashpage.h" + +#define TEST_ADDRESS1 (uint32_t)flashpage_addr(FLASHPAGE_NUMOF - 1) +#define TEST_ADDRESS2 (uint32_t)flashpage_addr(FLASHPAGE_NUMOF - 2) + +static mtd_dev_t _dev = MTD_FLASHPAGE_INIT_VAL(8); +static mtd_dev_t *dev = &_dev; + +static void setup(void) +{ + int ret = mtd_init(dev); + TEST_ASSERT_EQUAL_INT(0, ret); + mtd_erase(dev, TEST_ADDRESS1, dev->pages_per_sector * dev->page_size); + mtd_erase(dev, TEST_ADDRESS2, dev->pages_per_sector * dev->page_size); +} + +static void teardown(void) +{ + mtd_erase(dev, TEST_ADDRESS1, dev->pages_per_sector * dev->page_size); + mtd_erase(dev, TEST_ADDRESS2, dev->pages_per_sector * dev->page_size); +} + +static void test_mtd_init(void) +{ + int ret = mtd_init(dev); + TEST_ASSERT_EQUAL_INT(0, ret); +} + +static void test_mtd_erase(void) +{ + /* Erase last sector */ + int ret = mtd_erase(dev, TEST_ADDRESS1, FLASHPAGE_SIZE); + TEST_ASSERT_EQUAL_INT(0, ret); + + /* Erase with wrong size (less than sector size) */ + ret = mtd_erase(dev, TEST_ADDRESS1, dev->page_size); + TEST_ASSERT_EQUAL_INT(-EOVERFLOW, ret); + + /* Unaligned erase */ + ret = mtd_erase(dev, TEST_ADDRESS1 + dev->page_size, dev->page_size); + TEST_ASSERT_EQUAL_INT(-EOVERFLOW, ret); + + /* Erase 2 last sectors */ + ret = mtd_erase(dev, TEST_ADDRESS2, + FLASHPAGE_SIZE * 2); + TEST_ASSERT_EQUAL_INT(0, ret); + + /* Erase out of memory area */ + ret = mtd_erase(dev, TEST_ADDRESS1, + FLASHPAGE_SIZE * 2); + TEST_ASSERT_EQUAL_INT(-EOVERFLOW, ret); +} + +static void test_mtd_write_erase(void) +{ + const char buf[] = "ABCDEFGHIJKLMNO"; + + /* stm32l0x and stm32l1x erase its flash with 0's */ +#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) + uint8_t buf_empty[] = {0, 0, 0}; +#else + uint8_t buf_empty[] = {0xff, 0xff, 0xff}; +#endif + char buf_read[sizeof(buf) + sizeof(buf_empty)]; + memset(buf_read, 0, sizeof(buf_read)); + + int ret = mtd_write(dev, buf, TEST_ADDRESS1, sizeof(buf)); + TEST_ASSERT_EQUAL_INT(sizeof(buf), ret); + + ret = mtd_erase(dev, TEST_ADDRESS1, dev->pages_per_sector * dev->page_size); + TEST_ASSERT_EQUAL_INT(0, ret); + + uint8_t expected[sizeof(buf_read)]; +#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) + memset(expected, 0, sizeof(expected)); +#else + memset(expected, 0xff, sizeof(expected)); +#endif + ret = mtd_read(dev, buf_read, TEST_ADDRESS1, sizeof(buf_read)); + TEST_ASSERT_EQUAL_INT(sizeof(buf_read), ret); + TEST_ASSERT_EQUAL_INT(0, memcmp(expected, buf_read, sizeof(buf_read))); +} + +static void test_mtd_write_read(void) +{ + const char buf[] __attribute__ ((aligned (FLASHPAGE_RAW_ALIGNMENT))) = "ABCDEFGHIJKLMNO"; + + /* stm32l0x and stm32l1x erase its flash with 0's */ +#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1) + uint8_t buf_empty[] = {0, 0, 0}; +#else + uint8_t buf_empty[] = {0xff, 0xff, 0xff}; +#endif + char buf_read[sizeof(buf) + sizeof(buf_empty)]; + memset(buf_read, 0, sizeof(buf_read)); + + /* Basic write / read */ + int ret = mtd_write(dev, buf, TEST_ADDRESS1, sizeof(buf)); + TEST_ASSERT_EQUAL_INT(sizeof(buf), ret); + + ret = mtd_read(dev, buf_read, TEST_ADDRESS1, sizeof(buf_read)); + TEST_ASSERT_EQUAL_INT(sizeof(buf_read), ret); + TEST_ASSERT_EQUAL_INT(0, memcmp(buf, buf_read, sizeof(buf))); + TEST_ASSERT_EQUAL_INT(0, memcmp(buf_empty, buf_read + sizeof(buf), sizeof(buf_empty))); + + ret = mtd_erase(dev, TEST_ADDRESS1, dev->pages_per_sector * dev->page_size); + TEST_ASSERT_EQUAL_INT(0, ret); + + /* Unaligned write / read */ + ret = mtd_write(dev, buf, TEST_ADDRESS1 + sizeof(buf_empty), sizeof(buf)); + TEST_ASSERT_EQUAL_INT(-EINVAL, ret); + + /* Only Cortex-M0 doesn't allow unaligned reads */ +#if defined(CPU_ARCH_CORTEX_M0) + ret = mtd_read(dev, buf_read, TEST_ADDRESS1 + sizeof(buf_empty), sizeof(buf_read)); + TEST_ASSERT_EQUAL_INT(-EINVAL, ret); +#endif +} + +Test *tests_mtd_flashpage_tests(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_mtd_init), + new_TestFixture(test_mtd_erase), + new_TestFixture(test_mtd_write_erase), + new_TestFixture(test_mtd_write_read), + }; + + EMB_UNIT_TESTCALLER(mtd_flashpage_tests, setup, teardown, fixtures); + + return (Test *)&mtd_flashpage_tests; +} + +int main(void) +{ + TESTS_START(); + TESTS_RUN(tests_mtd_flashpage_tests()); + TESTS_END(); + return 0; +} +/** @} */ diff --git a/tests/mtd_flashpage/tests/01-run.py b/tests/mtd_flashpage/tests/01-run.py new file mode 100755 index 0000000000..5fc8788f24 --- /dev/null +++ b/tests/mtd_flashpage/tests/01-run.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2017 Freie Universität Berlin +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +import sys +from testrunner import run + + +def testfunc(child): + child.expect(r'OK \(\d+ tests\)') + + +if __name__ == "__main__": + sys.exit(run(testfunc))