Memory Technology Device

Low level Memory Technology Device interface. More...

Detailed Description

Low level Memory Technology Device interface.

Generic memory technology device interface

Unlike the Flash page driver, this is device driver based (i.e. all functions take a mtd_dev_t as a first argument), so that SPI based EEPROMs (e.g. AT25xxx) can be accessed the same way as internal flash or SD cards), all inside the same application.

MTD devices expose a block based erase and write interface. In that, they are the distinct from block devices (like hard disks) on which individual bytes can be overwritten. The Linux MTD FAQ has a convenient comparison (beware though of terminology differences outlined below). They can be erased (with some granularity, often wearing out the erased area a bit), and erased areas can be written to (sometimes multiple times).

MTD devices are described in terms of sectors, pages and feature flags:

Unless a flag (such as MTD_DRIVER_FLAG_DIRECT_WRITE or MTD_DRIVER_FLAG_CLEARING_OVERWRITE) allows it, this MTD API does not allow memory areas to be written to twice between erase operations. Drivers are not expected to count write accesses, and neither do this module's functions: The performance impact would be too great. It is up to the application to only write to erased memory once. Failure to do so may damage hardware.

This MTD API currently does not specify which value will be read from an erased sector.

Modules

 MTD wrapper for emulated MTD devices
 MTD device that is emulated in RAM for test purposes.
 
 Native MTD
 mtd flash emulation for native
 

Files

file  mtd.h
 

Data Structures

struct  mtd_dev_t
 MTD device descriptor. More...
 
struct  mtd_desc
 MTD driver interface. More...
 

Macros

#define MTD_XFA_ADD(dev, idx)    XFA_CONST(mtd_dev_xfa, idx) mtd_dev_t *mtd ## idx = (mtd_dev_t *)&(dev)
 Define MTD device pointer variable mtd<idx> More...
 
#define MTD_NUMOF   XFA_LEN(mtd_dev_t *, mtd_dev_xfa)
 Number of MTDs defined in the MTD device array in XFA. More...
 
#define MTD_DRIVER_FLAG_DIRECT_WRITE   (1 << 0)
 MTD driver can write any data to the storage without erasing it first. More...
 
#define MTD_DRIVER_FLAG_CLEARING_OVERWRITE   (1 << 1)
 MTD driver supports arbitrary clearing overwrites. More...
 

Typedefs

typedef struct mtd_desc mtd_desc_t
 MTD driver interface. More...
 

Enumerations

enum  mtd_power_state { MTD_POWER_UP , MTD_POWER_DOWN }
 MTD power states. More...
 

Functions

int mtd_init (mtd_dev_t *mtd)
 mtd_init Initialize a MTD device More...
 
int mtd_read (mtd_dev_t *mtd, void *dest, uint32_t addr, uint32_t count)
 Read data from a MTD device. More...
 
int mtd_read_page (mtd_dev_t *mtd, void *dest, uint32_t page, uint32_t offset, uint32_t size)
 Read data from a MTD device with pagewise addressing. More...
 
int mtd_write (mtd_dev_t *mtd, const void *src, uint32_t addr, uint32_t count)
 Write data to a MTD device. More...
 
int mtd_write_page_raw (mtd_dev_t *mtd, const void *src, uint32_t page, uint32_t offset, uint32_t size)
 Write data to a MTD device with pagewise addressing. More...
 
int mtd_write_page (mtd_dev_t *mtd, const void *src, uint32_t page, uint32_t offset, uint32_t size)
 Write data to a MTD device with pagewise addressing. More...
 
int mtd_erase (mtd_dev_t *mtd, uint32_t addr, uint32_t count)
 Erase sectors of a MTD device. More...
 
int mtd_erase_sector (mtd_dev_t *mtd, uint32_t sector, uint32_t num)
 Erase sectors of a MTD device. More...
 
int mtd_write_sector (mtd_dev_t *mtd, const void *src, uint32_t sector, uint32_t num)
 Write data to a MTD device with whole sector writes. More...
 
