Chapter 62. The Version 2 eCos FLASH API
Table of Contents
- 62.1. FLASH user API
- 62.1.1. Initializing the FLASH library
- 62.1.2. Retrieving information about FLASH devices
- 62.1.3. Reading from FLASH
- 62.1.4. Erasing areas of FLASH
- 62.1.5. Programming the FLASH
- 62.1.6. Locking and unlocking blocks
- 62.1.7. Locking FLASH mutexes
- 62.1.8. Configuring diagnostic output
- 62.1.9. Return values and errors
- 62.2. FLASH device API
There are two APIs described here. The first is the application API which programs should use. The second API is that between the FLASH IO library and the device drivers.
62.1. FLASH user API
- 62.1.1. Initializing the FLASH library
- 62.1.2. Retrieving information about FLASH devices
- 62.1.3. Reading from FLASH
- 62.1.4. Erasing areas of FLASH
- 62.1.5. Programming the FLASH
- 62.1.6. Locking and unlocking blocks
- 62.1.7. Locking FLASH mutexes
- 62.1.8. Configuring diagnostic output
- 62.1.9. Return values and errors
All of the functions described below are declared in the header
file <cyg/io/flash.h>
which all users of
the FLASH library should include.
62.1.1. Initializing the FLASH library
The FLASH library needs to be initialized before other FLASH operations can be performed. This only needs to be done once. The following function will only do the initialization once so it's safe to call multiple times:
__externC int cyg_flash_init(cyg_flash_printf *pf);
The parameter pf
must always be set to NULL. It
exists solely for backward compatibility and other settings are deprecated
and obsolete. Past use of this parameter has now been replaced with use of
the cyg_flash_set_global_printf
function.
62.1.2. Retrieving information about FLASH devices
The following five functions return information about the FLASH.
__externC int cyg_flash_get_info(cyg_uint32 devno, cyg_flash_info_t * info); __externC int cyg_flash_get_info_addr(cyg_flashaddr_t flash_base, cyg_flash_info_t * info); __externC int cyg_flash_verify_addr(const flashaddr_t address); __extern size_t cyg_flash_block_size(const cyg_flashaddr_t flash_base); typedef struct cyg_flash_block_info { size_t block_size; cyg_uint32 blocks; } cyg_flash_block_info_t; typedef struct { cyg_flashaddr_t start; // First address cyg_flashaddr_t end; // Last address cyg_uint32 num_block_infos;// Number of entries const cyg_flash_block_info_t *block_info; // Info about one block size } cyg_flash_info_t;
cyg_flash_get_info()
is the main function
to get information about installed flash devices. Parameter
devno
is used to iterate over the available
flash devices, starting from 0. If the devno'th device exists, the
structure pointed to by info
is filled in and
CYG_FLASH_ERR_OK
is returned, otherwise
CYG_FLASH_ERR_INVALID
.
cyg_flash_get_info_addr()
is similar, but returns the
information about the flash device at the given address.
cyg_flash_block_size()
returns the size of the
block at the given address. cyg_flash_verify_addr()
tests if the target addresses is within one of the FLASH
devices, returning CYG_FLASH_ERR_OK
if so.
62.1.3. Reading from FLASH
There are two methods for reading from FLASH. The first is to use the following function.
__externC int cyg_flash_read(cyg_flashaddr_t flash_base, void *ram_base, size_t len, cyg_flashaddr_t *err_address);
flash_base
is where in the flash to read
from. ram_base
indicates where the data read
from flash should be placed into RAM. len
is
the number of bytes to be read from the FLASH and
err_address
is used to return the location in
FLASH that any error occurred while reading.
The second method is to simply memcpy()
directly
from the FLASH. This is not recommended since some types of device
cannot be read in this way, eg NAND FLASH. Using the FLASH library
function to read the FLASH will always work so making it easy to port
code from one FLASH device to another.
62.1.4. Erasing areas of FLASH
Blocks of FLASH can be erased using the following function:
__externC int cyg_flash_erase(cyg_flashaddr_t flash_base, size_t len, cyg_flashaddr_t *err_address);
flash_base
is where in the flash to erase
from. len
is the minimum number of bytes to
erase in the FLASH and err_address
is used to
return the location in FLASH that any error occurred while erasing. It
should be noted that FLASH devices are block oriented when erasing. It
is not possible to erase a few bytes within a block, the whole block
will be erased. flash_base
may be anywhere
within the first block to be erased and flash_base+len
may be anywhere in the last block to be erased.
62.1.5. Programming the FLASH
Programming of the flash is achieved using the following function.
__externC int cyg_flash_program(cyg_flashaddr_t flash_base, void *ram_base, size_t len, cyg_flashaddr_t *err_address);
flash_base
is where in the flash to program
from. ram_base
indicates where the data to be
programmed into FLASH should be read from in RAM. len
is the number of bytes to be program into the FLASH and
err_address
is used to return the location in
FLASH that any error occurred while programming.
62.1.6. Locking and unlocking blocks
Some flash devices have the ability to lock and unlock blocks. A
locked block cannot be erased or programmed without it first being
unlocked. For devices which support this feature and when CYGHWR_IO_FLASH_BLOCK_LOCKING
is enabled then the following
two functions are available:
__externC int cyg_flash_lock( const cyg_flashaddr_t flash_base, size_t len, cyg_flashaddr_t *err_address); __externC int cyg_flash_unlock( const cyg_flashaddr_t flash_base, size_t len, cyg_flashaddr_t *err_address);
For some devices the granularity will be at the whole device level, where the code will lock or unlock all of the blocks at the same time.
62.1.7. Locking FLASH mutexes
When the eCos kernel package is included in the eCos configuration, the FLASH IO library will perform mutex locking on FLASH operations. This makes the API defined here thread safe. However applications may wish to directly access the contents of the FLASH. In order for this to be thread safe it is necessary for the application to use the following two functions to inform the FLASH IO library that the FLASH devices are being used and other API calls should be blocked.
__externC int cyg_flash_mutex_lock(const cyg_flashaddr_t from, size_t len); __externC int cyg_flash_mutex_unlock(const cyg_flashaddr_t from, size_t len);
62.1.8. Configuring diagnostic output
Each FLASH device can have an associated function which is called to perform diagnostic output. The function to be used can be configured with the following functions:
__externC int cyg_flash_set_printf(const cyg_flashaddr_t flash_base, cyg_flash_printf *pf); __externC void cyg_flash_set_global_printf(cyg_flash_printf *pf); typedef int cyg_flash_printf(const char *fmt, …);
The parameter pf
is a pointer to a function
which is to be used for diagnostic output. Typically the function
diag_printf()
will be passed. Normally this
function is not used by the higher layer of the library unless
CYGSEM_IO_FLASH_CHATTER
is enabled. Passing a
NULL
causes diagnostic output from lower level
drivers to be discarded.
cyg_flash_set_printf
is used to set a
diagnostic output function which will be used specifically when
diagnostic output is attempted from the FLASH device driver associated
with the base address of flash_base
. An error
will be returned if no FLASH device is found for this address, or the
FLASH subsystem has not yet been initialised with
cyg_flash_init
.
cyg_flash_set_global_printf
sets a
diagnostic output function for all available FLASH devices. Any
previous setting of a diagnostic output function (including with
cyg_flash_set_printf
) will be discarded.
This function may be called prior to
cyg_flash_init
.
62.1.9. Return values and errors
All the functions above return one of the following return values.
CYG_FLASH_ERR_OK No error - operation complete CYG_FLASH_ERR_INVALID Invalid FLASH address CYG_FLASH_ERR_ERASE Error trying to erase CYG_FLASH_ERR_LOCK Error trying to lock/unlock CYG_FLASH_ERR_PROGRAM Error trying to program CYG_FLASH_ERR_PROTOCOL Generic error CYG_FLASH_ERR_PROTECT Device/region is write-protected CYG_FLASH_ERR_NOT_INIT FLASH info not yet initialized CYG_FLASH_ERR_HWR Hardware (configuration?) problem CYG_FLASH_ERR_ERASE_SUSPEND Device is in erase suspend mode CYG_FLASH_ERR_PROGRAM_SUSPEND Device is in program suspend mode CYG_FLASH_ERR_DRV_VERIFY Driver failed to verify data CYG_FLASH_ERR_DRV_TIMEOUT Driver timed out waiting for device CYG_FLASH_ERR_DRV_WRONG_PART Driver does not support device CYG_FLASH_ERR_LOW_VOLTAGE Not enough juice to complete job
To turn an error code into a human readable string the following function can be used:
__externC const char *cyg_flash_errmsg(const int err);
62.2. FLASH device API
This section describes the API between the FLASH IO library the FLASH device drivers.
62.2.1. The FLASH device Structure
This structure keeps all the information about a single driver.
struct cyg_flash_dev { const struct cyg_flash_dev_funs *funs; // Function pointers cyg_uint32 flags; // Device characteristics cyg_flashaddr_t start; // First address cyg_flashaddr_t end; // Last address cyg_uint32 num_block_infos; // Number of entries const cyg_flash_block_info_t *block_info; // Info about one block size const void *priv; // Devices private data // The following are only written to by the FLASH IO layer. cyg_flash_printf *pf; // Pointer to diagnostic printf bool init; // Device has been initialised #ifdef CYGPKG_KERNEL cyg_mutex_t mutex; // Mutex for thread safeness #endif #if (CYGHWR_IO_FLASH_DEVICE > 1) struct cyg_flash_dev *next; // Pointer to next device #endif }; struct cyg_flash_dev_funs { int (*flash_init) ( struct cyg_flash_dev *dev ); size_t (*flash_query) ( struct cyg_flash_dev *dev, void *data, size_t len ); int (*flash_erase_block) (struct cyg_flash_dev *dev, cyg_flashaddr_t block_base ); int (*flash_program) (struct cyg_flash_dev *dev, cyg_flashaddr_t base, const void *data, size_t len ); int (*flash_read) ( struct cyg_flash_dev *dev, const cyg_flashaddr_t base, void *data, size_t len ); #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING int (*flash_block_lock) ( struct cyg_flash_dev *dev, const cyg_flashaddr_t block_base ); int (*flash_block_unlock) ( struct cyg_flash_dev *dev, const cyg_flashaddr_t block_base); #endif };
The FLASH IO layer will only pass requests for operations on a single block.
2024-12-10 | Open Publication License |