Skip to content

Commit

Permalink
Merge #19443
Browse files Browse the repository at this point in the history
19443: drivers: add support for MTDs emulated in RAM r=dylad a=gschorcht

### Contribution description

This PR adds a driver to provide MTDs that are emulated in RAM. It allows to test MTD-based applications on boards that do not provide MTDs by hardware.

It includes also some small documentation fixes for `mtd.h` that were found while writing the driver.

### Testing procedure

The following tests should work on any board:

`tests/pkg_littlefs`
`tests/pkg_littlefs2`
`tests/pkg_spiffs`

### Issues/PRs references


Co-authored-by: Gunar Schorcht <gunar@schorcht.net>
  • Loading branch information
bors[bot] and gschorcht authored Apr 12, 2023
2 parents 10e4d50 + 89f18c7 commit b342cdc
Show file tree
Hide file tree
Showing 19 changed files with 395 additions and 352 deletions.
16 changes: 8 additions & 8 deletions drivers/include/mtd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
57 changes: 43 additions & 14 deletions drivers/include/mtd_default.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,51 @@
#define MTD_DEFAULT_H

#include "board.h"
#include "modules.h"
#include "mtd.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Number of MTD devices
*/
#ifndef MTD_NUMOF
#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_NUMOF 4
#define MTD_BOARD_NUMOF 4
#elif defined(MTD_2)
#define MTD_NUMOF 3
#define MTD_BOARD_NUMOF 3
#elif defined(MTD_1)
#define MTD_NUMOF 2
#define MTD_BOARD_NUMOF 2
#elif defined(MTD_0)
#define MTD_NUMOF 1
#define MTD_BOARD_NUMOF 1
#else
#define MTD_NUMOF 0
#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
*/
#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

/**
Expand All @@ -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;
}

Expand Down
102 changes: 102 additions & 0 deletions drivers/include/mtd_emulated.h
Original file line number Diff line number Diff line change
@@ -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 <gunar@schorcht.net>
*/
#ifndef MTD_EMULATED_H
#define MTD_EMULATED_H

#include <stdbool.h>

#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 */
/** @} */
3 changes: 3 additions & 0 deletions drivers/mtd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions drivers/mtd_emulated/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base
Loading

0 comments on commit b342cdc

Please sign in to comment.