Name

ecoflash — Flash Programming Utility

Synopsis

ecoflash ---help [subcommand]
ecoflash [(1) options] boards
ecoflash [(1) options] info
ecoflash [(1) options] program [[-r] | [--raw]] [[-n] | [--no-erase]] { file } [ address ]
ecoflash [(1) options] dump [[-a] | [--append]] { file } [ address ] [ length ]
ecoflash [(1) options] erase { address } [ length ]
ecoflash [(1) options] write [[-n] | [--no-erase]] [[-o offset] | [--offset=offset]] { file } { address } [ length ]
ecoflash [(1) options] lock { address } [ length ]
ecoflash [(1) options] unlock { address } [ length ](1)
[[-h] | [--help]]
[--version]
[--dry-run]
[[-q] | [--quiet]]
[[-v] | [--verbose]]
[[-b board] | [--board=board]]
[[-g gdb executable] | [--gdb=gdb executable]]
[[-o objcopy executable] | [--objcopy=objcopy executable]]
[[-t target command] | [--target=target command]]

Description

ecoflash is a utility for programming on-board flash via BDM, jtag, or similar hardware debug technology. There is nothing particularly original about this. Most manufacturers will provide similar utilities, and in fact those are likely to offer better performance because they operate at a lower level. The main advantages of ecoflash are: it provides a common user experience across a range of hardware; it is designed to work within a typical eCos development environment; and it has some built-in knowledge of how eCos systems work.

ecoflash works by running a suitable version of gdb on the host machine and running gdb commands. That version of gdb must either be able to drive the hardware debug technology directly, or more commonly it will in turn interact with some stub or daemon that knows how to drive the debug hardware. The target is initialized and a small target-side executable, for example m5213evb_flash.elf, is then loaded on to the target. The target-side executable is a simple eCos application that is linked with the eCos flash driver support, so it can be readily ported to any target for which a suitable flash driver is available. Manipulating the flash involves setting target-side variables used gdb commands, letting the target-side executable run until a breakpoint is hit, and then examining more target-side variables to determine the status.

The basic syntax is: ecoflash [standard options] subcommand [options] args [optional args]. The standard options provide information such as the target board, and most of these can be specified instead using environment variables. The subcommands specify the exact operation to be performed, for example to program an executable at the default location within the flash. Some subcommands take additional options, for example to suppress automatic erasure of flash blocks. These are followed by required arguments such as the executable filename, and possibly optional arguments. ecoflash -h with no additional argument provides help information for the utility as a whole. Additional information for a specific subcommand can be obtained using e.g. ecoflash -h program.

Standard Options

ecoflash accepts a number of standard options, for example the target board can be specified using -b board. These options will be used by several but not all of the subcommands.

-h, --help
Obtain help information about ecoflash or one of its subcommands.
--version
Display the ecoflash version string.
--dry-run
This suppresses the low-level block erase and write operations so the flash state does not actually change, but otherwise ecoflash operates normally including initializing the board, downloading the target-side executable, and having the latter initialize the eCos flash driver. It can be used to verify that the hardware is operating correctly.
-q, --quiet, -v, --verbose
These can be used to reduce or increase the amount of feedback generated by ecoflash. -v can be specified several times for increased verbosity.
-b <board>, --board=<board>

ecoflash needs to know which target board it should access, so that it can perform appropriate initialization and download the right target-side executable. ecoflash boards can be used to get a list of supported boards. It is possible to set an environment variable ECOFLASH_BOARD as an alternative to specifying this option on the command line every time:

$ export ECOFLASH_BOARD=m5213evb

The board name has two effects. It causes ecoflash to load a configuration file <board>.ecf with hardware-specific information, for example how to initialize the board using gdb commands. It also determines the target-side executable <board>_flash.elf. For both files ecoflash will first look in the current directory. If an ECOFLASH_DIR environment variable is defined then it will look in that directory. Finally it will look in the directory ../share/ecos/ecoflash relative to the ecoflash executable.

