EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Dual program banks in LPC

Started by andersryl December 14, 2006
Hi,

Background:
uC - LPC2214
compiler - arm-elf-gcc
debugger - arm-elf-gdb / Amontec JTAG interface

I had an idea when starting my current LPC-project to divide the flash
into two program banks (sector 1-8 and sector 9-16 respectively). I
also wanted to be able to compile a general binary file that would
work in any of the banks.

This (if I can get it to work) would enable new software to be
downloaded to the inactive program bank (1) while a program is running
from the other, active, bank (0). Then a switch between program banks
can be made and the "new" software will start executing from bank (1).

The down-time for reprogramming would be minimal.

I think I have the start-up and interrupt vector handling under
control but after looking at the compiled C-code a little more
thoroughly I start to doubt that it is possible.

When looking at the dump-file it seems that function calls (in C) are
compiled into "BL" instructions that branches to absolute addresses.
Is this so?
This would mean that I need two different binaries linked for specific
banks. But otherwise it should work, right? Or no???

If no, Is it possible to tell the linker to use PC-relative branches
instead of absolute addressing?
Are there any general techniques for achieving hot-swappable
programs?

Thanks,
Anders

An Engineer's Guide to the LPC2100 Series

Hi,

If you write and compile your code in a relocatable form you can run
it where you like, but there are problems:-

You do not say if you are using Flash internaly, externaly or both.
I assume you mean internal flash, but the same is true for both.

Your first problem is interrupt vectors, these can only exist in one
of three places:
1: In internal RAM at addres 0
2: In internal Flash (64 bytes of which is mapped to address 0)
3: On the external bus (if you have one) at the bottom of the the
region mapped to CS0 (0x80000000), again 64 bytes of which are re-
mapped to address 0.

Secondly, if you use the IAP to program the internal flash, then the
program that is currently running can not be running from flash, you
must copy a loader into RAM, jump to it, program the flash via IAP
and return to it, then return to running from flash when the
programming is complete.

The same is true for external flash, the device you are programming
must not be accessed my code during the programming. So you would
need to run a program from RAM (internal or external) or have more
than one external flash device at different addresses.

Fourthly, if you do any reprogramming, the programming routing has
to manage if anything goes wrong during the programming cycle.

Lastly, the device can only boot from internal ROM or external CS0,
this means that program at these locations must always be intact or
you could end up with a lot of service returns. You may have to
supply some mechanism to select the boot ROM using the external pins
that survives boot and power cycles.

Regards.
jason.

--- In l..., "andersryl" wrote:
>
> Hi,
>
> Background:
> uC - LPC2214
> compiler - arm-elf-gcc
> debugger - arm-elf-gdb / Amontec JTAG interface
>
> I had an idea when starting my current LPC-project to divide the
flash
> into two program banks (sector 1-8 and sector 9-16 respectively). I
> also wanted to be able to compile a general binary file that would
> work in any of the banks.
>
> This (if I can get it to work) would enable new software to be
> downloaded to the inactive program bank (1) while a program is
running
> from the other, active, bank (0). Then a switch between program
banks
> can be made and the "new" software will start executing from bank
(1).
>
> The down-time for reprogramming would be minimal.
>
> I think I have the start-up and interrupt vector handling under
> control but after looking at the compiled C-code a little more
> thoroughly I start to doubt that it is possible.
>
> When looking at the dump-file it seems that function calls (in C)
are
> compiled into "BL" instructions that branches to absolute
addresses.
> Is this so?
> This would mean that I need two different binaries linked for
specific
> banks. But otherwise it should work, right? Or no???
>
> If no, Is it possible to tell the linker to use PC-relative
branches
> instead of absolute addressing?
> Are there any general techniques for achieving hot-swappable
> programs?
>
> Thanks,
> Anders
>
Hello andersryl;
My client currently is shipping a number of products that use the
LPC2214, and does exactly what you mention. Some things to consider:
1. All interrupt vectors in internal RAM, (code running from internal
RAM)
2. Startup code must copy interrupt code from FLASH to internal RAM!
3. We use Keil. All our ISR's MUST use the following type of
declaration: void my_interrupt_service_isr (void) __irq __ram ( <--
note the usage of the __irq and __ram keywords! )
4. Using IAP to program the FLASH is ok because the IAP runs from an
area that does not shutdown during FLASH programming
5. We segment our code such that the boot loader, (network aware for
downloads), starts at 0x00000000, and ends at 0x0000FFFF
6. We segment our code such that the main application starts at
0x00010000 and ends at 0x0003DFFF, (remember, Phlips FLASH boot block
starts at 0x0003E000)

