Chapter 64. FLASH I/O devices
Table of Contents
It can be useful to be able to access FLASH devices using the generic
I/O infrastructure found in CYGPKG_IO
, and the generic
FLASH layer provides an optional ability to do so. This allows
the use of functions like cyg_io_lookup()
,
cyg_io_read()
,
cyg_io_write()
etc.
Additionally it means that, courtesy of the
“devfs” pseudo-filesystem in the file I/O layer
(CYGPKG_IO_FILEIO
), functions like
open()
, read()
,
write()
etc. can even be used directly
on the FLASH devices.
64.1. Overview and CDL Configuration
This package implements support for FLASH as an I/O device by exporting
it as if it is a block device. To enable this support, the CDL option
titled “Provide /dev block devices”, also known as
CYGPKG_IO_FLASH_BLOCK_DEVICE
, must be enabled.
(There is also a legacy format alternative which is now deprecated).
There are two methods of addressing FLASH as a block device:
Using the FLASH Information System (FIS) - this is a method of defining and naming FLASH partitions, usually in RedBoot. This option is only valid if RedBoot is resident and was used to boot the application. To reference FLASH partitions in this way, you would use a device name of the form
/dev/flash/fis/
, for examplepartition-name
/dev/flash/fis/jffs2
to reference a FIS partition named JFFS2.The CDL option
CYGFUN_IO_FLASH_BLOCK_FROM_FIS
must be enabled for this support.Referencing by device number, offset and length - this method extracts addressing information from the name itself. The form of the device would be
/dev/flash/
]device-number
/offset
[,length
-
device-number
- This is a fixed number allocated to identify each FLASH region in the system. The first region is numbered 0, the second 1, and so on. If you have only one FLASH device, it will be numbered 0.
-
offset
-
This is the index into the FLASH region in bytes to use. It
may be specified as decimal, or if prefixed with
0x
, then hexadecimal. -
length
- This field is optional and defaults to the remainder of the FLASH region. Again it may be specified in decimal or hexadecimal.
Some examples:
- /dev/flash/0/0
- This defines a block device that uses the entirety of FLASH region 0.
- /dev/flash/1/0x20000,65536
- This defines a block device which points inside FLASH region 1, starting at offset 0x20000 (128Kb) and extending for 64Kb.
- /dev/flash/0/65536
- This defines a block device which points inside FLASH region 0, starting at offset 64Kb and continuing up to the end of the device.
Obviously great care is required when constructing the device names as using the wrong specification may subsequently overwrite important areas of FLASH, such as RedBoot. Using the alternative via FIS names is preferable as these are less error-prone to configure, and also allows for the FLASH region to be relocated without requiring program recompilation.
-
64.2. Using FLASH I/O devices
The FLASH I/O block devices can be accessed, read and written using
the standard interface supplied by the generic I/O
(CYGPKG_IO
) package. These include the functions:
cyg_io_lookup()
to access the device and get a
handle, cyg_io_read()
and
cyg_io_write()
for sequential read and write
operations, cyg_io_bread()
and
cyg_io_bwrite()
for random access read and write
operations, and cyg_io_get_config()
and
cyg_io_setconfig()
for run-time configuration
inspection and control.
However there are two aspects that differ from some other I/O devices accessed this way:
-
The first is that the lookup operation uses up
resources which must be subsequently freed when the last user of the
I/O handle is finished. The number of FLASH I/O devices that may be
simultaneously opened is configured with the
CYGNUM_IO_FLASH_BLOCK_DEVICES
CDL option. After the last user is finished, the device may be closed usingcyg_io_setconfig()
with theCYG_IO_SET_CONFIG_CLOSE
key. Reference counting to ensure that it is only the last user that causes a close, is left to higher layers. - The second is that write operations assume that the flash is already erased. Attempting to write to Flash that has already been written to may result in errors. Instead FLASH must be erased before it may be written.
FLASH block devices can also be read and written using the
standard POSIX primitives, open()
,
close()
, read()
,
write()
, lseek()
, and so on
if the POSIX file I/O package (CYGPKG_FILEIO
) is
included in the configuration. As with the eCos generic I/O interface
you must call close()
to ensure resources
are freed when the device is no longer used.
Other configuration keys are provided to perform FLASH erase
operations, and to retrieve device sizes, and FLASH block sizes at
a particular address. These operations are accessed with
cyg_io_get_config()
(or if using the POSIX
file I/O API, cyg_fs_getinfo()
) with the
following keys:
-
CYG_IO_GET_CONFIG_FLASH_ERASE
This erases a region of FLASH.
cyg_io_get_config()
must be passed a structure defined as per the following, which is also supplied in<cyg/io/flash.h>
:typedef struct { CYG_ADDRESS offset; size_t len; int flasherr; cyg_flashaddr_t err_address; } cyg_io_flash_getconfig_erase_t;
In this structure,
offset
specifies the offset within the block device to erase,len
specifies the amount to address,flasherr
is set on return to specify an error with the FLASH erase operation itself, anderr_address
is used if there was an error to specify at which address the error happened.-
CYG_IO_GET_CONFIG_FLASH_LOCK
This protects a region of FLASH using the locking facilities available on the card, if provided by the underlying driver.
cyg_io_get_config()
must be passed a structure defined as per the following:typedef struct { CYG_ADDRESS offset; size_t len; int flasherr; cyg_flashaddr_t err_address; } cyg_io_flash_getconfig_lock_t;
In this structure,
offset
specifies the offset within the block device to lock,len
specifies the amount to address,flasherr
is set on return to specify an error with the FLASH lock operation itself, anderr_address
is used if there was an error to specify at which address the error happened. If locking support is not available -EINVAL will be returned fromcyg_io_get_config()
.-
CYG_IO_GET_CONFIG_FLASH_UNLOCK
This disables protection for a region of FLASH using the unlocking facilities available on the card, if provided by the underlying driver.
cyg_io_get_config()
must be passed a structure defined as per the following:typedef struct { CYG_ADDRESS offset; size_t len; int flasherr; cyg_flashaddr_t err_address; } cyg_io_flash_getconfig_unlock_t;
In this structure,
offset
specifies the offset within the block device to unlock,len
specifies the amount to address,flasherr
is set on return to specify an error with the FLASH unlock operation itself, anderr_address
is used if there was an error to specify at which address the error happened. If unlocking support is not available -EINVAL will be returned fromcyg_io_get_config()
.-
CYG_IO_GET_CONFIG_FLASH_DEVSIZE
This returns the size of the FLASH block device. The
cyg_io_get_config()
function must be passed a structure defined as per the following, which is also supplied in<cyg/io/flash.h>
:typedef struct { size_t dev_size; } cyg_io_flash_getconfig_devsize_t;
In this structure,
dev_size
is used to return the size of the FLASH device.-
CYG_IO_GET_CONFIG_FLASH_DEVADDR
This returns the address in the virtual memory map that the generic flash layer has been informed that this FLASH device is mapped to. Note that some flash devices such as dataflash are not truly memory mapped, and so this function only returns useful information when used with a true memory mapped FLASH device. The
cyg_io_get_config()
function must be passed a structure defined as per the following, which is also supplied in<cyg/io/flash.h>
:typedef struct { cyg_flashaddr_t dev_addr; } cyg_io_flash_getconfig_devaddr_t;
In this structure,
dev_addr
is used to return the address corresponding to the base of the FLASH device in the virtual memory map.-
CYG_IO_GET_CONFIG_FLASH_BLOCKSIZE
This returns the size of a FLASH block at a supplied offset in the FLASH block device. The
cyg_io_get_config()
function must be passed a structure defined as per the following, which is also supplied in<cyg/io/flash.h>
:typedef struct { CYG_ADDRESS offset; size_t block_size; } cyg_io_flash_getconfig_blocksize_t;
In this structure,
offset
specifies the address within the block device of which the FLASH block size is required - a single FLASH device may contain blocks of differing sizes. Theblock_size
field is used to return the block size at the specified offset.
2024-03-18 | Open Publication License |