BeRTOS
|
Data Structures | |
struct | KBlock |
KBlock: interface for a generic block device. More... | |
Defines | |
#define | KB_BUFFERED BV(0) |
Internal flag: true if the KBlock has a buffer. | |
#define | KB_CACHE_DIRTY BV(1) |
Internal flag: true if the cache is dirty. | |
#define | KB_PARTIAL_WRITE BV(2) |
Internal flag: true if the device allows partial block write. | |
Typedefs | |
typedef uint32_t | block_idx_t |
Type for addressing blocks in the device. | |
Functions | |
int | kblock_trim (struct KBlock *b, block_idx_t start, block_idx_t count) |
Use a subset of the blocks on the device. | |
int | kblock_error (struct KBlock *b) |
Get the current errors for the device. | |
void | kblock_clearerr (struct KBlock *b) |
Clear the errors of the device. | |
int | kblock_flush (struct KBlock *b) |
Flush the cache (if any) to the device. | |
int | kblock_close (struct KBlock *b) |
Close the device. | |
bool | kblock_buffered (struct KBlock *b) |
block_idx_t | kblock_cachedBlock (struct KBlock *b) |
bool | kblock_cacheDirty (struct KBlock *b) |
Return the status of the internal cache. | |
bool | kblock_partialWrite (struct KBlock *b) |
size_t | kblock_read (struct KBlock *b, block_idx_t idx, void *buf, size_t offset, size_t size) |
Read data from the block device. | |
size_t | kblock_write (struct KBlock *b, block_idx_t idx, const void *buf, size_t offset, size_t size) |
Write data to the block device. | |
int | kblock_copy (struct KBlock *b, block_idx_t src, block_idx_t dest) |
Copy one block to another. | |
Prototypes for KBlock low level access functions. | |
When writing a driver implementing the KBlock interface you can choose which function subset to implement, but you have to set to NULL unimplemented features. | |
typedef size_t(* | kblock_read_direct_t )(struct KBlock *b, block_idx_t index, void *buf, size_t offset, size_t size) |
typedef size_t(* | kblock_write_direct_t )(struct KBlock *b, block_idx_t index, const void *buf, size_t offset, size_t size) |
typedef size_t(* | kblock_read_t )(struct KBlock *b, void *buf, size_t offset, size_t size) |
typedef size_t(* | kblock_write_t )(struct KBlock *b, const void *buf, size_t offset, size_t size) |
typedef int(* | kblock_load_t )(struct KBlock *b, block_idx_t index) |
typedef int(* | kblock_store_t )(struct KBlock *b, block_idx_t index) |
typedef int(* | kblock_error_t )(struct KBlock *b) |
typedef void(* | kblock_clearerr_t )(struct KBlock *b) |
typedef int(* | kblock_close_t )(struct KBlock *b) |
KBlock interface.
A block device is a device which can only be read/written with data blocks of constant size: flash memories, SD cards, hard disks, etc... This interface is designed to adapt to most block devices and use peculiar features in order to save CPU time and memory space.
There is no init function because you do not have to use this structure directly, specific implementations will supply their own init functions.
Error handling is done in a way similar to standard C library: whenever a function (eg. kblock_flush()) returns error, you need to check the error code, which is implementation specific.
Example of code flow:
// init a KBlock-derived class Flash fls; flash_init(&fls.blk, 0); // use kblock_* functions to access the derived class kblock_write(&fls.blk, ...); if (kblock_flush(&fls.blk) == EOF) { // oops, error occurred! int err = kblock_error(&fls.blk); // handle Flash specific error conditions // ... // clear error condition kblock_clearerr(&fls.blk); }
typedef uint32_t block_idx_t |
bool kblock_buffered | ( | struct KBlock * | b | ) | [inline] |
b | KBlock device. |
block_idx_t kblock_cachedBlock | ( | struct KBlock * | b | ) | [inline] |
b | KBlock device. |
bool kblock_cacheDirty | ( | struct KBlock * | b | ) | [inline] |
Return the status of the internal cache.
b | KBlock device. |
void kblock_clearerr | ( | struct KBlock * | b | ) | [inline] |
int kblock_close | ( | struct KBlock * | b | ) | [inline] |
int kblock_copy | ( | struct KBlock * | b, |
block_idx_t | src, | ||
block_idx_t | dest | ||
) |
Copy one block to another.
This function will copy the content of block src to block dest.
b | KBlock device. |
src | source block number. |
dest | destination block number. |
int kblock_error | ( | struct KBlock * | b | ) | [inline] |
Get the current errors for the device.
b | KBlock device. |
int kblock_flush | ( | struct KBlock * | b | ) |
Flush the cache (if any) to the device.
This function will write any pending modifications to the device. If the device does not have a cache, this function will do nothing.
bool kblock_partialWrite | ( | struct KBlock * | b | ) | [inline] |
b | KBlock device. |
size_t kblock_read | ( | struct KBlock * | b, |
block_idx_t | idx, | ||
void * | buf, | ||
size_t | offset, | ||
size_t | size | ||
) |
Read data from the block device.
This function will read size bytes from block idx starting at address offset inside the block.
Most block devices (almost all flash memories, for instance), can efficiently read even a part of the block.
b | KBlock device. |
idx | the block number where you want to read. |
buf | a buffer where the data will be read. |
offset | the offset inside the block from which data reading will start. |
size | the size of data to be read. |
int kblock_trim | ( | struct KBlock * | b, |
block_idx_t | start, | ||
block_idx_t | count | ||
) |
Use a subset of the blocks on the device.
This function is useful for partitioning a device and use it for different purposes at the same time.
This function will limit the number of blocks used on the device by setting a start index and a number of blocks to be used counting from that index.
The blocks outside this range are no more accessible.
Logical block indexes will be mapped to physical indexes inside this new range automatically. Even following calls to kblock_trim() will use logical indexes, so, once trimmed, access can only be limited further and never expanded back.
Example:
//...init KBlock device dev kblock_trim(dev, 200, 1500); // Restrict access to the 200-1700 physical block range. kblock_read(dev, 0, buf, 0, dev->blk_size); // Read from physical block #200. kblock_trim(dev, 0, 300); // Restrict access to the 200-500 physical block range.
b | KBlock device. |
start | The index of the start block for the limiting window in logical addressing units. |
count | The number of blocks to be used. |
size_t kblock_write | ( | struct KBlock * | b, |
block_idx_t | idx, | ||
const void * | buf, | ||
size_t | offset, | ||
size_t | size | ||
) |
Write data to the block device.
This function will write size bytes to block idx starting at address offset inside the block.
b | KBlock device. |
idx | the block number where you want to write. |
buf | a pointer to the data to be written. |
offset | the offset inside the block from which data writing will start. |
size | the size of data to be written. |