Mistake on this page?
Report an issue in GitHub or email us
Data Fields
_ARM_DRIVER_STORAGE Struct Reference

This is the set of operations constituting the Storage driver. More...

#include <Driver_Storage.h>

Data Fields

ARM_DRIVER_VERSION(* GetVersion )(void)
 Get driver version. More...
 
ARM_STORAGE_CAPABILITIES(* GetCapabilities )(void)
 Get driver capabilities. More...
 
int32_t(* Initialize )(ARM_Storage_Callback_t callback)
 Initialize the Storage Interface. More...
 
int32_t(* Uninitialize )(void)
 De-initialize the Storage Interface. More...
 
int32_t(* PowerControl )(ARM_POWER_STATE state)
 Control the Storage interface power. More...
 
int32_t(* ReadData )(uint64_t addr, void *data, uint32_t size)
 read the contents of a given address range from the storage device. More...
 
int32_t(* ProgramData )(uint64_t addr, const void *data, uint32_t size)
 program (write into) the contents of a given address range of the storage device. More...
 
int32_t(* Erase )(uint64_t addr, uint32_t size)
 Erase Storage range. More...
 
int32_t(* EraseAll )(void)
 Erase complete storage. More...
 
ARM_STORAGE_STATUS(* GetStatus )(void)
 Get the status of the current (or previous) command executed by the storage controller; stored in the structure ARM_STORAGE_STATUS. More...
 
int32_t(* GetInfo )(ARM_STORAGE_INFO *info)
 Get information about the Storage device; stored in the structure ARM_STORAGE_INFO. More...
 
uint32_t(* ResolveAddress )(uint64_t addr)
 For memory-mapped storage, resolve an address relative to the storage controller into a memory address. More...
 
int32_t(* GetNextBlock )(const ARM_STORAGE_BLOCK *prev_block, ARM_STORAGE_BLOCK *next_block)
 Advance to the successor of the current block (iterator), or fetch the first block (if 'prev_block' is passed in as NULL). More...
 
int32_t(* GetBlock )(uint64_t addr, ARM_STORAGE_BLOCK *block)
 Find the storage block (iterator) encompassing a given storage address. More...
 

Detailed Description

This is the set of operations constituting the Storage driver.

Their implementation is platform-specific, and needs to be supplied by the porting effort.

Some APIs within ARM_DRIVER_STORAGE will always operate synchronously: GetVersion, GetCapabilities, GetStatus, GetInfo, ResolveAddress, GetNextBlock, and GetBlock. This means that control returns to the caller with a relevant status code only after the completion of the operation (or the discovery of a failure condition).

The remainder of the APIs: Initialize, Uninitialize, PowerControl, ReadData, ProgramData, Erase, EraseAll, can function asynchronously if the underlying controller supports it–i.e. if ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. In the case of asynchronous operation, the invocation returns early (with ARM_DRIVER_OK) and results in a completion callback later. If ARM_STORAGE_CAPABILITIES::asynchronous_ops is not set, then all such APIs execute synchronously, and control returns to the caller with a status code only after the completion of the operation (or the discovery of a failure condition).

If ARM_STORAGE_CAPABILITIES::asynchronous_ops is set, a storage driver may still choose to execute asynchronous operations in a synchronous manner. If so, the driver returns a positive value to indicate successful synchronous completion (or an error code in case of failure) and no further invocation of completion callback should be expected. The expected return value for synchronous completion of such asynchronous operations varies depending on the operation. For operations involving data access, it often equals the amount of data transferred or affected. For non data-transfer operations, such as EraseAll or Initialize, it is usually 1.

Here's a code snippet to suggest how asynchronous APIs might be used by callers to handle both synchronous and asynchronous execution by the underlying storage driver:

ASSERT(ARM_DRIVER_OK == 0); // this is a precondition; it doesn't need to be put in code
int32_t returnValue = drv->asynchronousAPI(...);
if (returnValue < ARM_DRIVER_OK) {
// handle error.
} else if (returnValue == ARM_DRIVER_OK) {
ASSERT(drv->GetCapabilities().asynchronous_ops == 1);
// handle early return from asynchronous execution; remainder of the work is done in the callback handler.
} else {
ASSERT(returnValue == EXPECTED_RETURN_VALUE_FOR_SYNCHRONOUS_COMPLETION);
// handle synchronous completion.
}

Definition at line 292 of file Driver_Storage.h.

