From 756197316ddf5fd1665875c70ac659e06bb441e1 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sun, 2 Apr 2023 16:27:49 +0200 Subject: [PATCH 01/10] drivers/mtd: small fixes in doc --- drivers/include/mtd.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/include/mtd.h b/drivers/include/mtd.h index d4e02abcdd..bc2ccafac5 100644 --- a/drivers/include/mtd.h +++ b/drivers/include/mtd.h @@ -33,7 +33,7 @@ * * A **sector** is the device's erase unit. Calls to @ref mtd_erase need to * work in alignment with this number (commonly somewhere around 1kiB). * - * (Note that this corresponse to the term "page" as used in the flashpage + * (Note that this corresponds to the term "page" as used in the flashpage * API, and the term "eraseblock" in Linux's MTD). * * * A **page** is the largest a device can write in one transfer. @@ -108,7 +108,7 @@ typedef struct mtd_desc mtd_desc_t; typedef struct { const mtd_desc_t *driver; /**< MTD driver */ uint32_t sector_count; /**< Number of sector in the MTD */ - uint32_t pages_per_sector; /**< Number of pages by sector in the MTD */ + uint32_t pages_per_sector; /**< Number of pages per sector in the MTD */ uint32_t page_size; /**< Size of the pages in the MTD */ uint32_t write_size; /**< Minimum size and alignment of writes to the device */ #if defined(MODULE_MTD_WRITE_PAGE) || DOXYGEN @@ -324,8 +324,8 @@ int mtd_read(mtd_dev_t *mtd, void *dest, uint32_t addr, uint32_t count); * @param[in] offset offset from the start of the page (in bytes) * @param[in] size the number of bytes to read * - * @return 0 on success - * @return < 0 if an error occurred + * @return number of bytes read on success + * @return < 0 value on error * @return -ENODEV if @p mtd is not a valid device * @return -ENOTSUP if operation is not supported on @p mtd * @return -EOVERFLOW if @p addr or @p count are not valid, i.e. outside memory @@ -373,8 +373,8 @@ int mtd_write(mtd_dev_t *mtd, const void *src, uint32_t addr, uint32_t count); * @param[in] offset byte offset from the start of the page * @param[in] size the number of bytes to write * - * @return 0 on success - * @return < 0 if an error occurred + * @return number of bytes written on success + * @return < 0 value on error * @return -ENODEV if @p mtd is not a valid device * @return -ENOTSUP if operation is not supported on @p mtd * @return -EOVERFLOW if @p addr or @p count are not valid, i.e. outside memory, @@ -403,8 +403,8 @@ int mtd_write_page_raw(mtd_dev_t *mtd, const void *src, uint32_t page, * @param[in] offset byte offset from the start of the page * @param[in] size the number of bytes to write * - * @return 0 on success - * @return < 0 if an error occurred + * @return number of bytes written on success + * @return < 0 value on error * @return -ENODEV if @p mtd is not a valid device * @return -ENOTSUP if operation is not supported on @p mtd * @return -EOVERFLOW if @p addr or @p count are not valid, i.e. outside memory, From 609c090ceb0837b346ad18bed261f5930124f214 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sun, 2 Apr 2023 16:28:49 +0200 Subject: [PATCH 02/10] drivers/mtd_emulatd: MTD emulated in RAM for testing This driver provides support for MTDs emulated in RAM to test MTD-based applications on boards that do not provide MTDs in hardware. --- drivers/include/mtd_emulated.h | 102 ++++++++++++++++++ drivers/mtd/Kconfig | 3 + drivers/mtd_emulated/Makefile | 1 + drivers/mtd_emulated/mtd_emulated.c | 161 ++++++++++++++++++++++++++++ 4 files changed, 267 insertions(+) create mode 100644 drivers/include/mtd_emulated.h create mode 100644 drivers/mtd_emulated/Makefile create mode 100644 drivers/mtd_emulated/mtd_emulated.c diff --git a/drivers/include/mtd_emulated.h b/drivers/include/mtd_emulated.h new file mode 100644 index 0000000000..6e0195e3bc --- /dev/null +++ b/drivers/include/mtd_emulated.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2023 Gunar Schorcht + * + * 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. + */ + +/** + * @ingroup drivers_mtd + * @{ + * @brief MTD device that is emulated in RAM for test purposes + * + * Helpers for using emulated MTDs. + * + * @author Gunar Schorcht + */ +#ifndef MTD_EMULATED_H +#define MTD_EMULATED_H + +#include + +#include "board.h" +#include "macros/utils.h" +#include "mtd.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Macro to define an emulated MTD + * + * This macro creates a MTD device that is emulated in RAM. For example, using + * ``` + * MTD_EMULATED_DEV(0, 16, 4, 64) + * ``` + * creates the emulated MTD device `mtd_emulated_dev0` with 16 sectors, 4 pages + * per sector and a page size of 64 bytes. The write size is always 1 byte. + * + * @param n index of the emulated MTD (results into symbol `mtd_emulated_devn`) + * @param sc sectors of the emulated MTD + * @param pps pages per sector of the emulated MTD + * @param ps page size in bytes + */ +#define MTD_EMULATED_DEV(n, sc, pps, ps) \ + uint8_t _mtd_emulated_memory ## n[sc * pps * ps]; \ + \ + mtd_emulated_t mtd_emulated_dev ## n = { \ + .base = { \ + .driver = &_mtd_emulated_driver, \ + .sector_count = sc, \ + .pages_per_sector = pps, \ + .page_size = ps, \ + .write_size = 1, \ + }, \ + .size = sc * pps * ps, \ + .memory = _mtd_emulated_memory ## n, \ + .init_done = false, \ + } \ + +#if MODULE_VFS_AUTO_MOUNT || DOXYGEN +/** + * @brief Macro to define an automatic VFS mount point for an emulated MTD. + * + * For example, using + * ``` + * MTD_EMULATED_DEV_FS(0, 2, fatfs); + * ``` + * automatically mounts the emulated MTD `mtd_emulated_dev0` with FAT file + * system under mount point `/mtde0` with unique index 2. + * + * @param n index of the emulated MTD (symbol `mtd_emulated_devn`, mount point `/mtde0`) + * @param m unique overall index of VFS mount point + * @param fs filesystem type used + */ +#define MTD_EMULATED_DEV_FS(n, m, fs) \ + VFS_AUTO_MOUNT(fs, VFS_MTD(mtd_emulated_dev ## n), "/mtde" # n, m) + +#endif /* MODULE_VFS || DOXYGEN */ + +/** + * @brief Device descriptor for a MTD device that is emulated in RAM + */ +typedef struct { + mtd_dev_t base; /**< inherit from mtd_dev_t object */ + size_t size; /**< total size of the MTD device in bytes */ + uint8_t *memory; /**< RAM that is used for the emulated MTD device */ + bool init_done; /**< indicates whether initialization is already done */ +} mtd_emulated_t; + +/** + * @brief Emulated MTD device operations table for mtd + */ +extern const mtd_desc_t _mtd_emulated_driver; + +#ifdef __cplusplus +} +#endif + +#endif /* MTD_EMULATED_H */ +/** @} */ diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index fc18a5c5b0..23aa76002a 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -105,6 +105,9 @@ config MODULE_MTD_SDCARD bool "MTD interface for SPI SD-Card" depends on MODULE_SDCARD_SPI +config MODULE_MTD_EMULATED + bool "MTD interface for MTD emulated in RAM" + config MODULE_SAM0_SDHC bool "MTD interface for SAM0 SD Host Controller" depends on CPU_COMMON_SAM0 diff --git a/drivers/mtd_emulated/Makefile b/drivers/mtd_emulated/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/drivers/mtd_emulated/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/drivers/mtd_emulated/mtd_emulated.c b/drivers/mtd_emulated/mtd_emulated.c new file mode 100644 index 0000000000..68709bfcf7 --- /dev/null +++ b/drivers/mtd_emulated/mtd_emulated.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2023 Gunar Schorcht + * + * 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. + */ + +#include +#include + +#include "assert.h" +#include "macros/utils.h" +#include "mtd_emulated.h" + +static int _init(mtd_dev_t *dev) +{ + mtd_emulated_t *mtd = (mtd_emulated_t *)dev; + assert(mtd); + + if (!mtd->init_done) { + memset(mtd->memory, 0xff, mtd->size); + mtd->init_done = true; + } + return 0; +} + +static int _read(mtd_dev_t *dev, void *dest, uint32_t addr, uint32_t count) +{ + mtd_emulated_t *mtd = (mtd_emulated_t *)dev; + + assert(mtd); + assert(dest); + + if ((addr + count) > mtd->size) { + /* addr + count must not exceed the size of memory */ + return -EOVERFLOW; + } + memcpy(dest, mtd->memory + addr, count); + + return 0; +} + +static int _read_page(mtd_dev_t *dev, void *dest, + uint32_t page, uint32_t offset, uint32_t size) +{ + mtd_emulated_t *mtd = (mtd_emulated_t *)dev; + + (void)mtd; + + assert(mtd); + assert(dest); + + if (((page * mtd->base.page_size) + offset + size) > mtd->size) { + /* page addr + offset + size must not exceed the size of memory */ + return -EOVERFLOW; + } + memcpy(dest, mtd->memory + (page * mtd->base.page_size) + offset, size); + + return size; +} + +static int _write(mtd_dev_t *dev, const void *src, uint32_t addr, uint32_t count) +{ + mtd_emulated_t *mtd = (mtd_emulated_t *)dev; + + (void)mtd; + + assert(mtd); + assert(src); + + if (/* addr + count must be inside a page boundary. */ + (((addr % mtd->base.page_size) + count) > mtd->base.page_size) || + /* addr + count must not exceed the size of memory */ + ((addr + count) > mtd->size)) { + return -EOVERFLOW; + } + memcpy(mtd->memory + addr, src, count); + + return 0; +} + +int _write_page(mtd_dev_t *dev, const void *src, + uint32_t page, uint32_t offset, uint32_t size) +{ + mtd_emulated_t *mtd = (mtd_emulated_t *)dev; + + (void)mtd; + + assert(mtd); + assert(src); + + if (/* offset must be smaller than the page size */ + (offset >= mtd->base.page_size) || + /* page addr + offset + size must not exceed the size of memory */ + ((page * mtd->base.page_size) + offset + size) > mtd->size) { + return -EOVERFLOW; + } + memcpy(mtd->memory + (page * mtd->base.page_size) + offset, src, size); + + return size; +} + +static int _erase(mtd_dev_t *dev, uint32_t addr, uint32_t count) +{ + mtd_emulated_t *mtd = (mtd_emulated_t *)dev; + + (void)mtd; + assert(mtd); + + if (/* addr must be aligned on a sector boundary */ + (addr % (mtd->base.pages_per_sector * mtd->base.page_size) != 0) || + /* count must be a multiple of a sector size. */ + (count % (mtd->base.pages_per_sector * mtd->base.page_size) != 0) || + /* addr + count must not exceed the size of memory */ + ((addr + count) > mtd->size)) { + return -EOVERFLOW; + } + + memset(mtd->memory + addr, 0xff, count); + + return 0; +} + +static int _erase_sector(mtd_dev_t *dev, uint32_t sector, uint32_t num) +{ + mtd_emulated_t *mtd = (mtd_emulated_t *)dev; + + (void)mtd; + assert(mtd); + + if (/* sector must not exceed the number of sectors */ + (sector >= mtd->base.sector_count) || + /* sector + num must not exceed the number of sectors */ + ((sector + num) > mtd->base.sector_count)) { + return -EOVERFLOW; + } + + memset(mtd->memory + (sector * (mtd->base.pages_per_sector * mtd->base.page_size)), + 0xff, num * (mtd->base.pages_per_sector * mtd->base.page_size)); + + return 0; +} + +static int _power(mtd_dev_t *dev, enum mtd_power_state power) +{ + (void)dev; + (void)power; + return 0; +} + +const mtd_desc_t _mtd_emulated_driver = { + .init = _init, + .read = _read, + .read_page = _read_page, + .write = _write, + .write_page = _write_page, + .erase = _erase, + .erase_sector = _erase_sector, + .power = _power, +}; From 0cdcac96bc29d197b59259ae24432b52d96c000d Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Tue, 11 Apr 2023 08:39:53 +0200 Subject: [PATCH 03/10] tests/unittests/test-mtd: use emulated MTD as test mockup --- tests/unittests/tests-mtd/Makefile.include | 1 + tests/unittests/tests-mtd/tests-mtd.c | 86 ++-------------------- 2 files changed, 6 insertions(+), 81 deletions(-) diff --git a/tests/unittests/tests-mtd/Makefile.include b/tests/unittests/tests-mtd/Makefile.include index d663df8acc..e3ea225579 100644 --- a/tests/unittests/tests-mtd/Makefile.include +++ b/tests/unittests/tests-mtd/Makefile.include @@ -1,2 +1,3 @@ USEMODULE += mtd +USEMODULE += mtd_emulated USEMODULE += vfs diff --git a/tests/unittests/tests-mtd/tests-mtd.c b/tests/unittests/tests-mtd/tests-mtd.c index 23174f2c43..f22e95ab2d 100644 --- a/tests/unittests/tests-mtd/tests-mtd.c +++ b/tests/unittests/tests-mtd/tests-mtd.c @@ -29,6 +29,9 @@ #ifdef MTD_0 #define dev (MTD_0) #else + +#include "mtd_emulated.h" + /* Test mock object implementing a simple RAM-based mtd */ #ifndef SECTOR_COUNT #define SECTOR_COUNT 4 @@ -39,89 +42,10 @@ #ifndef PAGE_SIZE #define PAGE_SIZE 128 #endif -#ifndef WRITE_SIZE -#define WRITE_SIZE 1 -#endif -static uint8_t dummy_memory[PAGE_PER_SECTOR * PAGE_SIZE * SECTOR_COUNT]; +MTD_EMULATED_DEV(0, SECTOR_COUNT, PAGE_PER_SECTOR, PAGE_SIZE); -static int _init(mtd_dev_t *dev) -{ - (void)dev; - - memset(dummy_memory, 0xff, sizeof(dummy_memory)); - return 0; -} - -static int _read(mtd_dev_t *dev, void *buff, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - memcpy(buff, dummy_memory + addr, size); - - return 0; -} - -static int _write(mtd_dev_t *dev, const void *buff, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - if (((addr % PAGE_SIZE) + size) > PAGE_SIZE) { - return -EOVERFLOW; - } - memcpy(dummy_memory + addr, buff, size); - - return 0; -} - -static int _erase(mtd_dev_t *dev, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (size % (PAGE_PER_SECTOR * PAGE_SIZE) != 0) { - return -EOVERFLOW; - } - if (addr % (PAGE_PER_SECTOR * PAGE_SIZE) != 0) { - return -EOVERFLOW; - } - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - memset(dummy_memory + addr, 0xff, size); - - return 0; -} - -static int _power(mtd_dev_t *dev, enum mtd_power_state power) -{ - (void)dev; - (void)power; - return 0; -} - -static const mtd_desc_t driver = { - .init = _init, - .read = _read, - .write = _write, - .erase = _erase, - .power = _power, -}; - -static mtd_dev_t _dev = { - .driver = &driver, - .sector_count = SECTOR_COUNT, - .pages_per_sector = PAGE_PER_SECTOR, - .page_size = PAGE_SIZE, - .write_size = WRITE_SIZE, -}; - -static mtd_dev_t *dev = (mtd_dev_t*) &_dev; +#define dev (&mtd_emulated_dev0.base) #endif /* MTD_0 */ From af5b75a9a14c401bc1167a791b35606140aecc54 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sun, 2 Apr 2023 16:34:11 +0200 Subject: [PATCH 04/10] tests/littlefs: use emulated MTD as test mockup --- tests/pkg_littlefs/Makefile | 1 + tests/pkg_littlefs/main.c | 88 +++---------------------------------- 2 files changed, 8 insertions(+), 81 deletions(-) diff --git a/tests/pkg_littlefs/Makefile b/tests/pkg_littlefs/Makefile index 0cff046cf2..d3c0eab1a7 100644 --- a/tests/pkg_littlefs/Makefile +++ b/tests/pkg_littlefs/Makefile @@ -2,5 +2,6 @@ include ../Makefile.tests_common USEMODULE += littlefs USEMODULE += embunit +USEMODULE += mtd_emulated include $(RIOTBASE)/Makefile.include diff --git a/tests/pkg_littlefs/main.c b/tests/pkg_littlefs/main.c index 1586148ba5..c892d525fe 100644 --- a/tests/pkg_littlefs/main.c +++ b/tests/pkg_littlefs/main.c @@ -27,9 +27,13 @@ * CONFIG_USE_HARDWARE_MTD is defined (add CFLAGS=-DCONFIG_USE_HARDWARE_MTD to * the command line to enable it */ #if defined(MTD_0) && IS_ACTIVE(CONFIG_USE_HARDWARE_MTD) -#define USE_MTD_0 + #define _dev (MTD_0) + #else + +#include "mtd_emulated.h" + /* Test mock object implementing a simple RAM-based mtd */ #ifndef SECTOR_COUNT #define SECTOR_COUNT 16 @@ -41,84 +45,10 @@ #define PAGE_SIZE 64 #endif -static uint8_t dummy_memory[PAGE_PER_SECTOR * PAGE_SIZE * SECTOR_COUNT]; +MTD_EMULATED_DEV(0, SECTOR_COUNT, PAGE_PER_SECTOR, PAGE_SIZE); -static int _init(mtd_dev_t *dev) -{ - (void)dev; +#define _dev (&mtd_emulated_dev0.base) - return 0; -} - -static int _read(mtd_dev_t *dev, void *buff, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - memcpy(buff, dummy_memory + addr, size); - - return 0; -} - -static int _write(mtd_dev_t *dev, const void *buff, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - if (size > PAGE_SIZE) { - return -EOVERFLOW; - } - memcpy(dummy_memory + addr, buff, size); - - return 0; -} - -static int _erase(mtd_dev_t *dev, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (size % (PAGE_PER_SECTOR * PAGE_SIZE) != 0) { - return -EOVERFLOW; - } - if (addr % (PAGE_PER_SECTOR * PAGE_SIZE) != 0) { - return -EOVERFLOW; - } - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - memset(dummy_memory + addr, 0xff, size); - - return 0; -} - -static int _power(mtd_dev_t *dev, enum mtd_power_state power) -{ - (void)dev; - (void)power; - return 0; -} - -static const mtd_desc_t driver = { - .init = _init, - .read = _read, - .write = _write, - .erase = _erase, - .power = _power, -}; - -static mtd_dev_t dev = { - .driver = &driver, - .sector_count = SECTOR_COUNT, - .pages_per_sector = PAGE_PER_SECTOR, - .page_size = PAGE_SIZE, - .write_size = 1, -}; - -static mtd_dev_t *_dev = (mtd_dev_t*) &dev; #endif /* MTD_0 */ static littlefs_desc_t littlefs_desc; @@ -414,10 +344,6 @@ static void tests_littlefs_statvfs(void) Test *tests_littlefs(void) { -#ifndef USE_MTD_0 - memset(dummy_memory, 0xff, sizeof(dummy_memory)); -#endif - EMB_UNIT_TESTFIXTURES(fixtures) { new_TestFixture(tests_littlefs_format), new_TestFixture(tests_littlefs_mount_umount), From f724f34ac2366d19d89c1484fc99257d047e34a8 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sun, 2 Apr 2023 16:34:33 +0200 Subject: [PATCH 05/10] tests/littlefs2: use emulated MTD as test mockup --- tests/pkg_littlefs2/Makefile | 1 + tests/pkg_littlefs2/app.config.test | 1 + tests/pkg_littlefs2/main.c | 88 +++-------------------------- 3 files changed, 9 insertions(+), 81 deletions(-) diff --git a/tests/pkg_littlefs2/Makefile b/tests/pkg_littlefs2/Makefile index 07eef1db2c..ec9c0568a6 100644 --- a/tests/pkg_littlefs2/Makefile +++ b/tests/pkg_littlefs2/Makefile @@ -2,5 +2,6 @@ include ../Makefile.tests_common USEPKG += littlefs2 USEMODULE += embunit +USEMODULE += mtd_emulated include $(RIOTBASE)/Makefile.include diff --git a/tests/pkg_littlefs2/app.config.test b/tests/pkg_littlefs2/app.config.test index 3a3d184936..5aa1b1e84e 100644 --- a/tests/pkg_littlefs2/app.config.test +++ b/tests/pkg_littlefs2/app.config.test @@ -1,2 +1,3 @@ CONFIG_MODULE_EMBUNIT=y +CONFIG_MODULE_MTD_EMULATED=y CONFIG_PACKAGE_LITTLEFS2=y diff --git a/tests/pkg_littlefs2/main.c b/tests/pkg_littlefs2/main.c index df33d559fb..b555ff1bdd 100644 --- a/tests/pkg_littlefs2/main.c +++ b/tests/pkg_littlefs2/main.c @@ -27,9 +27,13 @@ * CONFIG_USE_HARDWARE_MTD is defined (add CFLAGS=-DCONFIG_USE_HARDWARE_MTD to * the command line to enable it */ #if defined(MTD_0) && IS_ACTIVE(CONFIG_USE_HARDWARE_MTD) -#define USE_MTD_0 + #define _dev (MTD_0) + #else + +#include "mtd_emulated.h" + /* Test mock object implementing a simple RAM-based mtd */ #ifndef SECTOR_COUNT #define SECTOR_COUNT 16 @@ -41,84 +45,10 @@ #define PAGE_SIZE 64 #endif -static uint8_t dummy_memory[PAGE_PER_SECTOR * PAGE_SIZE * SECTOR_COUNT]; +MTD_EMULATED_DEV(0, SECTOR_COUNT, PAGE_PER_SECTOR, PAGE_SIZE); -static int _init(mtd_dev_t *dev) -{ - (void)dev; +#define _dev (&mtd_emulated_dev0.base) - return 0; -} - -static int _read(mtd_dev_t *dev, void *buff, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - memcpy(buff, dummy_memory + addr, size); - - return 0; -} - -static int _write(mtd_dev_t *dev, const void *buff, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - if (size > PAGE_SIZE) { - return -EOVERFLOW; - } - memcpy(dummy_memory + addr, buff, size); - - return 0; -} - -static int _erase(mtd_dev_t *dev, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (size % (PAGE_PER_SECTOR * PAGE_SIZE) != 0) { - return -EOVERFLOW; - } - if (addr % (PAGE_PER_SECTOR * PAGE_SIZE) != 0) { - return -EOVERFLOW; - } - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - memset(dummy_memory + addr, 0xff, size); - - return 0; -} - -static int _power(mtd_dev_t *dev, enum mtd_power_state power) -{ - (void)dev; - (void)power; - return 0; -} - -static const mtd_desc_t driver = { - .init = _init, - .read = _read, - .write = _write, - .erase = _erase, - .power = _power, -}; - -static mtd_dev_t dev = { - .driver = &driver, - .sector_count = SECTOR_COUNT, - .pages_per_sector = PAGE_PER_SECTOR, - .page_size = PAGE_SIZE, - .write_size = 1, -}; - -static mtd_dev_t *_dev = (mtd_dev_t*) &dev; #endif /* MTD_0 */ static littlefs2_desc_t littlefs_desc; @@ -416,10 +346,6 @@ static void tests_littlefs_statvfs(void) Test *tests_littlefs(void) { -#ifndef USE_MTD_0 - memset(dummy_memory, 0xff, sizeof(dummy_memory)); -#endif - EMB_UNIT_TESTFIXTURES(fixtures) { new_TestFixture(tests_littlefs_format), new_TestFixture(tests_littlefs_mount_umount), From 631df7c69cec6390d628a541f3dd8e36430f2a48 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Sun, 2 Apr 2023 16:34:53 +0200 Subject: [PATCH 06/10] tests/spiffs: use emulated MTD as test mockup --- tests/pkg_spiffs/Makefile | 1 + tests/pkg_spiffs/main.c | 86 ++++----------------------------------- 2 files changed, 8 insertions(+), 79 deletions(-) diff --git a/tests/pkg_spiffs/Makefile b/tests/pkg_spiffs/Makefile index d52effe4bf..c7c7a08147 100644 --- a/tests/pkg_spiffs/Makefile +++ b/tests/pkg_spiffs/Makefile @@ -2,5 +2,6 @@ include ../Makefile.tests_common USEMODULE += spiffs USEMODULE += embunit +USEMODULE += mtd_emulated include $(RIOTBASE)/Makefile.include diff --git a/tests/pkg_spiffs/main.c b/tests/pkg_spiffs/main.c index e66a383f9f..08ea7a205f 100644 --- a/tests/pkg_spiffs/main.c +++ b/tests/pkg_spiffs/main.c @@ -25,9 +25,13 @@ * CONFIG_USE_HARDWARE_MTD is defined (add CFLAGS=-DCONFIG_USE_HARDWARE_MTD to * the command line to enable it */ #if defined(MTD_0) && IS_ACTIVE(CONFIG_USE_HARDWARE_MTD) -#define USE_MTD_0 + #define _dev (MTD_0) + #else + +#include "mtd_emulated.h" + /* Test mock object implementing a simple RAM-based mtd */ #ifndef SECTOR_COUNT #define SECTOR_COUNT 4 @@ -39,83 +43,10 @@ #define PAGE_SIZE 128 #endif -static uint8_t dummy_memory[PAGE_PER_SECTOR * PAGE_SIZE * SECTOR_COUNT]; +MTD_EMULATED_DEV(0, SECTOR_COUNT, PAGE_PER_SECTOR, PAGE_SIZE); -static int _init(mtd_dev_t *dev) -{ - (void)dev; - return 0; -} +#define _dev (&mtd_emulated_dev0.base) -static int _read(mtd_dev_t *dev, void *buff, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - memcpy(buff, dummy_memory + addr, size); - - return 0; -} - -static int _write(mtd_dev_t *dev, const void *buff, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - if (size > PAGE_SIZE) { - return -EOVERFLOW; - } - memcpy(dummy_memory + addr, buff, size); - - return 0; -} - -static int _erase(mtd_dev_t *dev, uint32_t addr, uint32_t size) -{ - (void)dev; - - if (size % (PAGE_PER_SECTOR * PAGE_SIZE) != 0) { - return -EOVERFLOW; - } - if (addr % (PAGE_PER_SECTOR * PAGE_SIZE) != 0) { - return -EOVERFLOW; - } - if (addr + size > sizeof(dummy_memory)) { - return -EOVERFLOW; - } - memset(dummy_memory + addr, 0xff, size); - - return 0; -} - -static int _power(mtd_dev_t *dev, enum mtd_power_state power) -{ - (void)dev; - (void)power; - return 0; -} - -static const mtd_desc_t driver = { - .init = _init, - .read = _read, - .write = _write, - .erase = _erase, - .power = _power, -}; - -static mtd_dev_t dev = { - .driver = &driver, - .sector_count = SECTOR_COUNT, - .pages_per_sector = PAGE_PER_SECTOR, - .page_size = PAGE_SIZE, - .write_size = 1, -}; - -static mtd_dev_t *_dev = (mtd_dev_t*) &dev; #endif /* MTD_0 */ static struct spiffs_desc spiffs_desc = { @@ -439,9 +370,6 @@ static void tests_spiffs_partition(void) Test *tests_spiffs(void) { -#ifndef USE_MTD_0 - memset(dummy_memory, 0xff, sizeof(dummy_memory)); -#endif EMB_UNIT_TESTFIXTURES(fixtures) { new_TestFixture(tests_spiffs_format), new_TestFixture(tests_spiffs_mount_umount), From 4bb283cb4b3779784485487595cd84e9f093fb98 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Tue, 4 Apr 2023 23:49:27 +0200 Subject: [PATCH 07/10] tests/usbus_msc: use emulated MTD as test mockup --- tests/usbus_msc/Makefile | 7 ++++++- tests/usbus_msc/README.md | 13 +++++++++++++ tests/usbus_msc/main.c | 26 ++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/tests/usbus_msc/Makefile b/tests/usbus_msc/Makefile index b30038d251..b9f051727b 100644 --- a/tests/usbus_msc/Makefile +++ b/tests/usbus_msc/Makefile @@ -5,7 +5,7 @@ include ../Makefile.tests_common # This has to be the absolute path to the RIOT base directory: RIOTBASE ?= $(CURDIR)/../.. - # Comment this out to disable code in RIOT that does safety checking +# Comment this out to disable code in RIOT that does safety checking # which is not needed in a production environment but helps in the # development process: DEVELHELP ?= 1 @@ -19,6 +19,11 @@ USEMODULE += shell USEMODULE += usbus_msc USEMODULE += ztimer_msec +# If your board does not provide a MTD for testing, use the following line +# to emulate an MTD with 64 sectors with 4 pages of 128 bytes each in RAM. You +# can override these parameters by SECTOR_COUNT, PAGES_PER_SECTOR and PAGE_SIZE. +# USEMODULE += mtd_emulated + # Change this to 0 show compiler invocation lines by default: QUIET ?= 1 diff --git a/tests/usbus_msc/README.md b/tests/usbus_msc/README.md index 4ba3fe49fe..001396f5e3 100644 --- a/tests/usbus_msc/README.md +++ b/tests/usbus_msc/README.md @@ -39,6 +39,19 @@ by attaching it to the host with the command: At this point, the USBUS stack will export the selected MTD devices. Devices should appears under /dev/sdX entries. +If the board does not provide a MTD device, a MTD device can be emulated in RAM +for testing using module `mtd_emulated`: +``` +USEMODULE=mtd_emulated BOARD=... make ... +``` +The emulated MTD device has by default 64 sectors with 4 pages of 128 bytes +each, the minimum size to be able to create a partition with FAT file system. +These default parameters can be overridden e.g. by `SECTOR_COUNT`, +`PAGES_PER_SECTOR` and `PAGE_SIZE`: +``` +CFLAGS='-DSECTOR_COUNT=128' USEMODULE=mtd_emulated BOARD=... make ... +``` + **Notes:** Depending on the MTD device and the USB speed, this operation can take some times. USB operation can be stopped at any time using: diff --git a/tests/usbus_msc/main.c b/tests/usbus_msc/main.c index 17870b693a..56020aff48 100644 --- a/tests/usbus_msc/main.c +++ b/tests/usbus_msc/main.c @@ -22,6 +22,32 @@ #include #include +#include "board.h" + +#if defined(MODULE_MTD_EMULATED) + +#include "mtd_emulated.h" + +/* The following parameters are only suitable for testing the basic functions + * of USB MSC. To create a partition with a FAT file system, at least 64 sectors + * have to be used. */ + +#ifndef SECTOR_COUNT +#define SECTOR_COUNT 64 +#endif + +#ifndef PAGES_PER_SECTOR +#define PAGES_PER_SECTOR 4 +#endif + +#ifndef PAGE_SIZE +#define PAGE_SIZE 128 +#endif + +MTD_EMULATED_DEV(0, SECTOR_COUNT, PAGES_PER_SECTOR, PAGE_SIZE); + +#endif /* MODULE_MTD_EMULATED */ + #include "mtd_default.h" #include "shell.h" #include "usb/usbus.h" From 1d4d3e47b80c381fb6d9cb1118030399fad1b7f6 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Tue, 11 Apr 2023 08:56:54 +0200 Subject: [PATCH 08/10] drivers/mtd_default: expose one SD Card and one MTD emulated --- drivers/include/mtd_default.h | 61 ++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 16 deletions(-) diff --git a/drivers/include/mtd_default.h b/drivers/include/mtd_default.h index 27f17dba5e..e8190c2316 100644 --- a/drivers/include/mtd_default.h +++ b/drivers/include/mtd_default.h @@ -18,27 +18,51 @@ #define MTD_DEFAULT_H #include "board.h" +#include "modules.h" #include "mtd.h" #ifdef __cplusplus extern "C" { #endif +#if defined(MODULE_MTD_SDCARD_DEFAULT) +#include "mtd_sdcard.h" +#endif + +#if defined(MODULE_MTD_EMULATED) +#include "mtd_emulated.h" +#endif + +#if !defined(MTD_NUMOF) && !DOXYGEN + +#if defined(MTD_3) +#define MTD_BOARD_NUMOF 4 +#elif defined(MTD_2) +#define MTD_BOARD_NUMOF 3 +#elif defined(MTD_1) +#define MTD_BOARD_NUMOF 2 +#elif defined(MTD_0) +#define MTD_BOARD_NUMOF 1 +#else +#define MTD_BOARD_NUMOF 0 +#endif + +#define MTD_SDCARD_NUMOF IS_USED(MODULE_MTD_SDCARD_DEFAULT) +#define MTD_EMULATED_NUMOF IS_USED(MODULE_MTD_EMULATED) + /** * @brief Number of MTD devices */ -#ifndef MTD_NUMOF -#if defined(MTD_3) -#define MTD_NUMOF 4 -#elif defined(MTD_2) -#define MTD_NUMOF 3 -#elif defined(MTD_1) -#define MTD_NUMOF 2 -#elif defined(MTD_0) -#define MTD_NUMOF 1 -#else -#define MTD_NUMOF 0 +#define MTD_NUMOF (MTD_BOARD_NUMOF + MTD_SDCARD_NUMOF + MTD_EMULATED_NUMOF) + +#endif /* !defined(MTD_NUMOF) && !DOXYGEN */ + +#if defined(MODULE_MTD_SDCARD_DEFAULT) +extern mtd_sdcard_t mtd_sdcard_dev0; #endif + +#if defined(MODULE_MTD_EMULATED) +extern mtd_emulated_t mtd_emulated_dev0; #endif /** @@ -52,20 +76,25 @@ extern "C" { static inline mtd_dev_t *mtd_default_get_dev(unsigned idx) { switch (idx) { -#ifdef MTD_0 +#if MTD_BOARD_NUMOF > 0 case 0: return MTD_0; #endif -#ifdef MTD_1 +#if MTD_BOARD_NUMOF > 1 case 1: return MTD_1; #endif -#ifdef MTD_2 +#if MTD_BOARD_NUMOF > 2 case 2: return MTD_2; #endif -#ifdef MTD_3 +#if MTD_BOARD_NUMOF > 3 case 3: return MTD_3; +#endif +#if MTD_SDCARD_NUMOF > 0 + case MTD_BOARD_NUMOF: return (mtd_dev_t *)&mtd_sdcard_dev0; +#endif +#if MTD_EMULATED_NUMOF > 0 + case MTD_BOARD_NUMOF + MTD_SDCARD_NUMOF: return (mtd_dev_t *)&mtd_emulated_dev0; #endif } - return NULL; } From 4af1fa6a3d8dd7504f91300c371de30c6b51c839 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Wed, 12 Apr 2023 11:23:58 +0200 Subject: [PATCH 09/10] tests/littlefs: reduce sector count for emulated MTD A `SECTOR_COUNT` of 12 seems to be sufficient to work for this test in emulated MTD. --- tests/pkg_littlefs/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pkg_littlefs/main.c b/tests/pkg_littlefs/main.c index c892d525fe..dc7f63b96a 100644 --- a/tests/pkg_littlefs/main.c +++ b/tests/pkg_littlefs/main.c @@ -36,7 +36,7 @@ /* Test mock object implementing a simple RAM-based mtd */ #ifndef SECTOR_COUNT -#define SECTOR_COUNT 16 +#define SECTOR_COUNT 12 #endif #ifndef PAGE_PER_SECTOR #define PAGE_PER_SECTOR 4 From 89f18c78210576badfe75f59daeec2f785a53ed2 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Wed, 12 Apr 2023 11:37:24 +0200 Subject: [PATCH 10/10] tests/littlefs: remove blacklisted boards due to reduced sector count Removing boards blacklisted for insufficient memory after reducing the number of sectors of the emulated MTD. --- tests/pkg_littlefs/Makefile.ci | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/pkg_littlefs/Makefile.ci b/tests/pkg_littlefs/Makefile.ci index 1de338a5bd..0e4d2fbd23 100644 --- a/tests/pkg_littlefs/Makefile.ci +++ b/tests/pkg_littlefs/Makefile.ci @@ -5,18 +5,12 @@ BOARD_INSUFFICIENT_MEMORY := \ arduino-uno \ atmega328p \ atmega328p-xplained-mini \ - i-nucleo-lrwan1 \ msb-430 \ msb-430h \ - nucleo-f030r8 \ nucleo-f031k6 \ nucleo-f042k6 \ nucleo-l011k4 \ - nucleo-l031k6 \ - nucleo-l053r8 \ samd10-xmini \ stk3200 \ stm32f030f4-demo \ - stm32f0discovery \ - stm32l0538-disco \ #