-g <gdb executable>, --gdb=<gdb executable>
All subcommands except boards involve starting a gdb session on the host and downloading a target-side executable. Usually the gdb executable, for example m68k-elf-gdb, is specified in the board .ecf configuration file and found in the current PATH, so there is no need to use this option. However an alternative gdb can be specified if desired, for example when building and debugging an experimental version of gdb. The environment variable ECOFLASH_GDB can also be used instead of the command line option.
-o <objcopy executable>, --objcopy=<objcopy executable>
The program subcommand can take an eCos executable in ELF format and automatically convert it to raw binary to program into flash. This involves running the appropriate host-side objcopy utility, for example m68k-elf-objcopy. By default ecoflash will munge the gdb file name to generate the objcopy name and will look for it on the PATH, so there is no need to use this option. An alternative objcopy can be specified on the command line or via the ECOFLASH_OBJCOPY environment variable.
-t <target command>, --target=<target command

ecoflash needs to know how to get gdb to interact with the debug hardware. The exact details of this depend not just on the hardware but also on the developer's setup, so cannot be provided by the board .ecf configuration file. Instead it must be provided by the user, in the form of a gdb target command. For example, if the debug hardware is accessed via a daemon on the local machine and that daemon listens on TCP/IP port 9000 for gdb remote protocol traffic then the gdb command to connect to the target hardware would be: target remote localhost:9000. The ecoflash -t option should consist of everything after target, for example:

$ ecoflash -b alaia -t 'remote localhost:9000' info

Note the use of quote marks to make the shell treat it as a single argument, even though it contains spaces, and to prevent any processing of special characters like $ and |. The ECOFLASH_TARGET environment variable can be set instead:

$ export ECOFLASH_TARGET='remote localhost:9000'

Supported Boards

ecoflash boards can be used to get the names of the boards supported in the current installation, in other words what -b options are valid. A board is considered supported if ecoflash can find a <board>.ecf configuration file and a target-side executable <board>_flash.elf. It will search in the current directory, in the directory specified by the ECOFLASH_DIR environment variable if that is defined, and in a directory relative to the ecoflash executable. For example if ecoflash is installed in /usr/local/ecos/bin then it will search in /usr/local/ecos/share/ecos/ecoflash.

Note that ecoflash boards only examines the file system and does not attempt to start gdb or interact in any way with target hardware.

Board Information

ecoflash info can be used to get information about a particular board, and also to verify that everything is working correctly.

% ecoflash -b m5213evb -t 'remote localhost:9000' info
Target board is m5213evb.
  gdb is "m68k-elf-gdb", gdb target is "remote localhost:9000"
  Target-side executable is version 1.
  Detected 1 bank of flash.
    Start 0x00000000, end 0x0003ffff -> 256K.
      128 blocks of 2K.
  Flash block locking is not supported.
  Default program location for executables is 0x00000000.
  Target-side buffer for read and write operation is 16K.

This shows the gdb command and the target string, which can be useful if that information comes from environment variables rather than the command line. ecoflash will run gdb and download the target-side executable, which reports itself as version 1. The target-side executable initializes the eCos flash driver and has detected the amount of flash reported and that lock and unlock operations are not supported. By default executables will be programmed at location 0x0, and transfers between host and target use a 16k buffer (the M5213EVB only has a small amount of RAM, usually a larger buffer will be used).

Programming an Executable

ecoflash program can be used to install an eCos executable at the boot location within the flash. The executable should be linked against an eCos configuration with a suitable startup type, usually ROM or ROMRAM although this may vary between platforms. In its simplest form the subcommand just takes a single argument, a filename for the executable:

$ ecoflash program redboot.elf
Erasing 0x00000000 - 0x0000be57
Writing 0x00000000 - 0x00003fff (16384 bytes) from file "/tmp/redboot.1495", offset 0
Writing 0x00004000 - 0x00007fff (16384 bytes) from file "/tmp/redboot.1495", offset 16384
Writing 0x00008000 - 0x0000be57 (15960 bytes) from file "/tmp/redboot.1495", offset 32768

This assumes the ECOFLASH_BOARD and ECOFLASH_TARGET environment variables are set. ecoflash will examine the specified file. ELF executables will be automatically converted to a temporary raw binary file before being programmed into flash, using the objcopy utility. The default address within the flash is supplied by the target-side executable. Usually this will be the processor's boot location but the exact boot mechanism varies widely between processors and platforms.

ecoflash program takes two options. -r or --raw can be used to suppress the detection of ELF format files. Instead the file will be treated as a raw binary and no conversion is performed. This may be useful if the board has its own primary bootloader which expects to find an ELF executable at a particular address within the flash. -n or --no-erase can be used to suppress the automatic erase of the flash blocks prior to programming the flash. This may be useful on hardware where flash erase is optional, or if ecoflash is used in a batch environment where a previous step will have already erased the required amount of flash.