--- of course, you must use RAM and relocation directives that are
specific to your development environment ---

So... what you are asking for is pretty doable. My client is
currently shipping 100's of units using this kind of technology, and
also supports remote field upgrades using the LPC2214. This technique
can also be used if you desire to use an external FLASH device hooked
up to the LPC2214.

Hope this helps somewhat;
Ken Wada
--- In l..., "andersryl" wrote:
>
> Hi,
>
> Background:
> uC - LPC2214
> compiler - arm-elf-gcc
> debugger - arm-elf-gdb / Amontec JTAG interface
>
> I had an idea when starting my current LPC-project to divide the
flash
> into two program banks (sector 1-8 and sector 9-16 respectively). I
> also wanted to be able to compile a general binary file that would
> work in any of the banks.
>
> This (if I can get it to work) would enable new software to be
> downloaded to the inactive program bank (1) while a program is
running
> from the other, active, bank (0). Then a switch between program
banks
> can be made and the "new" software will start executing from bank
(1).
>
> The down-time for reprogramming would be minimal.
>
> I think I have the start-up and interrupt vector handling under
> control but after looking at the compiled C-code a little more
> thoroughly I start to doubt that it is possible.
>
> When looking at the dump-file it seems that function calls (in C)
are
> compiled into "BL" instructions that branches to absolute addresses.
> Is this so?
> This would mean that I need two different binaries linked for
specific
> banks. But otherwise it should work, right? Or no???
>
> If no, Is it possible to tell the linker to use PC-relative branches
> instead of absolute addressing?
> Are there any general techniques for achieving hot-swappable
> programs?
>
> Thanks,
> Anders
>
Thank you for your replies!

Always nice to hear that someone has done something similar before
you. ;)

