CYGPKG_RBL — provide a robust boot service


The Robust Boot Loader (RBL) package provides an alternative to the usual RedBoot facilities for managing flash hardware, the fis and fconfig commands. It provides the following facilities:

  1. An application can be stored in flash memory. This can be loaded and run automatically during RedBoot startup, or it can started manually.
  2. The application can be updated in a robust fashion. The RBL code will automatically maintain a backup copy of the previous version of the application in flash. If something goes wrong during the update, for example a power cut, the system can still boot up using the backup.
  3. There is also support for a block of persistent data. Applications can save a block of memory to flash and restore it later, possibly after a reboot. Again updates will happen in a robust fashion with a primary and a backup copy.
  4. The RBL functionality can be accessed by application code via a suitable API. Some of the functionality is also available via RedBoot commands.

The RBL package is aimed primarily at field deployment of production systems rather than at application development. The code update facility allows the application to be updated when necessary. The persistent data can be used to hold per-unit settings and any state that should be preserved across power failures or anything else that causes a reboot. There is also some control over standard I/O: in a deployed system the serial port may be connected to some other hardware and outputting a RedBoot banner during startup could be confusing.

The package comes in two parts. When building RedBoot for a particular target platform the package detects the presence of CYGPKG_REDBOOT in the configuration and modifies the available functionality. In any other configuration, used for building the application, the package provides a set of library routines that allow access to this functionality.

The RBL code has gone through a number of versions, affecting the protocol used between the RedBoot code and the application. The version is selected via the configuration option CYGNUM_RBL_VERSION. RedBoot and the application must use the same version of RBL: an application linked against a V1 version of the RBL library routines will not work on top of a RedBoot built with the V2 code, and vice versa. By default the latest version of the protocol will be used.

RedBoot Builds

The first step in building RedBoot with RBL support is to create a RedBoot configuration appropriate for the target platform. This is somewhat target specific so the appropriate platform HAL or RedBoot documentation should be consulted for further details. Typically RedBoot should be configured for ROM startup.

Given this initial configuration the RBL package CYGPKG_RBL should now be added to the configuration, using one of the eCos configuration tools. For example with the command line tool this involves using ecosconfig add rbl. This involves a conflict related to the configuration option CYGPKG_REDBOOT_FLASH. The RBL code replaces the standard RedBoot flash support, based around the fis and fconfig commands, so that must be disabled.

It is also possible to enable the configuration option CYGOPT_RBL_FLASH_OVERRIDE to continue to permit use of RedBoot's standard flash management facilities, but use of this option is discouraged as it is possible to use RedBoot's flash management commands in ways that conflict with RBL. In particular RedBoot's FIS will not be aware of the location of the RBL-managed code and data blocks. Also, RBL is not aware of the location of RedBoot's FIS and fconfig data in Flash, so it is strongly recommended to use the CYGDAT_RBL_RESERVED_FLASH_BLOCKS option to reserve the flash area used for FIS and fconfig data, usually the final one or two blocks in flash. As a result of these sorts of complications, caution is strongly advised if considering use of CYGOPT_RBL_FLASH_OVERRIDE.

There are a number of other configuration options which may need to be changed at this point:

This determines the protocol used between the RedBoot code and the application library routines. The default is to use the latest version. If RedBoot should continue to work with existing application binaries using an older version then this configuration option should be updated to match.
This option is only of interest if the target hardware has multiple banks of flash. The current version of the package requires that all RBL code and data blocks reside in a single bank. By default this will be the same bank of flash that holds RedBoot, either as determined by CYGNUM_REDBOOT_FLASH_BASE or the first bank of flash. If CYGNUM_RBL_FLASH_BASE is enabled then its value will determine the bank of flash used for the RBL code and data blocks. This may be useful if for example the board has a small NOR flash for holding RedBoot and a much larger serial dataflash for holding the eCos application and its data.

Some of the flash blocks should not be used by the RBL package to store code or data. On a typical system it will be necessary to reserve at least flash block 0 because that is used to hold RedBoot itself. If a single flash block is too small to hold RedBoot or if there are other blocks which should be reserved then these should be listed in the value of CYGDAT_RBL_RESERVED_FLASH_BLOCKS, using a comma-separated list of numbers.

Note that if there are (smaller) boot blocks, RBL will instead consider them merged together as full sized blocks. For example, if the normal block size is 64K, but there are eight 8K boot blocks, those boot blocks will be counted as if they were another single 64K block, and the block numbers used for this option must reflect that.

