BeRTOS
Data Structures | Defines | Typedefs | Functions
KBlock interface
BeRTOS core functionality

KBlock interface. More...

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)

Detailed Description

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);
 }
Note:
The KBlock interface is optimized for block reads. If you need a file-like access, you can use KFile interface over KBlock.
Author:
Francesco Sacchi <batt@develer.com>

Typedef Documentation

typedef uint32_t block_idx_t

Type for addressing blocks in the device.

Definition at line 88 of file kblock.h.


Function Documentation

bool kblock_buffered ( struct KBlock b) [inline]
Returns:
true if the device b is buffered, false otherwise.
Parameters:
bKBlock device.
See also:
kblock_cachedBlock(), kblock_cacheDirty().

Definition at line 274 of file kblock.h.

block_idx_t kblock_cachedBlock ( struct KBlock b) [inline]
Returns:
The current cached block number if the device is buffered.
Parameters:
bKBlock device.
Note:
This function will throw an ASSERT if called on a non buffered KBlock.
See also:
kblock_buffered(), kblock_cacheDirty().

Definition at line 287 of file kblock.h.

bool kblock_cacheDirty ( struct KBlock b) [inline]

Return the status of the internal cache.

Parameters:
bKBlock device.
Returns:
If the device supports buffering, returns true if the cache is dirty, false if the cache is clean and coherent with device content.
Note:
This function will throw an ASSERT if called on a non buffered KBlock.
See also:
kblock_cachedBlock(), kblock_buffered().

Definition at line 303 of file kblock.h.

void kblock_clearerr ( struct KBlock b) [inline]

Clear the errors of the device.

Parameters:
bKBlock device.
See also:
kblock_error()

Definition at line 238 of file kblock.h.

int kblock_close ( struct KBlock b) [inline]

Close the device.

Parameters:
bKBlock device.
Returns:
0 on success, EOF on errors.

Definition at line 263 of file kblock.h.

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.

Note:
This function is available only on devices which support partial block write or are opened in buffered mode.
Parameters:
bKBlock device.
srcsource block number.
destdestination block number.
Returns:
0 if all is OK, EOF on errors.

Definition at line 196 of file kblock.c.

int kblock_error ( struct KBlock b) [inline]

Get the current errors for the device.

Note:
Calling this function will not clear the errors.
Parameters:
bKBlock device.
Returns:
0 if no error is present, a driver specific mask of errors otherwise.
See also:
kblock_clearerr()

Definition at line 224 of file kblock.h.

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.

Returns:
0 if all is OK, EOF on errors.
See also:
kblock_read(), kblock_write(), kblock_buffered().

Definition at line 117 of file kblock.c.

bool kblock_partialWrite ( struct KBlock b) [inline]
Returns:
true if the device b supports partial block write. That is, you can call kblock_write() with a size which is lesser than the block size.
Parameters:
bKBlock device.
See also:
kblock_write().

Definition at line 316 of file kblock.h.

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.

Note:
This function can be slow if you try to partial read a block from a device which does not support partial block reads and is opened in unbuffered mode.
Parameters:
bKBlock device.
idxthe block number where you want to read.
bufa buffer where the data will be read.
offsetthe offset inside the block from which data reading will start.
sizethe size of data to be read.
Returns:
the number of bytes read.
See also:
kblock_write().

Definition at line 103 of file kblock.c.

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.
Parameters:
bKBlock device.
startThe index of the start block for the limiting window in logical addressing units.
countThe number of blocks to be used.
Returns:
0 if all is OK, EOF on errors.

Definition at line 152 of file kblock.c.

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.

Note:
Partial block writes are supported only on certain devices. You can use kblock_partialWrite() in order to check if the device has this feature or not.
If the device is opened in buffered mode, this function will use efficiently and trasparently the cache provided. In order to be sure that all modifications are actually written to the device you have to call kblock_flush().
Parameters:
bKBlock device.
idxthe block number where you want to write.
bufa pointer to the data to be written.
offsetthe offset inside the block from which data writing will start.
sizethe size of data to be written.
Returns:
the number of bytes written.
See also:
kblock_read(), kblock_flush(), kblock_buffered(), kblock_partialWrite().

Definition at line 169 of file kblock.c.