There is however one thing that differs from your software, Ken. My
idea was to have two "main"-program banks in the internal flash (with
the bootloading mechanism integrated into the main software. The first
program bank from 0x0 to 0x1FFFF and the second from 0x20000 to 0x3DFFF.

While the unit is running, using the code in the first program bank,
the second one could be programmed (with IAP) with a new (better!?)
version. When appropriate, a switch between the banks is made and the
next time the software needs to be updated bank one is used for
software downloading. The problem here is that the code generated from
gcc uses absolute addressing for function calls. This means that a
program running from bank two making a function call to a function
residing at e.g. PC + 0x26C0 jumps to PC + 0x26C0 - 0x20000 (bank two
offset) because of absolute addressing.

I see that you are using Keil and my question should probably be
posted in the GNU-ARM group because it seems it is related to what the
arm-elf linker is able to do with absolute versus PC-relative addressing.

/Anders

--- In l..., "Ken Wada" wrote:
>
> Hello andersryl;
> My client currently is shipping a number of products that use the
> LPC2214, and does exactly what you mention. Some things to consider:
> 1. All interrupt vectors in internal RAM, (code running from internal
> RAM)
> 2. Startup code must copy interrupt code from FLASH to internal RAM!
> 3. We use Keil. All our ISR's MUST use the following type of
> declaration: void my_interrupt_service_isr (void) __irq __ram ( <--
> note the usage of the __irq and __ram keywords! )
> 4. Using IAP to program the FLASH is ok because the IAP runs from an
> area that does not shutdown during FLASH programming
> 5. We segment our code such that the boot loader, (network aware for
> downloads), starts at 0x00000000, and ends at 0x0000FFFF
> 6. We segment our code such that the main application starts at
> 0x00010000 and ends at 0x0003DFFF, (remember, Phlips FLASH boot block
> starts at 0x0003E000)
>
> --- of course, you must use RAM and relocation directives that are
> specific to your development environment ---
>
> So... what you are asking for is pretty doable. My client is
> currently shipping 100's of units using this kind of technology, and
> also supports remote field upgrades using the LPC2214. This technique
> can also be used if you desire to use an external FLASH device hooked
> up to the LPC2214.
>
> Hope this helps somewhat;
> Ken Wada
--- In l..., "andersryl" wrote:
>
> Thank you for your replies!
>
> Always nice to hear that someone has done something similar before
> you. ;)
>
> There is however one thing that differs from your software, Ken. My
> idea was to have two "main"-program banks in the internal flash
(with
> the bootloading mechanism integrated into the main software. The
first
> program bank from 0x0 to 0x1FFFF and the second from 0x20000 to
0x3DFFF.
>
> While the unit is running, using the code in the first program bank,
> the second one could be programmed (with IAP) with a new (better!?)
> version. When appropriate, a switch between the banks is made and
the
> next time the software needs to be updated bank one is used for
> software downloading. The problem here is that the code generated
from
> gcc uses absolute addressing for function calls. This means that a
> program running from bank two making a function call to a function
> residing at e.g. PC + 0x26C0 jumps to PC + 0x26C0 - 0x20000 (bank
two
> offset) because of absolute addressing.
>
> I see that you are using Keil and my question should probably be
> posted in the GNU-ARM group because it seems it is related to what
the
> arm-elf linker is able to do with absolute versus PC-relative
addressing.
>
> /Anders
>

Anders,

To avoid having to use position independent code, you could always
build two images and get the target system to select which one it
wants when it is being upgraded.

The key thing with in-service upgrade systems is to make them robust
from various failures that can happen (e.g. corruption of program
image as it's downloaded, system resetting during the download
process etc.).

One fairly standard way of handling this is to have a very small boot
loader that is never replaced (at least when in service). This checks
(a) which one of the two images it should run, using some non-
volatile status and (b) checks the integrity of that image (you
should really use some CRC-type system rather than a simple checksum)
before jumping to it.

The upgrade process is simple enough: download the image and store it
as the backup image, change the "active image" status and reboot.

An alternative is to just have the program built for one location,
and reserve an area of the Flash for holding the backup copy. The
upgrade system is then:

- download the program to the backup storage area of flash
- store the CRC value for the data with the backup image
- set a flag in non-volatile storage saying a backup should be loaded
on next reset
- reset
- boot loader (which never changes) runs from reset and sees it needs
to load backup image
- boot loader checks the backup image (against the CRC) and if it's
valid starts programming the flash using ISP
- boot loader when it's finished checks the CRC against the freshly
programmed image in memory, and if it's OK changes the status back to
normal boot
- reset again
- system runs as normal

Note that in this case the backup image can be stored elsewhere (e.g.
an external EEPROM/serial flash etc.).

There's plenty of variations on this, the key things are having a
small loader that never changes and some reliable mechanism for
detecting a valid program.

Note: the LPC2xxx makes having this kind of set up fairly easy in
relation to interrupts, as the basic interrupt code (a few lines of
assembler) can be kept in the boot loader. The "real" interrupt
handlers are all set at run time, by configuring the VIC.

Hope this helps.

Brendan
Hello Anders;
I concur with Brendan Murphy. He says you need to write a small
bootloader. From what I can see, this is the most practical approach.
The methods that Brendan describes are both eminently workable and
will work.

Ken Wada

--- In l..., "andersryl" wrote:
>
> Thank you for your replies!
>
> Always nice to hear that someone has done something similar before
> you. ;)
>
> There is however one thing that differs from your software, Ken. My
> idea was to have two "main"-program banks in the internal flash
(with
> the bootloading mechanism integrated into the main software. The
first
> program bank from 0x0 to 0x1FFFF and the second from 0x20000 to
0x3DFFF.
>
> While the unit is running, using the code in the first program bank,
> the second one could be programmed (with IAP) with a new (better!?)
> version. When appropriate, a switch between the banks is made and
the
> next time the software needs to be updated bank one is used for
> software downloading. The problem here is that the code generated
from
> gcc uses absolute addressing for function calls. This means that a
> program running from bank two making a function call to a function
> residing at e.g. PC + 0x26C0 jumps to PC + 0x26C0 - 0x20000 (bank
two
> offset) because of absolute addressing.
>
> I see that you are using Keil and my question should probably be
> posted in the GNU-ARM group because it seems it is related to what
the
> arm-elf linker is able to do with absolute versus PC-relative
addressing.
>
> /Anders
>
> --- In l..., "Ken Wada" wrote:
> >
> > Hello andersryl;
> > My client currently is shipping a number of products that use the
> > LPC2214, and does exactly what you mention. Some things to
consider:
> > 1. All interrupt vectors in internal RAM, (code running from
internal
> > RAM)
> > 2. Startup code must copy interrupt code from FLASH to internal
RAM!
> > 3. We use Keil. All our ISR's MUST use the following type of
> > declaration: void my_interrupt_service_isr (void) __irq __ram ( <-
-
> > note the usage of the __irq and __ram keywords! )
> > 4. Using IAP to program the FLASH is ok because the IAP runs from
an
> > area that does not shutdown during FLASH programming
> > 5. We segment our code such that the boot loader, (network aware
for
> > downloads), starts at 0x00000000, and ends at 0x0000FFFF
> > 6. We segment our code such that the main application starts at
> > 0x00010000 and ends at 0x0003DFFF, (remember, Phlips FLASH boot
block
> > starts at 0x0003E000)
> >
> > --- of course, you must use RAM and relocation directives that
are
> > specific to your development environment ---
> >
> > So... what you are asking for is pretty doable. My client is
> > currently shipping 100's of units using this kind of technology,
and
> > also supports remote field upgrades using the LPC2214. This
technique
> > can also be used if you desire to use an external FLASH device
hooked
> > up to the LPC2214.
> >
> > Hope this helps somewhat;
> > Ken Wada
> >
>
Ken,

Just two further minor clarification points:

- the boot loader I was suggesting doesn't replace the built-in one,
but runs after it. I believe it's possible to replace the built-in
loader, though I'd strongly discourage this as you're in the realms
of using undocumented and unsupported features at that stage.

- I haven't actually done this on the LPC2xxx, (I've done similar
systems on several other different MCUs), but can't see why it
shouldn't work very well.