Field Documentation

int32_t(* Erase) (uint64_t addr, uint32_t size)

Erase Storage range.

This function erases a range of storage specified by [addr, addr + size). Both 'addr' and 'addr + size' should align with the 'erase_unit'(s) of the respective owning storage block(s) (see ARM_STORAGE_BLOCK and ARM_STORAGE_BLOCK_ATTRIBUTES). The range to be erased will have its contents returned to the un-programmed state– i.e. to 'erased_value' (see ARM_STORAGE_BLOCK_ATTRIBUTES), which is usually 1 to indicate the pattern of all ones: 0xFF.

Parameters
[in]addrThis is the start-address of the range to be erased. It must start at an 'erase_unit' boundary of the underlying block.
[in]sizeSize (in bytes) of the range to be erased. 'addr + size' must be aligned with the 'erase_unit' of the underlying block.
Note
This API may execute asynchronously if ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous execution is optional even if 'asynchronous_ops' is set.
Returns
If the range to be erased doesn't align with the erase_units of the respective start and end blocks, ARM_DRIVER_ERROR_PARAMETER is returned. If any part of the range is protected, ARM_STORAGE_ERROR_PROTECTED is returned. If any part of the range is not erasable, ARM_STORAGE_ERROR_NOT_ERASABLE is returned. All such sanity-check failures result in the error code being returned synchronously and the storage bytes within the range remain unaffected. Otherwise the function executes in the following ways: If asynchronous activity is launched, an invocation returns ARM_DRIVER_OK, and the caller can expect to receive a callback in the future with the number of successfully erased bytes passed in as the 'status' parameter. In the case of synchronous execution, control returns after completion with a positive erase-count. Return values less than ARM_DRIVER_OK (0) signify errors.
Note
Erase() may return a smaller (positive) value than the size of the requested range. The returned value indicates the actual number of bytes erased. It is the caller's responsibility to follow up with an appropriate request to complete the operation.
in the case of a failed erase (except when ARM_DRIVER_ERROR_PARAMETER, ARM_STORAGE_ERROR_PROTECTED, or ARM_STORAGE_ERROR_NOT_ERASABLE is returned synchronously), the requested range should be assumed to be in an unknown state. The previous contents may not be retained.

Definition at line 611 of file Driver_Storage.h.

int32_t(* EraseAll) (void)

Erase complete storage.

Optional function for faster erase of the complete device.

This optional function erases the complete device. If the device does not support global erase then the function returns the error value ARM_DRIVER_ERROR_UNSUPPORTED. The data field 'erase_all' = 1 of the structure ARM_STORAGE_CAPABILITIES encodes that ARM_STORAGE_EraseAll is supported.

Note
This API may execute asynchronously if ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous execution is optional even if 'asynchronous_ops' is set.
Returns
If any part of the storage range is protected, ARM_STORAGE_ERROR_PROTECTED is returned. If any part of the storage range is not erasable, ARM_STORAGE_ERROR_NOT_ERASABLE is returned. All such sanity-check failures result in the error code being returned synchronously and the storage bytes within the range remain unaffected. Otherwise the function executes in the following ways: If asynchronous activity is launched, an invocation returns ARM_DRIVER_OK, and the caller can expect to receive a callback in the future with ARM_DRIVER_OK passed in as the 'status' parameter. In the case of synchronous execution, control returns after completion with a value of 1. Return values less than ARM_DRIVER_OK (0) signify errors.

Definition at line 639 of file Driver_Storage.h.

int32_t(* GetBlock) (uint64_t addr, ARM_STORAGE_BLOCK *block)

Find the storage block (iterator) encompassing a given storage address.

Parameters
[in]addrStorage address in bytes.
[out]blockA caller-owned buffer large enough to be filled in with the ARM_STORAGE_BLOCK encapsulating the given address. This value can also be passed in as NULL if the caller isn't interested in populating a buffer with the block–if the caller only wishes to establish the presence of a containing storage block.
Returns
ARM_DRIVER_OK if a containing storage-block is found. In this case, if block is non-NULL, the buffer pointed to by it is populated with the contents of the storage block–i.e. if block is valid and a block is found, ARM_STORAGE_VALID_BLOCK(block) would return true following this call. If there is no storage block containing the given offset, or in case the driver is unable to resolve an address to a storage-block, an error (negative) value is returned and an invalid StorageBlock is populated into the supplied buffer.
Note
This API returns synchronously–it does not result in an invocation of a completion callback.