ecoflash program takes an optional additional argument, an alternative address within the flash. This may be useful if for example the board can boot from one of two locations depending on the state of a jumper.

Dumping Flash Contents

ecoflash dump can be used to read part or all of the flash and dump the data to a file on the host. This can be particularly useful when saving a known working image prior to replacing it with an experimental version. The default behaviour is to dump the entire flash contents:

$ ecoflash dump /tmp/working.bin
Dumping 0x00000000 - 0x00003fff (16384 bytes) to file "/tmp/working.bin"
Dumping 0x00004000 - 0x00007fff (16384 bytes) to file "/tmp/working.bin"
…

Optionally the starting address and the length can be specified:

$ ecoflash dump /tmp/working.bin 0xFFF00000 128K

Lengths can be specified in bytes, kilobytes using a K suffix, megabytes using an M suffix, or flash blocks using a B suffix. Note that some flash devices have boot blocks of varying sizes so specifying a size in terms of blocks can be confusing.

ecoflash dump takes a single option, -a or --append. This causes ecoflash to append to the specified file instead of overwriting it.

Erasing Flash Blocks

ecoflash erase can be used to erase one or more flash blocks. This command is rarely needed since both the program and write subcommands will erase the required number of flash blocks by default, but may prove useful if the flash contains data other than an eCos executable and that data should be reset to uninitialized. In its simplest form the erase subcommand just takes an address:

$ ecoflash erase 0x40000

This causes ecoflash to erase the single flash block containing the specified address. Optionally a length can be specified, for example to erase 8 flash blocks:

$ ecoflash erase 0x40000 8B

The length can be specified in bytes, in kilobytes using a K suffix, in megabytes using an M suffix, or in flash blocks using a B suffix. Care must be taken if the specified address is not at the start of a flash block. For example if the address is 0x48000, the length is 128K, and flash blocks are 64K, then this is treated as a request to erase flash from 0x48000 to 0x67FFF. Since erase operations always involve whole flash blocks the actual erase affects all memory from 0x40000 to 0x6FFFF, so a total of 192K gets erased.

The erase subcommand does not have any options of its own, just the standard ones for all subcommands.

Writing Raw Data

ecoflash write can be used to write a raw data file to an arbitrary location within the flash. It is intended for installing additional data rather than the main executable, since the program subcommand is more appropriate for the latter. At least a filename and an address within the flash should be specified:

$ ecoflash write data.bin 0x00040000
Erasing 0x00040000 - 0x0004297c
Writing 0x00040000 - 0x0004297c (10621 bytes) from file "data.bin", offset 0

Optionally a length can be specified, for example:

$ ecoflash write data.bin 0x00040000 64K

This will write only the first 64K of data.bin rather than the whole file. The length can be specified in bytes, in kilobytes using a K suffix, in megabytes using an M suffix, or in flash blocks using a B suffix.

ecoflash write takes two options. -n or --no-erase can be used to suppress the automatic erase before the data is written to flash. This can be useful if a single flash block should contain data from more than one file: ecoflash erase would be used to erase the whole flash black, then two ecoflash write -n commands would program the two files at the appropriate locations; alternatively the erase step can be skipped in subsumed by the first write, with only the second write using a -n option.

-o <offset> or -offset=<offset> can be used to skip part of a file. For example the following writes 12K of a file starting at a 4K offset:

$ ecoflash write --offset=4096 data.bin 12K

The offset can be specified in bytes, kilobytes using a K suffix, or megabytes using an M suffix.

Locking and Unlocking

On targets where the hardware and the flash driver support locking, the lock and unlock subcommands can be used to manipulate the locked status of one or more flash blocks. Both subcommands take an address and an optional length:

$ ecoflash lock 0x40000
…
$ ecoflash unlock 0x50000 256K

If no length is specified then just a single flash block is affected, unless the hardware implements locking at a coarser grain than individual flash blocks. The length can be specified in bytes, in kilobytes using a K suffix, in megabytes using an M suffix, or in flash blocks using a B suffix.

With some flash hardware locking is not persistent. Instead the locks are set to a default state when the flash chips are powered up or reset, usually locked. On such hardware the ecoflash lock and unlock subcommands are of little use since the locks would revert to their default state when ecoflash exits. Instead the target-side executable will either unlock all flash blocks during initialization or take whatever action is needed at run-time to handle erase and write operations.

Installation

