Name

RBL functions — allow applications to access RBL services

Synopsis

#include <cyg/rbl/rbl.h>
      

cyg_bool rbl_get_flash_details(rbl_flash_details* details);

rbl_flash_block_purpose rbl_get_flash_block_purpose(cyg_uint32 block);

cyg_bool rbl_get_block_details(rbl_block_purpose which, rbl_block_details* details);

cyg_bool rbl_update_code(void* buffer, cyg_uint32 length);

cyg_bool rbl_update_data(void* buffer, cyg_uint32 length);

cyg_bool rbl_load_data(void* buffer, cyg_uint32 length);

void rbl_reset(void);

Flash Details

rbl_get_flash_details can be used by application code to get information about the flash hardware and how it is being used by the RBL code inside RedBoot. The function takes a single argument, a pointer to an rbl_flash_details structure.

typedef struct rbl_flash_details {
    cyg_uint8*  rbl_flash_base;
    int         rbl_flash_block_size;
    int         rbl_flash_num_blocks;
    int         rbl_code_num_blocks;
    int         rbl_data_num_blocks;
    int         rbl_trailer_size;
} rbl_flash_details;

The rbl_flash_base field gives the location of the flash in the target's memory map. Application code does not usually need this information since the flash hardware is entirely managed by RedBoot, but it may be useful for debugging purposes.

The rbl_flash_block_size and rbl_flash_num_blocks provide further information about the flash hardware. Typical sets of values might be 8 blocks of 256K apiece, or 64 blocks of 64K. If the flash chips support smaller boot blocks then the eCos flash management code will usually treat these as a single full-size block.

rbl_code_num_blocks gives the number of flash blocks that will be used for the primary and the backup code blocks. It corresponds to the value of the CYGNUM_RBL_CODE_BLOCKS configuration option used when building RedBoot. rbl_data_num_blocks provides the same information for the persistent data blocks, with a value of 0 indicating that the support for persistent data was disabled.

The RBL code uses a small amount of flash memory for management purposes. This amount of memory is given by rbl_trailer_size. Application code can determine the maximum size of an executable using:

rbl_flash_details details;
if (! rbl_get_flash_details(&details)) {
    fputs("Error: failed to get RBL flash details\n", stderr);
    return false;
 }
size = (details.rbl_flash_block_size * details.rbl_code_num_blocks) -
       details.rbl_trailer_size;

The rbl_get_flash_details function will return true on success, false on failure. The most likely reason for failure is that the current RedBoot installation does not have RBL support.

Flash Blocks

rbl_get_flash_block_purpose can be used to find out how the RBL code inside RedBoot has allocated each flash block. Typically this is used only for debugging purposes. The argument should be a small number between 0 and details.rbl_flash_num_blocks - 1. The return value will be one of the following:

rbl_flash_block_reserved
This flash block is reserved, for example it may hold some or all of the RedBoot code. Flash blocks can be reserved using the configuration option CYGDAT_RBL_RESERVED_FLASH_BLOCKS when building RedBoot.
rbl_flash_block_code_A , rbl_flash_block_code_B , rbl_flash_block_data_A , rbl_flash_block_data_B
The flash block is used for an RBL code or data block.
rbl_flash_block_free
This flash block is not used by the RBL code. It may be used by application code for other purposes.
rbl_flash_block_invalid
This value will be returned if the argument to rbl_get_flash_block_purpose is outside the valid range. It will also be returned if the current RedBoot installation does not have RBL support.

RBL Block Details

rbl_get_block_details can be used to get information about a specific RBL block, for example the primary code block. The function takes two arguments. The first identifies the particular RBL block that is of interest:

rbl_block_code_primary , rbl_block_code_backup , rbl_block_data_primary , rbl_block_data_backup
These identify an RBL block by purpose.
rbl_block_code_A , rbl_block_code_B , rbl_block_data_A , rbl_block_data_B
These identify an RBL block by memory location. RedBoot will allocate flash blocks to code and data in the above order.

The second argument should be a pointer to an rbl_block_details structure which will be used for storing the results.

typedef struct rbl_block_details {
    cyg_bool    rbl_valid;
    cyg_uint32  rbl_first_flash_block;
    void*       rbl_address;
    cyg_uint32  rbl_size;
    cyg_uint32  rbl_sequence_number;
} rbl_block_details;

At any time a particular RBL block may or may not contain valid code or data. For example if the system has an installed application which has not yet been updated then the primary code block will be valid but the backup code block will be invalid. The other fields will only be valid if the rbl_valid flag is set.

The rbl_first_flash_block and rbl_address fields give information about where an RBL block is held in memory. If an RBL block is spread over multiple flash blocks then care has to be taken: there may be one or more reserved flash blocks in the middle of an RBL block.

The rbl_size field gives the current size of a code or data block. This is the actual size specified when the block was updated, not the maximum size.

The rbl_sequence_number is used by the RBL code to distinguish between primary and backup blocks. It may also prove useful for debugging purposes.

rbl_get_block_details returns true on success, false on failure. The function can fail if the current RedBoot installation does not have RedBoot support, or if an invalid argument is passed.

Updating the Code

rbl_update_code is used to install a new code image. It takes two arguments, a buffer and a length. The buffer should contain an ELF executable valid for the target platform, usually stripped to remove unnecessary debug information. Filling this buffer is left to application code.

The function returns true on success, false on failure. It can fail if the current RedBoot installation does not have RedBoot support, if an invalid argument is passed, or if the specified size is larger than the flash space available for a code block.

A flash update involves erasing one or more flash blocks and then programming in the new data. It is important that while this is happening no other threads or interrupt handlers access the flash hardware since that would interfere with the update. Hence interrupts will be disabled for some time while the update is happening.

Updating the Data

rbl_update_data is used to install a new version of the persistent data. It takes two arguments, a buffer and a length. The RBL code does not care about the contents of the buffer, this is left entirely to application code.

The function returns true on success, false on failure. It can fail if the current RedBoot installation does not have RBL support, if an invalid argument is passed, or if the specified size is larger than the flash space available for a data block. It is also possible that support for persistent data was disabled completely inside RedBoot by setting the configuration option CYGNUM_RBL_DATA_BLOCKS to 0.

A flash update involves erasing one or more flash blocks and then programming in the new data. It is important that while this is happening no other threads or interrupt handlers access the flash hardware since that would interfere with the update. Hence interrupts will be disabled for some time while the update is happening.

Loading the Data

rbl_load_data is used to load the current version of the persistent data back into memory. It takes two arguments, a buffer and a length. If there is a valid primary data block then the RBL code will transfer that data into the specified buffer. The amount of data transferred will be either the actual block size or the length argument, whichever is smaller.

The function returns true on success, false on failure. It can fail if the current RedBoot installation does not have RBL support, if an invalid argument is passed, or if there is no current primary data block.

Restarting the Hardware

rbl_reset can be used to restart the hardware. Typically this is used after a code update. The function takes no arguments and does not return.