Definition at line 766 of file Driver_Storage.h.

ARM_STORAGE_CAPABILITIES(* GetCapabilities) (void)

Get driver capabilities.

The function GetCapabilities() returns information about capabilities in this driver implementation. The data fields of the struct ARM_STORAGE_CAPABILITIES encode various capabilities, for example if the device is able to execute operations asynchronously.

Example:

extern ARM_DRIVER_STORAGE *drv_info;
void read_capabilities (void) {
ARM_STORAGE_CAPABILITIES drv_capabilities;
drv_capabilities = drv_info->GetCapabilities ();
// interrogate capabilities
}
Returns
ARM_STORAGE_CAPABILITIES.
Note
This API returns synchronously–it does not result in an invocation of a completion callback.
The function GetCapabilities() can be called any time to obtain the required information from the driver (even before initialization). It always returns the same information.

Definition at line 357 of file Driver_Storage.h.

int32_t(* GetInfo) (ARM_STORAGE_INFO *info)

Get information about the Storage device; stored in the structure ARM_STORAGE_INFO.

Parameters
[out]infoA caller-supplied buffer capable of being filled in with an ARM_STORAGE_INFO.
Returns
ARM_DRIVER_OK if a ARM_STORAGE_INFO structure containing top level metadata about the storage controller is filled into the supplied buffer, else an appropriate error value.
Note
It is the caller's responsibility to ensure that the buffer passed in is able to be initialized with a ARM_STORAGE_INFO.
This API returns synchronously–it does not result in an invocation of a completion callback.

Definition at line 670 of file Driver_Storage.h.

int32_t(* GetNextBlock) (const ARM_STORAGE_BLOCK *prev_block, ARM_STORAGE_BLOCK *next_block)

Advance to the successor of the current block (iterator), or fetch the first block (if 'prev_block' is passed in as NULL).

This helper function fetches (an iterator to) the next block (or the first block if 'prev_block' is passed in as NULL). In the failure case, a terminating, invalid block iterator is filled into the out parameter: 'next_block'. In combination with ARM_STORAGE_VALID_BLOCK(), it can be used to iterate over the sequence of blocks within the storage map:

for (drv->GetNextBlock(NULL, &block); ARM_STORAGE_VALID_BLOCK(&block); drv->GetNextBlock(&block, &block)) {
// make use of block
}
Parameters
[in]prev_blockAn existing block (iterator) within the same storage controller. The memory buffer holding this block is owned by the caller. This pointer may be NULL; if so, the invocation fills in the first block into the out parameter: 'next_block'.
[out]next_blockA caller-owned buffer large enough to be filled in with the following ARM_STORAGE_BLOCK. It is legal to provide the same buffer using 'next_block' as was passed in with 'prev_block'. It is also legal to pass a NULL into this parameter if the caller isn't interested in populating a buffer with the next block–i.e. if the caller only wishes to establish the presence of a next block.
Returns
ARM_DRIVER_OK if a valid next block is found (or first block, if prev_block is passed as NULL); upon successful operation, the contents of the next (or first) block are filled into the buffer pointed to by the parameter 'next_block' and ARM_STORAGE_VALID_BLOCK(next_block) is guaranteed to be true. Upon reaching the end of the sequence of blocks (iterators), or in case the driver is unable to fetch information about the next (or first) block, an error (negative) value is returned and an invalid StorageBlock is populated into the supplied buffer. If prev_block is NULL, the first block is returned.
Note
This API returns synchronously–it does not result in an invocation of a completion callback.

Definition at line 738 of file Driver_Storage.h.

ARM_STORAGE_STATUS(* GetStatus) (void)

Get the status of the current (or previous) command executed by the storage controller; stored in the structure ARM_STORAGE_STATUS.

Returns
The status of the underlying controller.
Note
This API returns synchronously–it does not result in an invocation of a completion callback.

Definition at line 651 of file Driver_Storage.h.

ARM_DRIVER_VERSION(* GetVersion) (void)

Get driver version.

The function GetVersion() returns version information of the driver implementation in ARM_DRIVER_VERSION.

  • API version is the version of the CMSIS-Driver specification used to implement this driver.
  • Driver version is source code version of the actual driver implementation.

Example:

