Name
BootUp Integration — Detail
BootUp
The BootUp support for the STM32F7xx-EVAL target is primarily
implemented in the stm32f7xx_eval_support.c
file. The majority of the functions provided by that source file are
only included when the CYGPKG_BOOTUP
package is
being used to construct the actual BootUp ROM loader binary.
The BootUp code is designed to be very simple, and it is envisaged that once its implementation has been tested and validated, the binary will only need to be installed onto a device once. Its only purpose is to allow the safe updating and startup of the main application. If the BootUp code ever needs to be replaced then it is a “factory” operation, for example using JTAG/SWD to re-program the on-chip flash.
This platform specific documentation should be read in conjunction with the generic BootUp package and bundle image support documentation.
The BootUp package provides a basic but fully functional implementation for the platform. This has been tested to ensure that the underlying mechanism is sound. It is envisaged that the developer will customize and further extend the platform side support to meet their specific application update requirements.
BootUp loaded applications
Applications started via the BootUp loader, since they cannot include
the CYGPKG_BOOTUP
package themselves, may need
access to some related configuration state. The platform is
responsible for providing such “common” information. For
example, the CDL option CYGIMP_BOOTUP_RESERVED
specifies the amount of on-chip flash set aside for
BootUp. Applications can then ensure that they do not interfere with
the BootUp loader if using the remaining on-chip flash for their own
purposes.
Warning | |
---|---|
Care must be taken to ensure that the target application configuration
matches the BootUp configuration, since it is normally expected that the
applications to be loaded will be independent of the initial BootUp
build environment. This includes the fundamental on-chip flash space
set aside for the BootUp ROM loader code
( |
The platform HAL header file
at <cyg/hal/plf_io.h>
defines the following convenience function for BootUp, and
applications started by BootUp, to ascertain the configured off-chip
bundle/update location:
extern struct cyg_flash_dev *hal_stm32f7xx_eval_source_flash(cyg_flashaddr_t *pbase,cyg_flashaddr_t *plimit);
The function will return a pointer to the relevant flash device. The
passed pbase
parameter is a pointer to the
value to be filled with the base address for the image
(or NULL
if the value is not needed by the
caller). Similarly the plimit
parameter is a
pointer to the value to be filled with the limiting address for any
image, or NULL
if the address is not needed.
Primarily to avoid source duplication,
the hal_stm32f7xx_eval_source_flash()
function
provides common run-time access to the settings derived from the CDL
options CYGIMP_BOOTUP_STM32F7XX_EVAL_SOURCE
, CYGNUM_BOOTUP_STM32F7XX_EVAL_SOURCE_OFFSET
and CYGNUM_BOOTUP_STM32F7XX_EVAL_SOURCE_LIMIT
.
Bundle based applications
When the CDL
option CYGIMP_BOOTUP_STM32F7XX_EVAL_BUNDLE
is
enabled, the STM32F7xx-EVAL platform BootUp code incorporates
the CYGPKG_BUNDLE
package and support for
bundle based application distribution.
The current STM32F7xx-EVAL platform BootUp bundle support is limited
(by design) to starting SDRAM based
applications. i.e. CYG_HAL_STARTUP_JTAG
startup
type.
Note | |
---|---|
The (slightly misleading) |
The platform HAL and CYGPKG_BUNDLE
package provide
a common set of routines shared by both BootUp and applications. This
ensures that all bundle operations are carried out in a compatible and
consistent manner.
Figure 306.1. On-chip flash
BootUp
ROMINT
application in on-chip flash
On startup the BootUp loader will use
the hal_stm32f7xx_eval_source_flash()
function to
ascertain the NVM memory used to hold the source bundle
image. If a valid bundle image is found, then the configured
“main application” item tag as specified by the CDL
option CYGNUM_BOOTUP_STM32F7XX_EVAL_BUNDLE_TAG
is
searched for within the bundle. If a valid matching tag item is found,
then the data from that item is loaded into SDRAM and executed.
Note | |
---|---|
This simple approach of using a fixed, pre-allocated, area for holding the bundle image simplifies the BootUp (and similarly any main application based update) code without the issues that would need to be considered if the bundle was stored in a filesystem. e.g. a JFFS2 filesystem on the SPI flash, with potentially slow JFFS2 mount performance, inability to ascertain how much “true” free space is available on the filesystem, programmatic support for deletion of “data” to free space for a bundle as part of an update, etc. The normal “lifetime” cycles of NOR flash (e.g. S25FL256S) should be more than sufficient for the “limited” number of in-field updates that may be undertaken on a specific board over its lifetime. |
Figure 306.2. NVM bundle
Main application held in bundle stored in NVM
If a valid bundle exists and contains a
valid CYGNUM_BOOTUP_STM32F7XX_EVAL_BUNDLE_TAG
item,
then the BootUp loader will always start that application. The BootUp
loader itself does NOT perform any update revision based automatic
update support. That support is entirely within the domain of the
started application program, which is responsible for all system
update decisions and processing.
The only case where BootUp will initiate a system update is when a
bundle is not present or is invalid, or when an otherwise valid bundle
doesn't contain a
valid CYGNUM_BOOTUP_STM32F7XX_EVAL_BUNDLE_TAG
item. In this case BootUp will attempt to install a bundle from
external media. The current example implementation uses a FATFS
formatted SD Card for this purpose.
Note | |
---|---|
A beneficial side-effect of this approach is that it can help simplify the board production process. Boards only need to be pre-initialized with the stable BootUp binary, which can then be used to install the latest application firmware in NVM. |
The example BootUp bundle support provided for this platform expects a
single release bundle to be stored in the root directory of an
inserted FATFS SD Card. The first file found that matches
the CYGDAT_BOOTUP_STM32F7XX_EVAL_BUNDLE_PREFIX
prefix is used. Any filename text after the prefix is ignored and can
contain human-readable or customer specific identification information
as required. For example,
assuming CYGDAT_BOOTUP_STM32F7XX_EVAL_BUNDLE_PREFIX
is configured as “MyProductName_”
, then
files named MyProductName_1.02
,
MyProductName_1.03.B99.1234
,
MyProductName_example.bin
would all be matched.
The SD Card FATFS filesystem is mounted read-only, so any interrupted update operations (e.g. loss-of-power, reset condition) should not affect the “validity” of the FATFS filesystem held on the SD Card.
Since only a single bundle image is held in the SPI flash there is a chance for the SPI flash based bundle to be in a “corrupt” state if an update fails (power-loss, CPU reset, etc.) during an active update. However, since an update is only manually started when a validated image is available on an SDcard, if the update is interrupted the same SDcard (and field-engineer/operator) should be available to re-apply the update on the system restart. This avoids the (normal) “robustness” requirement of providing two application images to be held in the SPI flash to ensure “safe” updates.
To reiterate, the BootUp code will ONLY perform
an update from an SD Card to the NVM when there
is NO valid main application bundle/item pair
(missing or corrupted). For in-field upgrades any update process will
be instigated under the control of the BootUp started
“main application”. For example, the application
could use the CYGPKG_BUNDLE
API to validate a
bundle image from whatever source it has access to, and then to update
the relevant NVM image itself. If the update is provided on an
SD Card then (after ensuring the SD Card does contain a
valid bundle image) the main application just needs to invalidate the
current NVM bundle image, and then force a CPU reset to have BootUp
detect the now invalid main application and apply the update. It is up
to the developer to decide the best approach for their particular
needs in how point-revision updates are installed, and is beyond the
scope of this documentation.
The bundle implementation currently limits the number of automatic
update attempts when a missing/invalid bundle is detected. This is a
deliberate choice to avoid continually failing attempts that could
eventually wear out a flash device. The
platform hal_stm32f7xx_eval_badapp()
function
implementation, when bundle support is configured, will reset the
system to allow another restart attempt if the
“Wakeup/Tamper”
(CYGHWR_HAL_STM32F7XX_EVAL_BUTTON_USER
) button is
pressed for more than one second. This can be used to manually
force another “automatic” update attempt to be started.
When BootUp has installed a bundle to the SPI flash, the last 4-bytes of the SPI flash area (partition) set aside for the bundle will be erased to 0xFFFFFFFF. This location and value can be used by the customer main application to ascertain that an install/update has just been performed (since sector erase will only occur as part of a bundle install/update). It is the responsibility of the main application to update this single location (clearing at minimum 1-bit) if it wants to track “post update” state. This can by used by the main application to acknowledge the update, and can ensure, for example, that any (potentially slow) “post update” main application specific functionality is not performed on every normal startup. For example, the main application may need to check and update the software components of attached daughter-boards from the bundle, and can use this mechanism to ensure it is only performed once after an update. This simple (erased flash) mechanism avoids complicated support for passing non-volatile “log” information between the seperate BootUp and main application worlds.
Note | |
---|---|
The main application should NOT use bit 31 of this field (treating the 32-bit value as being stored in little-endian format) since it is reserved as a flag for the BootUp loader update processing. The main application should ALWAYS leave bit 31 set. |
On-Chip ROMAPP applications
If the CDL
option CYGIMP_BOOTUP_STM32F7XX_EVAL_BUNDLE
is not
enabled, then BootUp provides an alternative mechanism that supports
the safe update of on-chip flash resident
(CYG_HAL_STARTUP_ROMAPP
) applications.
Updates using this mechanism are initiated and directed solely by the application itself. The application is responsible for locating, acquiring and verifying a new update, and placing it into NVM storage. If BootUp detects a verified update in NVM, it installs the update into the on-chip flash, overwriting and replacing the existing application. The updated application is then executed.
Figure 306.3. BootUp and Application
BootUp
ROMINT
loader andROMAPP
main application held in on-chip flash
Figure 306.4. Application Update image
Update for
ROMAPP
main application held in NVM
The example implementation uses a simple scheme that checks a
fixed-format contiguous structure near the start of the binary
application image file. Other than the fields used to identify the
structure, the BootUp code does not interpret
the hal_stm32f7xx_eval_bootup_structure_t
structure identity
field.
Depending on how the alternative (pending update) application is
downloaded and installed in the NVM, it may be more relevant to have
the tail
marker at the very end of the binary
image. The developer may wish to update the build/release process so
that the actual binary length is held in the application description
structure, since that could avoid the overhead of unnecessary flash
reads and writes when processing updates. Similarly, instead of a
simple binary number being used to differentiate application images,
the choice may be made to use the 64-bit UTC timestamp the application
was created, or a human-readable string as the unique identification
for a release. It is the responsibility of the build/release engineer
to ensure individual releases are uniquely identifiable.
It is critical that the main application, when
storing a pending update, stores the tail
marker as
the last bytes written. It is the responsibility of the main
application to verify the data written, prior to placing
the tail
marker. This ensures that a partial image
is not treated as a valid update. For example the sequence undertaken
by the main application would be:
Table 306.2. Pending update sequence
Operation | Details |
---|---|
Invalidate “previous” alternative image |
At a minimum ensure an invalid signature tail
marker is written. Erasing the flash is normally required anyway, and
would invalidate any previous image.
|
Receive update application image and write to alternative image location |
NOT writing the tail marker. The code that stores the
application should leave a “hole” where
the tail marker resides to ensure a partial image
is not incorrectly treated as valid
|
Verify downloaded contents | e.g. CRC or binary comparison. Normally this would be done as individual application chunks are downloaded and written to the alternative storage |
Write tail marker |
This is the very last operation after validating that the alternative
image has been stored correctly. If an error has occured during the
download then not-writing the tail ensures that the
BootUp loader will not interpret the data written as a pending
update
|
Force system RESET to start update | e.g. using the HAL_PLATFORM_RESET macro |
The BootUp loader code will only READ from the alternative image location. This ensures that if an in-progress update is interrupted (e.g. power-loss) then when the system restarts the BootUp code will restart the application update as required.
If the BootUp platform implementation for validating the alternative
image is extended to include a CRC, or similar “slow”
processing, it may be worth considering whether the main application
on startup will always invalidate the tail
marker
after an update to avoid subsequent system resets having to
re-validate the alternative image prior to discovering that it is the
same as the current main application.
Note | |
---|---|
We cannot have the SIGNATURE support purely conditional on the BOOTUP support; since non-BOOTUP applications need to be built leaving the space. For the moment this is only enforced for ROMAPP applications, since that is all that the simple (non-BUNDLE) BootUp update support implements. |
Building BootUp
The ROMINT
startup type is chosen for BootUp so
that the loader uses the on-chip SRAM for its workspace, to avoid the
overhead of managing off-chip memory where the target application will
be loaded.
Example eCos configuration templates for BootUp are provided in the
misc
directory of the
release. The hostboot_ROMINT.ecm
configuration
file can be used to construct a bundle based BootUp loader
and bootup_ROMINT.ecm
for the simpler on-chip
ROMAPP update BootUp loader.
Building a BootUp ROM image is most conveniently done at the command
line. For the stm32f746g_eval2
, the steps needed
to rebuild the bundle based ROMINT version of BootUp on linux are:
$mkdir hostboot_romint
$cd hostboot_romint
$ecosconfig new stm32f746g_eval2 minimal
[ … ecosconfig output elided … ] $ecosconfig import $ECOS_REPOSITORY/hal/cortexm/stm32/stm32f7xx_eval/current/misc/hostboot_ROMINT.ecm
$ecosconfig resolve
$ecosconfig tree
$make
The steps needed to rebuild the bundle based ROMINT version of BootUp on Windows within the Shell Environment are
C:\Users\demo>mkdir hostboot_romint
C:\Users\demo>cd hostboot_romint
C:\Users\demo\hostboot_romint>ecosconfig new stm32f746g_eval2 minimal
[ … ecosconfig output elided … ] C:\Users\demo\hostboot_romint>ecosconfig import \ %ECOS_REPOSITORY%/hal/cortexm/stm32/stm32f7xx_eval/current/misc/hostboot_ROMINT.ecm
C:\Users\demo\hostboot_romint>ecosconfig resolve
C:\Users\demo\hostboot_romint>ecosconfig tree
C:\Users\demo\hostboot_romint>make
The resulting install/bin/bootup.bin
binary can
then be programmed into the on-chip flash from
address 0x08000000
.
It is expected that the BootUp binary is installed onto
the STM32F427 on-chip flash either via JTAG/SWD or by utilising
the on-chip BootROM
USB based DFU process. This is
a factory or in-field process requiring specific
equipment/host-software.
Once BootUp is installed it is not normally expected to require
updating. Its purpose is to bootstrap the main application, and
provide a standard mechanism for installing the main application. The
update mechanism does NOT provide a method for
updating the BootUp loader itself. If in-field updates of the BootUp
binary are necessary, this could be achieved via the STM32
on-chip BootROM
USB based DFU process.
BootUp Test Programs
The tests/bundle_example.c
source implements a
simple example of an application that utilises
the CYGPKG_BUNDLE
package. Its code could serve as
a useful starting point when adding bundle update support to your own
application.
Normally a standard CYG_HAL_STARTUP_JTAG
configured
build of the bundle_example would be used. If the
bootup application is used to bootstrap the processor
and is built as described in
Building
BootUp, the eCos Configuration against
which bundle_example is linked must also include
“CRC Support” (CYGPKG_CRC
),
“Zlib compress/decompress support”
(CYGPKG_COMPRESS_ZLIB
), “File IO”
(CYGPKG_IO_FILEIO
) and
“Generic FLASH memory support”
(CYGPKG_IO_FLASH
).
As well as ensuring the required packages are present in the
configuration, the CDL
option CYGBLD_HAL_CORTEXM_STM32F7XX_EVAL_TESTS_MANUAL
,
and its
sub-option CYGBLD_HAL_CORTEXM_STM32F7XX_EVAL_TEST_BOOTUP
,
should be enabled to allow bundle_example to be
built.
Note | |
---|---|
If required, the release provides an example “default”
template for the |
Once built, a raw binary copy of the application would be extracted for adding to a bundle using the arm-eabi-objcopy command. For example:
$ arm-eabi-objcopy -O binary bundle_example bundle_example.bin
The resulting binary could then be added to a bundle image using the host-based bundle tool:
$ bundle MyProductName_example.bin create add 0x0001:bundle_example.bin:C:md5
Refer to the bundle host tool section for detailed information on the bundle host tool.
In this example the bundle image would then be placed onto a suitably formatted FATFS SD Card. The bundle would then be installed into the NVM either by a pre-existing main application, or by the BootUp loader if a valid bundle is not currently installed in the NVM.
Note | |
---|---|
When placing the bundle image onto a FATFS SD Card only
the |
The provided bundle_invalidate test can be used during BootUp bundle testing to explicitly invalidate any NVM held bundle. This can be done to check the BootUp operation when no valid bundle containing a main application is available, e.g. to test installation from FATFS SD Card.
2024-03-18 | eCosPro Non-Commercial Public License |