In previous posts about Flash programming, we’ve briefly touched on address
offsets and how important it is to understand to which addresses (system level
or Flash level) the data should be programmed. Let’s expand on this concept and
try to understand why and how we should use address offsets in certain cases.
We see a common scenario related to boundary-scan based in-system programming
that usually goes something like this:
"We’ve programmed and verified the Flash, but the board still doesn’t boot.
We used our development tools to look at the Flash and the data is not there. If
the verify step really did its job, why doesn’t the board boot and why don’t we
see the data?"
This situation is quite often due to a misunderstanding about which address
offset value should be used when programming. Let’s take a look at how we can
ensure that the data to be programmed always goes into the same space.
System Address Space vs. Flash Address Space
Consider the simplified diagram below. The system includes a Flash device at
address in the system address space of 0xC0000000. The Flash device itself has
1G address locations, or a maximum address in the Flash address space of
Figure 1: System and Flash Memory Maps
Why does this matter to the test engineer?
The problem comes from differences in perspective: the system software/firmware
developers are usually looking at the Flash from one step removed and looking at
system addresses—the system’s CPU is taking care of all the details about how to
control the Flash memory. Along the same lines, development tools that utilize
the CPU or in-circuit emulator will maintain this perspective and generate
programming files targeted at the system address.
For test engineers using boundary-scan for tests and ISP, the CPU’s core logic
is not running and doesn’t come into play. Boundary-scan has to take the place
of the CPU and directly control the Flash, meaning test engineers and the tools
they use are looking directly at the Flash pins and nothing else in the system.
In other words, the Flash always starts at address zero from this perspective!
So, how can we reconcile these two viewpoints? Let’s look at the most common
The Flash part to be programmed is mapped to some non-zero location in system
address space, for example 0xC0000000. A data file is generated by the
development tools with address information, such that the data file begins with
In this case, a “Subtract” offset should be used. There is no such thing as
address 0xC0000000 in our Flash device. By entering a value of "0xC0000000" in
the address offset field and selecting “Subtract”, this value will be subtracted
from each address in the data file, thereby actually programming everything in
the right spot on the Flash device (starting from Flash address 0x00000000). Now
not only will we program and verify the data, but if we’re using production code
the board will boot and all will be well.
Note: If the data file starts at address 0 and covers the entire Flash device,
it will not be possible to enter any start address besides 0 without generating
an error. Why? The value entered is subtracted from each address obtained from
the data file, so even if a value of "subtract 1" was entered for the start
address, the first location would be -1, which is invalid. Any “add x” values
would result in invalid locations beyond the Flash capacity.
Understanding how to configure address offsets comes with realizing the right
perspective. When using boundary-scan tools such as ScanExpress Runner or
ScanExpress Programmer for in-system-programming, always make sure that the data
file is set up for Flash address space or that the software is configured with
an appropriate address offset to compensate.