Brendan

--- In l..., "Ken Wada" wrote:
>
> Hello Anders;
> I concur with Brendan Murphy. He says you need to write a small
> bootloader. From what I can see, this is the most practical
approach.
> The methods that Brendan describes are both eminently workable and
> will work.
>
> Ken Wada
>
> --- In l..., "andersryl" wrote:
> >
> > Thank you for your replies!
> >
> > Always nice to hear that someone has done something similar before
> > you. ;)
> >
> > There is however one thing that differs from your software, Ken.
My
> > idea was to have two "main"-program banks in the internal flash
> (with
> > the bootloading mechanism integrated into the main software. The
> first
> > program bank from 0x0 to 0x1FFFF and the second from 0x20000 to
> 0x3DFFF.
> >
> > While the unit is running, using the code in the first program
bank,
> > the second one could be programmed (with IAP) with a new
(better!?)
> > version. When appropriate, a switch between the banks is made and
> the
> > next time the software needs to be updated bank one is used for
> > software downloading. The problem here is that the code generated
> from
> > gcc uses absolute addressing for function calls. This means that a
> > program running from bank two making a function call to a function
> > residing at e.g. PC + 0x26C0 jumps to PC + 0x26C0 - 0x20000 (bank
> two
> > offset) because of absolute addressing.
> >
> > I see that you are using Keil and my question should probably be
> > posted in the GNU-ARM group because it seems it is related to
what
> the
> > arm-elf linker is able to do with absolute versus PC-relative
> addressing.
> >
> > /Anders
> >
> > --- In l..., "Ken Wada" wrote:
> > >
> > > Hello andersryl;
> > > My client currently is shipping a number of products that use
the
> > > LPC2214, and does exactly what you mention. Some things to
> consider:
> > > 1. All interrupt vectors in internal RAM, (code running from
> internal
> > > RAM)
> > > 2. Startup code must copy interrupt code from FLASH to internal
> RAM!
> > > 3. We use Keil. All our ISR's MUST use the following type of
> > > declaration: void my_interrupt_service_isr (void) __irq __ram (
<-
> -
> > > note the usage of the __irq and __ram keywords! )
> > > 4. Using IAP to program the FLASH is ok because the IAP runs
from
> an
> > > area that does not shutdown during FLASH programming
> > > 5. We segment our code such that the boot loader, (network
aware
> for
> > > downloads), starts at 0x00000000, and ends at 0x0000FFFF
> > > 6. We segment our code such that the main application starts at
> > > 0x00010000 and ends at 0x0003DFFF, (remember, Phlips FLASH boot
> block
> > > starts at 0x0003E000)
> > >
> > > --- of course, you must use RAM and relocation directives that
> are
> > > specific to your development environment ---
> > >
> > > So... what you are asking for is pretty doable. My client is
> > > currently shipping 100's of units using this kind of
technology,
> and
> > > also supports remote field upgrades using the LPC2214. This
> technique
> > > can also be used if you desire to use an external FLASH device
> hooked
> > > up to the LPC2214.
> > >
> > > Hope this helps somewhat;
> > > Ken Wada
> > >
> > >
>
Thank you guys!

First of all I realize that dont need two functioning program banks.
It is better, as you suggested Brendan, to use the upper part of the
memory for temporary storage of the next program image before it is
moved to the program memory area. This way absolute vs PC-relative
addressing is no longer a problem since the image will execute in the
memory area it is linked for.

The time taken to move an image from temporary storage area to the
program memory area is probably negligible in my case.

In the scenario above a separate boot loader is a must since a reset
during the move of an image from temporary storage to program memory
must be taken into account. If this happens when you reprogram the
"second" bootloader you are dead. Hence, never reprogram the bootloader.

To avoid accepting and swapping to a faulty image checksums should
definitely be used.

Thanks!
/Anders

--- In l..., "Brendan Murphy"
wrote:
> Ken,
>
> Just two further minor clarification points:
>
> - the boot loader I was suggesting doesn't replace the built-in one,
> but runs after it. I believe it's possible to replace the built-in
> loader, though I'd strongly discourage this as you're in the realms
> of using undocumented and unsupported features at that stage.
>
> - I haven't actually done this on the LPC2xxx, (I've done similar
> systems on several other different MCUs), but can't see why it
> shouldn't work very well.
>
> Brendan
>
> --- In l..., "Ken Wada" wrote:
> >
> > Hello Anders;
> > I concur with Brendan Murphy. He says you need to write a small
> > bootloader. From what I can see, this is the most practical
> approach.
> > The methods that Brendan describes are both eminently workable and
> > will work.
> >
> > Ken Wada
> >
> > --- In l..., "andersryl" wrote:
> > >
> > > Thank you for your replies!
> > >
> > > Always nice to hear that someone has done something similar before
> > > you. ;)
> > >
> > > There is however one thing that differs from your software, Ken.
> My
> > > idea was to have two "main"-program banks in the internal flash
> > (with
> > > the bootloading mechanism integrated into the main software. The
> > first
> > > program bank from 0x0 to 0x1FFFF and the second from 0x20000 to
> > 0x3DFFF.
> > >
> > > While the unit is running, using the code in the first program
> bank,
> > > the second one could be programmed (with IAP) with a new
> (better!?)
> > > version. When appropriate, a switch between the banks is made and
> > the
> > > next time the software needs to be updated bank one is used for
> > > software downloading. The problem here is that the code generated
> > from
> > > gcc uses absolute addressing for function calls. This means that a
> > > program running from bank two making a function call to a function
> > > residing at e.g. PC + 0x26C0 jumps to PC + 0x26C0 - 0x20000 (bank
> > two
> > > offset) because of absolute addressing.
> > >
> > > I see that you are using Keil and my question should probably be
> > > posted in the GNU-ARM group because it seems it is related to
> what
> > the
> > > arm-elf linker is able to do with absolute versus PC-relative
> > addressing.
> > >
> > > /Anders
> > >
> > > --- In l..., "Ken Wada" wrote:
> > > >
> > > > Hello andersryl;
> > > > My client currently is shipping a number of products that use
> the
> > > > LPC2214, and does exactly what you mention. Some things to
> > consider:
> > > > 1. All interrupt vectors in internal RAM, (code running from
> > internal
> > > > RAM)
> > > > 2. Startup code must copy interrupt code from FLASH to internal
> > RAM!
> > > > 3. We use Keil. All our ISR's MUST use the following type of
> > > > declaration: void my_interrupt_service_isr (void) __irq __ram (
> <-
> > -
> > > > note the usage of the __irq and __ram keywords! )
> > > > 4. Using IAP to program the FLASH is ok because the IAP runs
> from
> > an
> > > > area that does not shutdown during FLASH programming
> > > > 5. We segment our code such that the boot loader, (network
> aware
> > for
> > > > downloads), starts at 0x00000000, and ends at 0x0000FFFF
> > > > 6. We segment our code such that the main application starts at
> > > > 0x00010000 and ends at 0x0003DFFF, (remember, Phlips FLASH boot
> > block
> > > > starts at 0x0003E000)
> > > >
> > > > --- of course, you must use RAM and relocation directives that
> > are
> > > > specific to your development environment ---
> > > >
> > > > So... what you are asking for is pretty doable. My client is
> > > > currently shipping 100's of units using this kind of
> technology,
> > and
> > > > also supports remote field upgrades using the LPC2214. This
> > technique
> > > > can also be used if you desire to use an external FLASH device
> > hooked
> > > > up to the LPC2214.
> > > >
> > > > Hope this helps somewhat;
> > > > Ken Wada
> > > >
> > > >
> > >
>
Hello Anders, Brendan;

Again, I concur with Brendan's approach, and warning. It is not a
good idea to attempt to replace the Philips bootloader. You need to
create one that runs 'after' the normal Philips boot. Also, you are
quite right about scanning and checking the application image during
boot. Because this is so critical, we use a 32-bit CRC instead of a
simple checksum.

Pretty much everything Brendan has recommended, has been tried and
does work, and is currently being shipped on 1000's of units.

And yes, both of you are correct. That boot had better be rock solid.
This 'loader' pretty much remains untouched during the lifetime of
the instrument, or widget that you are controlling.

Ken Wada

--- In l..., "andersryl" wrote:
>
> Thank you guys!
>
> First of all I realize that dont need two functioning program
banks.
> It is better, as you suggested Brendan, to use the upper part of the
> memory for temporary storage of the next program image before it is
> moved to the program memory area. This way absolute vs PC-relative
> addressing is no longer a problem since the image will execute in
the
> memory area it is linked for.
>
> The time taken to move an image from temporary storage area to the
> program memory area is probably negligible in my case.
>
> In the scenario above a separate boot loader is a must since a reset
> during the move of an image from temporary storage to program memory
> must be taken into account. If this happens when you reprogram the
> "second" bootloader you are dead. Hence, never reprogram the
bootloader.
>
> To avoid accepting and swapping to a faulty image checksums should
> definitely be used.
>
> Thanks!
> /Anders
>
> --- In l..., "Brendan Murphy"
> wrote:
> >
> >
> > Ken,
> >
> > Just two further minor clarification points:
> >
> > - the boot loader I was suggesting doesn't replace the built-in
one,
> > but runs after it. I believe it's possible to replace the built-
in
> > loader, though I'd strongly discourage this as you're in the
realms
> > of using undocumented and unsupported features at that stage.
> >
> > - I haven't actually done this on the LPC2xxx, (I've done similar
> > systems on several other different MCUs), but can't see why it
> > shouldn't work very well.
> >
> > Brendan
> >
> > --- In l..., "Ken Wada" wrote:
> > >
> > > Hello Anders;
> > > I concur with Brendan Murphy. He says you need to write a small
> > > bootloader. From what I can see, this is the most practical
> > approach.
> > > The methods that Brendan describes are both eminently workable
and
> > > will work.
> > >
> > > Ken Wada
> > >
> > > --- In l..., "andersryl" wrote:
> > > >
> > > > Thank you for your replies!
> > > >
> > > > Always nice to hear that someone has done something similar
before
> > > > you. ;)
> > > >
> > > > There is however one thing that differs from your software,
Ken.
> > My
> > > > idea was to have two "main"-program banks in the internal
flash
> > > (with
> > > > the bootloading mechanism integrated into the main software.
The
> > > first
> > > > program bank from 0x0 to 0x1FFFF and the second from 0x20000
to
> > > 0x3DFFF.
> > > >
> > > > While the unit is running, using the code in the first
program
> > bank,
> > > > the second one could be programmed (with IAP) with a new
> > (better!?)
> > > > version. When appropriate, a switch between the banks is made
and
> > > the
> > > > next time the software needs to be updated bank one is used
for
> > > > software downloading. The problem here is that the code
generated
> > > from
> > > > gcc uses absolute addressing for function calls. This means
that a
> > > > program running from bank two making a function call to a
function
> > > > residing at e.g. PC + 0x26C0 jumps to PC + 0x26C0 - 0x20000
(bank
> > > two
> > > > offset) because of absolute addressing.
> > > >
> > > > I see that you are using Keil and my question should probably
be
> > > > posted in the GNU-ARM group because it seems it is related to
> > what
> > > the
> > > > arm-elf linker is able to do with absolute versus PC-relative
> > > addressing.
> > > >
> > > > /Anders
> > > >
> > > > --- In l..., "Ken Wada" wrote:
> > > > >
> > > > > Hello andersryl;
> > > > > My client currently is shipping a number of products that
use
> > the
> > > > > LPC2214, and does exactly what you mention. Some things to
> > > consider:
> > > > > 1. All interrupt vectors in internal RAM, (code running
from
> > > internal
> > > > > RAM)
> > > > > 2. Startup code must copy interrupt code from FLASH to
internal
> > > RAM!
> > > > > 3. We use Keil. All our ISR's MUST use the following type
of
> > > > > declaration: void my_interrupt_service_isr (void) __irq
__ram (
> > <-
> > > -
> > > > > note the usage of the __irq and __ram keywords! )
> > > > > 4. Using IAP to program the FLASH is ok because the IAP
runs
> > from
> > > an
> > > > > area that does not shutdown during FLASH programming
> > > > > 5. We segment our code such that the boot loader, (network
> > aware
> > > for
> > > > > downloads), starts at 0x00000000, and ends at 0x0000FFFF
> > > > > 6. We segment our code such that the main application
starts at
> > > > > 0x00010000 and ends at 0x0003DFFF, (remember, Phlips FLASH
boot
> > > block
> > > > > starts at 0x0003E000)
> > > > >
> > > > > --- of course, you must use RAM and relocation directives
that
> > > are
> > > > > specific to your development environment ---
> > > > >
> > > > > So... what you are asking for is pretty doable. My client
is
> > > > > currently shipping 100's of units using this kind of
> > technology,
> > > and
> > > > > also supports remote field upgrades using the LPC2214. This
> > > technique
> > > > > can also be used if you desire to use an external FLASH
device
> > > hooked
> > > > > up to the LPC2214.
> > > > >
> > > > > Hope this helps somewhat;
> > > > > Ken Wada
> > > > >
> > > > >
> > > >
> > >
>

The 2024 Embedded Online Conference