extern ARM_DRIVER_STORAGE *drv_info;
void read_version (void) {
version = drv_info->GetVersion ();
if (version.api < 0x10A) { // requires at minimum API version 1.10 or higher
// error handling
return;
}
}
Returns
ARM_DRIVER_VERSION.
Note
This API returns synchronously–it does not result in an invocation of a completion callback.
The function GetVersion() can be called any time to obtain the required information from the driver (even before initialization). It always returns the same information.

Definition at line 325 of file Driver_Storage.h.

int32_t(* Initialize) (ARM_Storage_Callback_t callback)

Initialize the Storage Interface.

The function Initialize is called when the middleware component starts operation. In addition to bringing the controller to a ready state, Initialize() receives a callback handler to be invoked upon completion of asynchronous operations.

Initialize() needs to be called explicitly before powering the peripheral using PowerControl(), and before initiating other accesses to the storage controller.

The function performs the following operations:

  • Initializes the resources needed for the Storage interface.
  • Registers the ARM_Storage_Callback_t callback function.

To start working with a peripheral the functions Initialize and PowerControl need to be called in this order: drv->Initialize (...); // Allocate I/O pins drv->PowerControl (ARM_POWER_FULL); // Power up peripheral, setup IRQ/DMA

  • Initialize() typically allocates the I/O resources (pins) for the peripheral. The function can be called multiple times; if the I/O resources are already initialized it performs no operation and just returns with ARM_DRIVER_OK.
  • PowerControl (ARM_POWER_FULL) sets the peripheral registers including interrupt (NVIC) and optionally DMA. The function can be called multiple times; if the registers are already set it performs no operation and just returns with ARM_DRIVER_OK.

To stop working with a peripheral the functions PowerControl and Uninitialize need to be called in this order: drv->PowerControl (ARM_POWER_OFF); // Terminate any pending transfers, reset IRQ/DMA, power off peripheral drv->Uninitialize (...); // Release I/O pins

The functions PowerControl and Uninitialize always execute and can be used to put the peripheral into a Safe State, for example after any data transmission errors. To restart the peripheral in an error condition, you should first execute the Stop Sequence and then the Start Sequence.

Parameters
[in]callbackCaller-defined callback to be invoked upon command completion for asynchronous APIs (including the completion of initialization). Use a NULL pointer when no callback signals are required.
Note
This API may execute asynchronously if ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous execution is optional even if 'asynchronous_ops' is set.
Returns
If asynchronous activity is launched, an invocation returns ARM_DRIVER_OK, and the caller can expect to receive a callback in the future with a status value of ARM_DRIVER_OK or an error-code. In the case of synchronous execution, control returns after completion with a value of 1. Return values less than ARM_DRIVER_OK (0) signify errors.

Definition at line 414 of file Driver_Storage.h.

int32_t(* PowerControl) (ARM_POWER_STATE state)

Control the Storage interface power.

The function ARM_Storage_PowerControl operates the power modes of the Storage interface.

To start working with a peripheral the functions Initialize and PowerControl need to be called in this order: drv->Initialize (...); // Allocate I/O pins drv->PowerControl (ARM_POWER_FULL); // Power up peripheral, setup IRQ/DMA

  • Initialize() typically allocates the I/O resources (pins) for the peripheral. The function can be called multiple times; if the I/O resources are already initialized it performs no operation and just returns with ARM_DRIVER_OK.
  • PowerControl (ARM_POWER_FULL) sets the peripheral registers including interrupt (NVIC) and optionally DMA. The function can be called multiple times; if the registers are already set it performs no operation and just returns with ARM_DRIVER_OK.

To stop working with a peripheral the functions PowerControl and Uninitialize need to be called in this order:

drv->PowerControl (ARM_POWER_OFF);     // Terminate any pending transfers, reset IRQ/DMA, power off peripheral
drv->Uninitialize (...);               // Release I/O pins

The functions PowerControl and Uninitialize always execute and can be used to put the peripheral into a Safe State, for example after any data transmission errors. To restart the peripheral in an error condition, you should first execute the Stop Sequence and then the Start Sequence.

Parameters
stateARM_POWER_STATE. The target power-state for the storage controller. The parameter state can have the following values:
  • ARM_POWER_FULL : set-up peripheral for data transfers, enable interrupts (NVIC) and optionally DMA. Can be called multiple times. If the peripheral is already in this mode, then the function performs no operation and returns with ARM_DRIVER_OK.
  • ARM_POWER_LOW : may use power saving. Returns ARM_DRIVER_ERROR_UNSUPPORTED when not implemented.
  • ARM_POWER_OFF : terminates any pending data transfers, disables peripheral, disables related interrupts and DMA.