The RBL code inside RedBoot needs to know how many flash blocks to allocate for the application code and for the persistent data. Because it maintains both primary and backup versions the actual requirements will be double the sum of these two options. These values will be hard-coded into the versions of RedBoot that get deployed in the field and cannot easily be changed, so they should be chosen carefully.
Because the flash is used for storing RBL blocks there is nowhere for Redboot to store an fis directory or any fconfig settings. Hence certain settings like the default IP address cannot be managed via fconfig. Instead such settings must be configured statically via configuration options. Typically this will not be a problem because RBL will be used primarily in systems deployed in the field and RedBoot is used only to start the application. If application code needs such settings then they can be held in the RBL persistent data.

Usually RedBoot will obtain its boot script, if any, from the fconfig data. This is not available when using RBL so instead the boot script should be specified using a configuration option. For a deployed system CYGDAT_REDBOOT_DEFAULT_BOOT_SCRIPT should be set to "rbl boot\n" (including the double quotes). If the flash contains a valid application then this will be loaded and run automatically.

RedBoot gives users a chance to interrupt the system before running the boot script. Typically this is irrelevant for a deployed system because there will be nothing attached to the terminal port, but it can be useful during development if for example a broken version of the application has been installed by mistake. For a deployed system it may be desirable to reduce the timeout from the default 10 seconds, so that the application restarts more quickly after a power failure.

This provides control over standard I/O behaviour and is described in more detail below.

Once RedBoot has been appropriately configured it can be built and installed as usual for the target platform.

Application Builds

In addition to the RedBoot extensions the RBL package provides a number of functions for use by application code. These functions interact with the main RBL code inside the currently installed RedBoot using the eCos virtual vector mechanism.

The RBL package is not part of any standard eCos configuration so it must be added explicitly to the configuration used for application builds, for example by using ecosconfig add. The package's CDL script will detect that CYGPKG_REDBOOT is not defined and hence know that the package is being used for an application build rather than for extending RedBoot. The package does not require any special support from other parts of eCos.

The package's misc subdirectory contains three example programs that illustrate the use of the RBL API, together with a README and various support files.

Standard I/O

The RBL package builds on standard RedBoot functionality such as boot scripts. Some of this functionality is desirable in a development environment but can cause problems for a system deployed in the field. For example during startup RedBoot will usually output a banner message via a serial port, and it will listen on that serial port for an incoming control-C character in case the developer wants to abort the boot script. When a system is deployed that serial port may be connected to other hardware which does not expect the banner message, or which might be sending a stream of data that happens to include the occasional control-C.

When configuring and building RedBoot it is possible to change the default standard I/O behaviour using the configuration option CYGGLO_RBL_STDIO. This can take one of three values:

RedBoot I/O behaves as usual, so typically the RedBoot banner will be sent out of a serial port and RedBoot will abort the boot script if it detects an incoming control-C. Application standard I/O is also not affected so for example a printf call will result in data being sent out of the serial port.
RedBoot I/O is suppressed. Any RedBoot output such as the banner message will be discarded, and incoming characters will be ignored. When the application is started via rbl boot I/O is reset so the application behaves as normal.

RedBoot I/O is suppressed as before, but I/O is not reset when the application is started. Hence any printf or similar output produced by the application gets discarded as well (at least in the default configuration where output is sent via the HAL diagnostic pseudo-device). The serial port is now available for other purposes, for example it can be accessed via a full serial driver.

Suppressing application I/O in this way will only work if the application uses the HAL virtual vector mechanisms to route I/O activity via RedBoot. If instead the application is configured to ignore the virtual vectors, for example by disabling CYGSEM_HAL_USE_ROM_MONITOR, then the RedBoot CYGGLO_RBL_OUTPUT setting will have no effect on application I/O.

Manipulating the standard I/O behaviour like this should only be done when the application will be started automatically via an rbl boot command in the boot script. If instead applications will be run via a gdb session interacting with RedBoot then suppressing RedBoot I/O will interfere with the gdb traffic.

There is also a common HAL configuration option that application developers should be aware of: CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT. By default this will be enabled for a RAM startup application. It causes the system startup code to install an interrupt handler that looks for incoming control-C characters and switch control to the gdb stubs. Usually this is sensible behaviour during development, but the option should be disabled for a deployed system. Note that it is the application configuration that needs to be changed, not the RedBoot configuration.