int mtd_power (mtd_dev_t *mtd, enum mtd_power_state power)
 Set power mode on a MTD device. More...
 
static mtd_dev_tmtd_dev_get (unsigned idx)
 Get an MTD device by index. More...
 

Variables

mtd_dev_t *const mtd_dev_xfa []
 MTD device array as XFA. More...
 
static mtd_dev_tmtd_default_get_dev (unsigned idx)
 Default MTD device configuration. More...
 

Macro Definition Documentation

◆ MTD_DRIVER_FLAG_CLEARING_OVERWRITE

#define MTD_DRIVER_FLAG_CLEARING_OVERWRITE   (1 << 1)

MTD driver supports arbitrary clearing overwrites.

If this is set, (arbitrarily) many writes are permitted per write size, and the result is the old value bitwise-AND the written value.

This property is common for managed flash memories. (By comparison, the raw flash often used internally by MCUs may not allow overwrites, or may allow them with the same semantics, but only for a limited number of writes between erasures; there is currently no flag describing these any further).

Definition at line 192 of file mtd.h.

◆ MTD_DRIVER_FLAG_DIRECT_WRITE

#define MTD_DRIVER_FLAG_DIRECT_WRITE   (1 << 0)

MTD driver can write any data to the storage without erasing it first.

If this is set, a write completely overrides the previous values.

Definition at line 179 of file mtd.h.

◆ MTD_NUMOF

#define MTD_NUMOF   XFA_LEN(mtd_dev_t *, mtd_dev_xfa)

Number of MTDs defined in the MTD device array in XFA.

Definition at line 172 of file mtd.h.

◆ MTD_XFA_ADD

#define MTD_XFA_ADD (   dev,
  idx 
)     XFA_CONST(mtd_dev_xfa, idx) mtd_dev_t *mtd ## idx = (mtd_dev_t *)&(dev)

Define MTD device pointer variable mtd<idx>

The macro defines the MTD device pointer variable mtd<idx>, sets it to the address of the MTD device specified by the dev parameter, and adds it to the XFA of MTD device pointers mtd_dev_xfa. For example

MTD_XFA_ADD(my_dev, 1);
#define MTD_XFA_ADD(dev, idx)
Define MTD device pointer variable mtd<idx>
Definition: mtd.h:166

defines the variable mtd1 pointing to the device my_dev.

The parameter idx is used as priority of the MTD device pointer within the XFA. That means it determines the order of the MTD device pointers within mtd_dev_xfa.

Note
Only if each MTD device is added with a unique priority and only if the priorities start at 0 and are used in consecutive order, the parameter idx corresponds to the position of the MTD device pointer within the mtd_dev_xfa XFA and mtd_dev_xfa[i] points to the i-th MTD device.
Parameters
devMTD device
idxPriority of the MTD device pointer within the XFA

Definition at line 166 of file mtd.h.

Typedef Documentation

◆ mtd_desc_t

typedef struct mtd_desc mtd_desc_t

MTD driver interface.

This define the functions to access a MTD.

A MTD is composed of pages combined into sectors. A sector is the smallest erasable unit. The number of pages in a sector must be constant for the whole MTD.

The erase operation is available only for entire sectors.

Definition at line 104 of file mtd.h.

Enumeration Type Documentation

◆ mtd_power_state

MTD power states.

Enumerator
MTD_POWER_UP 

Power up.

MTD_POWER_DOWN 

Power down.

Definition at line 89 of file mtd.h.

Function Documentation

◆ mtd_default_get_dev()

static mtd_dev_t * mtd_default_get_dev ( unsigned  idx)
inlinestatic

Default MTD device configuration.

Helpers for generic MTD use.

Author
Benjamin Valentin benja.nosp@m.min..nosp@m.valen.nosp@m.tin@.nosp@m.ml-pa.nosp@m..com

Get the default MTD device by index

