mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 15:15:44 +00:00
PR2040: libblock: Flash disk documentation
This commit is contained in:
@@ -1,3 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @ingroup RTEMSFDisk
|
||||||
|
*
|
||||||
|
* This file defines the interface to a flash disk block device.
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* flashdisk.h -- Flash disk block device implementation
|
* flashdisk.h -- Flash disk block device implementation
|
||||||
*
|
*
|
||||||
@@ -19,13 +27,84 @@
|
|||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base name of the flash disks.
|
* @defgroup RTEMSFDisk Flash Disk Device
|
||||||
*/
|
*
|
||||||
#define RTEMS_FLASHDISK_DEVICE_BASE_NAME "/dev/fdd"
|
* @ingroup rtems_blkdev
|
||||||
|
*
|
||||||
/**
|
* Flash disk driver for RTEMS provides support for block based
|
||||||
* Flash disk specific ioctl request types. To use open the
|
* file systems on flash devices. The driver is not a flash file
|
||||||
* device and issue the ioctl call.
|
* system nor does it try to compete with flash file systems. It
|
||||||
|
* currently does not journal how-ever block sequence numbering
|
||||||
|
* could be added to allow recovery of a past positions if
|
||||||
|
* a power down occurred while being updated.
|
||||||
|
*
|
||||||
|
* This flash driver provides block device support for most flash
|
||||||
|
* devices. The driver has been tested on NOR type devices such
|
||||||
|
* as the AMLV160 or M28W160. Support for NAND type devices may
|
||||||
|
* require driver changes to allow speedy recover of the block
|
||||||
|
* mapping data and to also handle the current use of word programming.
|
||||||
|
* Currently the page descriptors are stored in the first few pages
|
||||||
|
* of each segment.
|
||||||
|
*
|
||||||
|
* The driver supports devices, segments and pages. You provide
|
||||||
|
* to the driver the device descriptions as a table of device
|
||||||
|
* descriptors. Each device descriptor contain a table of
|
||||||
|
* segment descriptions or segment descriptors. The driver uses
|
||||||
|
* this information to manage the devices.
|
||||||
|
*
|
||||||
|
* A device is made up of segments. These are also called
|
||||||
|
* sectors or blocks. It is the smallest erasable part of a device.
|
||||||
|
* A device can have differing size segments at different
|
||||||
|
* offsets in the device. The segment descriptors support repeating
|
||||||
|
* segments that are continuous in the device. The driver breaks the
|
||||||
|
* segments up into pages. The first pages of a segment contain
|
||||||
|
* the page descriptors. A page descriptor hold the page flags,
|
||||||
|
* a CRC for the page of data and the block number the page
|
||||||
|
* holds. The block can appear in any order in the devices. A
|
||||||
|
* page is active if it hold a current block of data. If the
|
||||||
|
* used bit is set the page is counted as used. A page moves
|
||||||
|
* from erased to active to used then back to erased. If a block
|
||||||
|
* is written that is already in a page, the block is written to
|
||||||
|
* a new page the old page is flagged as used.
|
||||||
|
*
|
||||||
|
* At initialization time each segment's page descriptors are
|
||||||
|
* read into memory and scanned to determine the active pages,
|
||||||
|
* the used pages and the bad pages. If a segment has any erased
|
||||||
|
* pages it is queue on the available queue. If the segment has
|
||||||
|
* no erased pages it is queue on the used queue.
|
||||||
|
*
|
||||||
|
* The available queue is sorted from the least number available
|
||||||
|
* to the most number of available pages. A segment that has just
|
||||||
|
* been erased will placed at the end of the queue. A segment that
|
||||||
|
* has only a few available pages will be used sooner and once
|
||||||
|
* there are no available pages it is queued on the used queue.
|
||||||
|
* The used queue hold segments that have no available pages and
|
||||||
|
* is sorted from the least number of active pages to the most
|
||||||
|
* number of active pages.
|
||||||
|
*
|
||||||
|
* The driver is required to compact segments. Compacting takes
|
||||||
|
* the segment with the most number of available pages from the
|
||||||
|
* available queue then takes segments with the least number of
|
||||||
|
* active pages from the used queue until it has enough pages
|
||||||
|
* to fill the empty segment. As the active pages are moved
|
||||||
|
* they flagged as used and once the segment has only used pages
|
||||||
|
* it is erased.
|
||||||
|
*
|
||||||
|
* A flash block driver like this never knows if a page is not
|
||||||
|
* being used by the file-system. A typical file system is not
|
||||||
|
* design with the idea of erasing a block on a disk once it is
|
||||||
|
* not being used. The file-system will normally use a flag
|
||||||
|
* or a location as a marker to say that part of the disk is
|
||||||
|
* no longer in use. This means a number of blocks could be
|
||||||
|
* held in active pages but are no in use by the file system.
|
||||||
|
* The file system may also read blocks that have never been
|
||||||
|
* written to disk. This complicates the driver and may make
|
||||||
|
* the wear, usage and erase patterns harsher than a flash
|
||||||
|
* file system. The driver may also suffer from problems if
|
||||||
|
* power is lost.
|
||||||
|
*
|
||||||
|
* There are some flash disk specific IO control request types.
|
||||||
|
* To use open the device and issue the ioctl() call.
|
||||||
*
|
*
|
||||||
* @code
|
* @code
|
||||||
* int fd = open ("/dev/flashdisk0", O_WRONLY, 0);
|
* int fd = open ("/dev/flashdisk0", O_WRONLY, 0);
|
||||||
@@ -41,7 +120,15 @@
|
|||||||
* }
|
* }
|
||||||
* close (fd);
|
* close (fd);
|
||||||
* @endcode
|
* @endcode
|
||||||
|
*
|
||||||
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The base name of the flash disks.
|
||||||
|
*/
|
||||||
|
#define RTEMS_FLASHDISK_DEVICE_BASE_NAME "/dev/fdd"
|
||||||
|
|
||||||
#define RTEMS_FDISK_IOCTL_ERASE_DISK _IO('B', 128)
|
#define RTEMS_FDISK_IOCTL_ERASE_DISK _IO('B', 128)
|
||||||
#define RTEMS_FDISK_IOCTL_COMPACT _IO('B', 129)
|
#define RTEMS_FDISK_IOCTL_COMPACT _IO('B', 129)
|
||||||
#define RTEMS_FDISK_IOCTL_ERASE_USED _IO('B', 130)
|
#define RTEMS_FDISK_IOCTL_ERASE_USED _IO('B', 130)
|
||||||
@@ -50,7 +137,7 @@
|
|||||||
#define RTEMS_FDISK_IOCTL_PRINT_STATUS _IO('B', 133)
|
#define RTEMS_FDISK_IOCTL_PRINT_STATUS _IO('B', 133)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flash Disk Monitoring Data allows a user to obtain
|
* @brief Flash Disk Monitoring Data allows a user to obtain
|
||||||
* the current status of the disk.
|
* the current status of the disk.
|
||||||
*/
|
*/
|
||||||
typedef struct rtems_fdisk_monitor_data
|
typedef struct rtems_fdisk_monitor_data
|
||||||
@@ -74,10 +161,9 @@ typedef struct rtems_fdisk_monitor_data
|
|||||||
} rtems_fdisk_monitor_data;
|
} rtems_fdisk_monitor_data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flash Segment Descriptor holds, number of continuous segments in the
|
* @brief Flash Segment Descriptor holds, number of continuous segments in the
|
||||||
* device of this type, the base segment number in the device, the
|
* device of this type, the base segment number in the device, the address
|
||||||
* address offset of the base segment in the device, and the size of
|
* offset of the base segment in the device, and the size of segment.
|
||||||
* segment.
|
|
||||||
*
|
*
|
||||||
* Typically this structure is part of a table of segments in the
|
* Typically this structure is part of a table of segments in the
|
||||||
* device which is referenced in the flash disk configuration table.
|
* device which is referenced in the flash disk configuration table.
|
||||||
@@ -93,7 +179,7 @@ typedef struct rtems_fdisk_segment_desc
|
|||||||
} rtems_fdisk_segment_desc;
|
} rtems_fdisk_segment_desc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of kilo-bytes.
|
* @brief Return the number of kilo-bytes.
|
||||||
*/
|
*/
|
||||||
#define RTEMS_FDISK_KBYTES(_k) (UINT32_C(1024) * (_k))
|
#define RTEMS_FDISK_KBYTES(_k) (UINT32_C(1024) * (_k))
|
||||||
|
|
||||||
@@ -103,8 +189,8 @@ typedef struct rtems_fdisk_segment_desc
|
|||||||
struct rtems_fdisk_device_desc;
|
struct rtems_fdisk_device_desc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flash Low Level driver handlers.
|
* @brief Flash Low Level driver handlers.
|
||||||
|
*
|
||||||
* Typically this structure is part of a table of handlers in the
|
* Typically this structure is part of a table of handlers in the
|
||||||
* device which is referenced in the flash disk configuration table.
|
* device which is referenced in the flash disk configuration table.
|
||||||
* The reference is kept in the driver and used all the time to
|
* The reference is kept in the driver and used all the time to
|
||||||
@@ -245,10 +331,10 @@ typedef struct rtems_fdisk_driver_handlers
|
|||||||
} rtems_fdisk_driver_handlers;
|
} rtems_fdisk_driver_handlers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flash Device Descriptor holds the segments in a device. The
|
* @brief Flash Device Descriptor holds the segments in a device.
|
||||||
* placing of the segments in a device decriptor allows the
|
*
|
||||||
* low level driver to share the segment descriptors for a
|
* The placing of the segments in a device decriptor allows the low level
|
||||||
* number of devices.
|
* driver to share the segment descriptors for a number of devices.
|
||||||
*
|
*
|
||||||
* Typically this structure is part of a table of segments in the
|
* Typically this structure is part of a table of segments in the
|
||||||
* device which is referenced in the flash disk configuration table.
|
* device which is referenced in the flash disk configuration table.
|
||||||
@@ -263,7 +349,7 @@ typedef struct rtems_fdisk_device_desc
|
|||||||
} rtems_fdisk_device_desc;
|
} rtems_fdisk_device_desc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RTEMS Flash Disk configuration table used to initialise the
|
* @brief RTEMS Flash Disk configuration table used to initialise the
|
||||||
* driver.
|
* driver.
|
||||||
*
|
*
|
||||||
* The unavailable blocks count is the number of blocks less than the
|
* The unavailable blocks count is the number of blocks less than the
|
||||||
@@ -298,13 +384,22 @@ typedef struct rtems_flashdisk_config
|
|||||||
const rtems_fdisk_device_desc* devices; /**< The device descriptions. */
|
const rtems_fdisk_device_desc* devices; /**< The device descriptions. */
|
||||||
uint32_t flags; /**< Set of flags to control
|
uint32_t flags; /**< Set of flags to control
|
||||||
driver. */
|
driver. */
|
||||||
uint32_t unavail_blocks; /**< Number of blocks not
|
/**
|
||||||
available to the file sys. */
|
* Number of blocks not available to the file system. This number must be
|
||||||
|
* greater than or equal to the number of blocks in the largest segment to
|
||||||
|
* avoid starvation of erased blocks.
|
||||||
|
*/
|
||||||
|
uint32_t unavail_blocks;
|
||||||
|
|
||||||
uint32_t compact_segs; /**< Max number of segs to
|
uint32_t compact_segs; /**< Max number of segs to
|
||||||
compact in one pass. */
|
compact in one pass. */
|
||||||
uint32_t avail_compact_segs; /**< The number of segments
|
/**
|
||||||
when compaction occurs
|
* The number of segments when compaction occurs when writing. In case the
|
||||||
when writing. */
|
* number of segments in the available queue is less than or equal to this
|
||||||
|
* number the compaction process will be triggered. The available queue
|
||||||
|
* contains all segments with erased blocks.
|
||||||
|
*/
|
||||||
|
uint32_t avail_compact_segs;
|
||||||
uint32_t info_level; /**< Default info level. */
|
uint32_t info_level; /**< Default info level. */
|
||||||
} rtems_flashdisk_config;
|
} rtems_flashdisk_config;
|
||||||
|
|
||||||
@@ -352,15 +447,17 @@ rtems_fdisk_initialize (rtems_device_major_number major,
|
|||||||
void* arg);
|
void* arg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* External reference to the configuration. Please supply.
|
* @brief External reference to the configuration. Please supply.
|
||||||
* Support is present in confdefs.h for providing this variable.
|
* Support is present in confdefs.h for providing this variable.
|
||||||
*/
|
*/
|
||||||
extern const rtems_flashdisk_config rtems_flashdisk_configuration[];
|
extern const rtems_flashdisk_config rtems_flashdisk_configuration[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* External reference to the number of configurations. Please supply.
|
* @brief External reference to the number of configurations. Please supply.
|
||||||
* Support is present in confdefs.h for providing this variable.
|
* Support is present in confdefs.h for providing this variable.
|
||||||
*/
|
*/
|
||||||
extern uint32_t rtems_flashdisk_configuration_size;
|
extern uint32_t rtems_flashdisk_configuration_size;
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,86 +9,11 @@
|
|||||||
*
|
*
|
||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* @file
|
/*
|
||||||
*
|
|
||||||
* Flash disk driver for RTEMS provides support for block based
|
|
||||||
* file systems on flash devices. The driver is not a flash file
|
|
||||||
* system nor does it try to compete with flash file systems. It
|
|
||||||
* currently does not journal how-ever block sequence numbering
|
|
||||||
* could be added to allow recovery of a past positions if
|
|
||||||
* a power down occurred while being updated.
|
|
||||||
*
|
|
||||||
* This flash driver provides block device support for most flash
|
|
||||||
* devices. The driver has been tested on NOR type devices such
|
|
||||||
* as the AMLV160 or M28W160. Support for NAND type devices may
|
|
||||||
* require driver changes to allow speedy recover of the block
|
|
||||||
* mapping data and to also handle the current use of word programming.
|
|
||||||
* Currently the page descriptors are stored in the first few pages
|
|
||||||
* of each segment.
|
|
||||||
*
|
|
||||||
* The driver supports devices, segments and pages. You provide
|
|
||||||
* to the driver the device descriptions as a table of device
|
|
||||||
* descriptors. Each device descriptor contain a table of
|
|
||||||
* segment descriptions or segment descriptors. The driver uses
|
|
||||||
* this information to manage the devices.
|
|
||||||
*
|
|
||||||
* A device is made up of segments. These are also called
|
|
||||||
* sectors or blocks. It is the smallest erasable part of a device.
|
|
||||||
* A device can have differing size segments at different
|
|
||||||
* offsets in the device. The segment descriptors support repeating
|
|
||||||
* segments that are continous in the device. The driver breaks the
|
|
||||||
* segments up into pages. The first pages of a segment contain
|
|
||||||
* the page descriptors. A page descriptor hold the page flags,
|
|
||||||
* a CRC for the page of data and the block number the page
|
|
||||||
* holds. The block can appear in any order in the devices. A
|
|
||||||
* page is active if it hold a current block of data. If the
|
|
||||||
* used bit is set the page is counted as used. A page moves
|
|
||||||
* from erased to active to used then back to erased. If a block
|
|
||||||
* is written that is already in a page, the block is written to
|
|
||||||
* a new page the old page is flagged as used.
|
|
||||||
*
|
|
||||||
* At initialisation time each segment's page descriptors are
|
|
||||||
* read into memory and scanned to determine the active pages,
|
|
||||||
* the used pages and the bad pages. If a segment has any erased
|
|
||||||
* pages it is queue on the available queue. If the segment has
|
|
||||||
* no erased pages it is queue on the used queue.
|
|
||||||
*
|
|
||||||
* The available queue is sorted from the least number available
|
|
||||||
* to the most number of available pages. A segment that has just
|
|
||||||
* been erased will placed at the end of the queue. A segment that
|
|
||||||
* has only a few available pages will be used sooner and once
|
|
||||||
* there are no available pages it is queued on the used queue.
|
|
||||||
* The used queue hold segments that have no available pages and
|
|
||||||
* is sorted from the least number of active pages to the most
|
|
||||||
* number of active pages.
|
|
||||||
*
|
|
||||||
* The driver is required to compact segments. Compacting takes
|
|
||||||
* the segment with the most number of available pages from the
|
|
||||||
* available queue then takes segments with the least number of
|
|
||||||
* active pages from the used queue until it has enough pages
|
|
||||||
* to fill the empty segment. As the active pages are moved
|
|
||||||
* they flagged as used and once the segment has only used pages
|
|
||||||
* it is erased.
|
|
||||||
*
|
|
||||||
* A flash block driver like this never knows if a page is not
|
|
||||||
* being used by the file-system. A typical file system is not
|
|
||||||
* design with the idea of erasing a block on a disk once it is
|
|
||||||
* not being used. The file-system will normally use a flag
|
|
||||||
* or a location as a marker to say that part of the disk is
|
|
||||||
* no longer in use. This means a number of blocks could be
|
|
||||||
* held in active pages but are no in use by the file system.
|
|
||||||
* The file system may also read blocks that have never been
|
|
||||||
* written to disk. This complicates the driver and may make
|
|
||||||
* the wear, usage and erase patterns harsher than a flash
|
|
||||||
* file system. The driver may also suffer from problems if
|
|
||||||
* power is lost.
|
|
||||||
*
|
|
||||||
* @note
|
|
||||||
*
|
|
||||||
* The use of pages can vary. The rtems_fdisk_seg_*_page set
|
* The use of pages can vary. The rtems_fdisk_seg_*_page set
|
||||||
* routines use an absolute page number relative to the segment
|
* routines use an absolute page number relative to the segment
|
||||||
* while all other page numbera are relative to the number of
|
* while all other page numbers are relative to the number of
|
||||||
* page descriptor pages a segment has. You need to add the
|
* page descriptor pages a segment has. You need to add the
|
||||||
* number of page descriptor pages (pages_desc) to the page number
|
* number of page descriptor pages (pages_desc) to the page number
|
||||||
* when call the rtems_fdisk_seg_*_page functions.
|
* when call the rtems_fdisk_seg_*_page functions.
|
||||||
|
|||||||
Reference in New Issue
Block a user