Note
This API may execute asynchronously if ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous execution is optional even if 'asynchronous_ops' is set.
Returns
If asynchronous activity is launched, an invocation returns ARM_DRIVER_OK, and the caller can expect to receive a callback in the future with a status value of ARM_DRIVER_OK or an error-code. In the case of synchronous execution, control returns after completion with a value of 1. Return values less than ARM_DRIVER_OK (0) signify errors.

Definition at line 485 of file Driver_Storage.h.

int32_t(* ProgramData) (uint64_t addr, const void *data, uint32_t size)

program (write into) the contents of a given address range of the storage device.

Write the contents of a given memory buffer into a range of storage memory. In the case of flash memory, the destination range in storage memory typically has its contents in an erased state from a preceding erase operation. The source memory buffer is owned by the caller and should remain accessible for the lifetime of this command.

Parameters
[in]addrThis is the start address of the range to be written into. It needs to be aligned to the device's program_unit specified in ARM_STORAGE_INFO.
[in]dataThe source of the write operation. The buffer is owned by the caller and should remain accessible for the lifetime of this command.
[in]sizeThe number of bytes requested to be written. The buffer should be at least as large as this size.
Note
'size' should be a multiple of the device's 'program_unit' (see ARM_STORAGE_INFO).
It is best for the middleware to write in units of 'optimal_program_unit' (ARM_STORAGE_INFO) of the device.
This API may execute asynchronously if ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous execution is optional even if 'asynchronous_ops' is set.
Returns
If asynchronous activity is launched, an invocation returns ARM_DRIVER_OK, and the caller can expect to receive a callback in the future with the number of successfully transferred bytes passed in as the 'status' parameter. In the case of synchronous execution, control returns after completion with a positive transfer-count. Return values less than ARM_DRIVER_OK (0) signify errors.

Definition at line 558 of file Driver_Storage.h.

int32_t(* ReadData) (uint64_t addr, void *data, uint32_t size)

read the contents of a given address range from the storage device.

Read the contents of a range of storage memory into a buffer supplied by the caller. The buffer is owned by the caller and should remain accessible for the lifetime of this command.

Parameters
[in]addrThis specifies the address from where to read data.
[out]dataThe destination of the read operation. The buffer is owned by the caller and should remain accessible for the lifetime of this command.
[in]sizeThe number of bytes requested to read. The data buffer should be at least as large as this size.
Note
This API may execute asynchronously if ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous execution is optional even if 'asynchronous_ops' is set.
Returns
If asynchronous activity is launched, an invocation returns ARM_DRIVER_OK, and the caller can expect to receive a callback in the future with the number of successfully transferred bytes passed in as the 'status' parameter. In the case of synchronous execution, control returns after completion with a positive transfer-count. Return values less than ARM_DRIVER_OK (0) signify errors.

Definition at line 517 of file Driver_Storage.h.

uint32_t(* ResolveAddress) (uint64_t addr)

For memory-mapped storage, resolve an address relative to the storage controller into a memory address.

Parameters
addrThis is the address for which we want a resolution to the processor's physical address space. It is an offset from the start of the storage map maintained by the owning storage controller.
Returns
The resolved address in the processor's address space; else ARM_STORAGE_INVALID_ADDRESS, if no resolution is possible.
Note
This API returns synchronously. The invocation should return quickly, and result in a resolved address.

Definition at line 689 of file Driver_Storage.h.

int32_t(* Uninitialize) (void)

De-initialize the Storage Interface.

The function Uninitialize() de-initializes the resources of Storage interface.

It is called when the middleware component stops operation, and wishes to release the software resources used by the interface.

Note
This API may execute asynchronously if ARM_STORAGE_CAPABILITIES::asynchronous_ops is set. Asynchronous execution is optional even if 'asynchronous_ops' is set.
Returns
If asynchronous activity is launched, an invocation returns ARM_DRIVER_OK, and the caller can expect to receive a callback in the future with a status value of ARM_DRIVER_OK or an error-code. In the case of synchronous execution, control returns after completion with a value of 1. Return values less than ARM_DRIVER_OK (0) signify errors.

Definition at line 434 of file Driver_Storage.h.

Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.