Deprecated:
Use mtd_dev_get instead
Parameters
[in]idxIndex of the MTD device
Returns
MTD_0 for idx 0 and so on NULL if no MTD device exists for the given index

Definition at line 54 of file mtd_default.h.

◆ mtd_dev_get()

static mtd_dev_t * mtd_dev_get ( unsigned  idx)
inlinestatic

Get an MTD device by index.

Parameters
[in]idxIndex of the MTD device
Returns
MTD_0 for idx 0 and so on NULL if no MTD device exists for the given index

Definition at line 535 of file mtd.h.

◆ mtd_erase()

int mtd_erase ( mtd_dev_t mtd,
uint32_t  addr,
uint32_t  count 
)

Erase sectors of a MTD device.

addr must be aligned on a sector boundary. count must be a multiple of a sector size.

Parameters
mtdthe device to erase
[in]addrthe address of the first sector to erase
[in]countthe number of bytes to erase
Return values
0if erase successful
<0if an error occurred
-ENODEVif mtd is not a valid device
-ENOTSUPif operation is not supported on mtd
-EOVERFLOWif addr or count are not valid, i.e. outside memory
-EIOif I/O error occurred

◆ mtd_erase_sector()

int mtd_erase_sector ( mtd_dev_t mtd,
uint32_t  sector,
uint32_t  num 
)

Erase sectors of a MTD device.

Parameters
mtdthe device to erase
[in]sectorthe first sector number to erase
[in]numthe number of sectors to erase
Return values
0if erase successful
<0if an error occurred
-ENODEVif mtd is not a valid device
-ENOTSUPif operation is not supported on mtd
-EOVERFLOWif addr or sector are not valid, i.e. outside memory
-EIOif I/O error occurred

◆ mtd_init()

int mtd_init ( mtd_dev_t mtd)

mtd_init Initialize a MTD device

Parameters
mtdthe device to initialize
Return values
0on success
<0on error probably errno
-ENODEVif no device if given or no driver is set
-ENOTSUPif device has no init function

◆ mtd_power()

int mtd_power ( mtd_dev_t mtd,
enum mtd_power_state  power 
)

Set power mode on a MTD device.

Parameters
mtdthe device to access
[in]powerthe power mode to set
Return values
0if power mode successfully set
<0if an error occurred
-ENODEVif mtd is not a valid device
-ENOTSUPif operation or power state is not supported on mtd
-EIOif I/O error occurred

◆ mtd_read()

int mtd_read ( mtd_dev_t mtd,
void *  dest,
uint32_t  addr,
uint32_t  count 
)

Read data from a MTD device.

No alignment is required on addr and count.

Parameters
mtdthe device to read from
[out]destthe buffer to fill in
[in]addrthe start address to read from
[in]countthe number of bytes to read
Return values
0on success
<0if an error occurred
-ENODEVif mtd is not a valid device
-ENOTSUPif operation is not supported on mtd
-EOVERFLOWif addr or count are not valid, i.e. outside memory
-EIOif I/O error occurred

◆ mtd_read_page()

int mtd_read_page ( mtd_dev_t mtd,
void *  dest,
uint32_t  page,
uint32_t  offset,
uint32_t  size 
)

Read data from a MTD device with pagewise addressing.

The MTD layer will take care of splitting up the transaction into multiple reads if it is required by the underlying storage media.

Parameters
mtdthe device to read from
[out]destthe buffer to fill in
[in]pagePage number to start reading from
[in]offsetoffset from the start of the page (in bytes)
[in]sizethe number of bytes to read
Return values
nnumber of bytes read on success
<0value on error
-ENODEVif mtd is not a valid device
-ENOTSUPif operation is not supported on mtd
-EOVERFLOWif addr or count are not valid, i.e. outside memory
-EIOif I/O error occurred

◆ mtd_write()

int mtd_write ( mtd_dev_t mtd,
const void *  src,
uint32_t  addr,
uint32_t  count 
)