Depending on your eCos distribution ecoflash may already be installed on your system. If not, installation is straightforward. The host-side consists of a single executable ecoflash in the package's host subdirectory. This is actually a platform-independent script written in the expect scripting language. It needs to be installed in a suitable location on the user's search PATH. The file can just be copied manually, or alternatively the host subdirectory contains a suitable configure script and support files:

$ <package path>/host/configure --prefix=/usr/local
$ make
$ make install

This will install ecoflash in the directory /usr/local/bin. Note that eCos also has a top-level configure script which will find subsidiary configure scripts inside the individual packages. A top-level configure/make/make install sequence will automatically install ecoflash as well as host-side support from other packages.

The ecoflash package contains only the generic support. It should be complemented by a .ecf configuration file and a _flash.elf target-side executable for every supported platform. The platform HAL's misc subdirectory usually holds a suitable .ecf file. The target-side executable will need to be rebuilt:

$ ecosconfig new <target> minimal
$ ecosconfig import <path>/ecoflash.ecm
$ ecosconfig tree
$ make

For an existing port there should be an ecoflash.ecm file in the platform HAL's misc subdirectory. Importing this will add the ecoflash package and any necessary support packages, set any platform-specific configuration options, and resolve any conflicts. After the make there should be a file install/bin/flash.elf, the target-side executable, and this should get renamed to <board>_flash.elf and installed in a location where ecoflash will find it.

Porting

Typically the only hard part of porting ecoflash to a new platform is to get gdb to interact with the jtag or BDM hardware and initialize the board. The porting process involves three steps: adding appropriate definitions to the platform HAL; building the target-side executable <board>_flash.elf; and writing the platform configuration file <board>.ecf.

The platform HAL must supply a single #define'd symbol corresponding to the default base address for ecoflash program operations. Usually this symbol gets defined in cyg/hal/plf_io.h, but the details may vary between architectures.

#define HAL_ECOFLASH_PROGRAM_BASE        0x00000000

Optionally the platform HAL can define a buffer size using HAL_ECOFLASH_BUFLEN, an additional header file to include using HAL_ECOFLASH_HEADER, and an initialization macro HAL_ECOFLASH_EXTRA_INIT(). The latter may perform operations such as unlocking all flash blocks on hardware where locks are transient.

The target-side executable is a very simple eCos application that uses the generic flash driver support to interact with the the hardware. Hence it assumes that a suitable flash driver is already available. Code and data sizes are both of the order of 4K, although obviously that will depend on the processor architecture. Usually the code will be RAM-resident and linked with a JTAG or RAM startup configuration. In addition a buffer is needed for transferring data between host and target. By default that buffer is 64K, corresponding to typical flash block sizes, but can be smaller if there is not enough RAM for a buffer that size. Building the target-side executable is straightforward:

$ ecosconfig new <target> minimal
$ ecosconfig add CYGPKG_IO_FLASH CYGPKG_LIBC_STRING CYGPKG_ECOFLASH
$ ecosconfig resolve
$ ecosconfig tree
$ make

It may be necessary to tweak the configuration data before generating the build tree, for example to change the startup type to JTAG or RAM. Adding the ecoflash package will result in one conflict related to the global compiler flags: by default ecoflash is built with no eCos debugging information, except for the ecoflash application itself. The target-side executable may get checked into the source code control system as a binary, so avoiding debug information helps to keep the size down. Stripping out all debug information after the build is not possible because it would interfere with some of the gdb commands that ecoflash uses to interact with the target.

The result of the make is an executable flash.elf in the install/bin subdirectory. This should get renamed to <target>_flash.elf and installed to a directory where ecoflash will find it. Optionally an ecoflash.ecm file containing the configuration settings can be exported to facilitate future rebuilding.

Next it is necessary to write the configuration file <target>.ecf. This is a straightforward expect script that gets included by the main ecoflash executable. It should set variables ::gdb_executable and ::command_prefix. Optionally it may also define procedures target_init0, target_init1, and target_kill. target_init0 is invoked after gdb has been started but before the gdb target command has been issued. target_init1 is invoked after the gdb target command has been issued, and typically takes care of initializing the board via a sequence of gdb commands. To facilitate this the main ecoflash script provides procedures gdb_run_command and gdb_run_quiet_command which will do the hard work. target_kill is invoked just before shutting down the gdb session. The <target>.ecf file is typically placed in the platform HAL's misc subdirectory.