Write data to a MTD device.

addr + count must be inside a page boundary. addr can be anywhere but the buffer cannot overlap two pages.

Both parameters must be multiples of the device's write size.

Parameters
mtdthe device to write to
[in]srcthe buffer to write
[in]addrthe start address to write to
[in]countthe number of bytes to write
Return values
0on success
<0if an error occurred
-ENODEVif mtd is not a valid device
-ENOTSUPif operation is not supported on mtd
-EOVERFLOWif addr or count are not valid, i.e. outside memory, or overlapping two pages
-EIOif I/O error occurred
-EINVALif parameters are invalid (invalid alignment for instance)

◆ mtd_write_page()

int mtd_write_page ( mtd_dev_t mtd,
const void *  src,
uint32_t  page,
uint32_t  offset,
uint32_t  size 
)

Write data to a MTD device with pagewise addressing.

The MTD layer will take care of splitting up the transaction into multiple writes if it is required by the underlying storage media.

If the underlying sector needs to be erased before it can be written, the MTD layer will take care of the read-modify-write operation.

offset must be smaller than the page size

Note
this requires the mtd_write_page module
Parameters
mtdthe device to write to
[in]srcthe buffer to write
[in]pagePage number to start writing to
[in]offsetbyte offset from the start of the page
[in]sizethe number of bytes to write
Return values
nnumber of bytes written on success
<0value on error
-ENODEVif mtd is not a valid device
-ENOTSUPif operation is not supported on mtd
-EOVERFLOWif addr or count are not valid, i.e. outside memory,
-EIOif I/O error occurred
-EINVALif parameters are invalid

◆ mtd_write_page_raw()

int mtd_write_page_raw ( mtd_dev_t mtd,
const void *  src,
uint32_t  page,
uint32_t  offset,
uint32_t  size 
)

Write data to a MTD device with pagewise addressing.

The MTD layer will take care of splitting up the transaction into multiple writes if it is required by the underlying storage media.

This performs a raw write, no automatic read-modify-write cycle is performed.

Both offset and size must be multiples of the device's write size.

Parameters
mtdthe device to write to
[in]srcthe buffer to write
[in]pagePage number to start writing to
[in]offsetbyte offset from the start of the page
[in]sizethe number of bytes to write
Return values
nnumber of bytes written on success
<0value on error
-ENODEVif mtd is not a valid device
-ENOTSUPif operation is not supported on mtd
-EOVERFLOWif addr or count are not valid, i.e. outside memory,
-EIOif I/O error occurred
-EINVALif parameters are invalid

◆ mtd_write_sector()

int mtd_write_sector ( mtd_dev_t mtd,
const void *  src,
uint32_t  sector,
uint32_t  num 
)

Write data to a MTD device with whole sector writes.

The MTD layer will take care of splitting up the transaction into multiple writes if it is required by the underlying storage media.

The sectors will be erased before writing if needed.

Parameters
mtdDevice to write to
[in]srcBuffer to write
[in]sectorSector number to start writing to
[in]numNumber of sectors to write
Return values
nnumber of bytes written on success
<0value on error
-ENODEVif mtd is not a valid device
-ENOTSUPif operation is not supported on mtd
-EOVERFLOWif addr or count are not valid, i.e. outside memory,
-EIOif I/O error occurred
-EINVALif parameters are invalid

Variable Documentation

◆ mtd_dev_xfa

mtd_dev_t* const mtd_dev_xfa[]

MTD device array as XFA.

The array contains the addresses of all MTD devices that are defined using the MTD_XFA_ADD macro, for example:

MTD_XFA_ADD(my_dev, 0);

The MTD devices in this array can be used for automatic functions such as with the mtd_default module. The i-th device in this array can then be accessed with mtd_dev_xfa[i]. The number of MTDs defined in this array is XFA_LEN(mtd_dev_xfa).

Definition at line 139 of file mtd.h.