EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Force the reset vector to a specific address

Started by Robert April 6, 2010
Hello. I saw this question asked a little while back but I didn't see anyone answer this specific question. Here's the situation. We have a custom bootloader and an application. In IAR, both builds set the reset vector to the start of that build. The location in memory is changed specified in the linker file.

The interrupt vectors are used by the application only, except for that pesky reset vector. Our current process is to program the bootloader first, and then the app, so the reset vector for the app is valid. In reality, our "bootloader" is just a reprogrammer. It's not called at boot-up.

We want to change this so the bootloader is called at boot-up. That way, if the app is invalid, the bootloader will wait for data on the serial port to reprogram the app. So, I want the application to set the reset vector to a specific address for where the bootloader is located, and to "ignore" its own reset address.

I could write some sort of command line tool that does this, and call it as a post-build action for the application, but this seems too difficult. Can I "force" the linker set a value in flash, and not have it overwritten by the reset vector? Any thoughts?

Beginning Microcontrollers with the MSP430

The reset vectors for all interrupts are fixed in the last 32 bytes or
so of flash memory. You can do nothing about them. However you can
change the address at those vectors, which I assume is what you want. ie
your compiler is forcing the address in the RESET VECTOr at 0xFFFE to
the address of its own start up routine. To change that you will need to
re-write the IAR start-up routine. I know from posst here it can be
done. I use assembler, so i don't have to messa round with those issues.

If you are asking if you can relocate the vector from 0xFFFE to
somewhere else then the answer is no.

In my own self programming systems i have the default RESET VECTOR, ie
the program entry point as the self loader. this performs a quick
integrity check before deciding whether to run user code or loader code.
It sounds like you are trying to achieve the same thing.

Al

Robert wrote:
> Hello. I saw this question asked a little while back but I didn't see anyone answer this specific question. Here's the situation. We have a custom bootloader and an application. In IAR, both builds set the reset vector to the start of that build. The location in memory is changed specified in the linker file.
>
> The interrupt vectors are used by the application only, except for that pesky reset vector. Our current process is to program the bootloader first, and then the app, so the reset vector for the app is valid. In reality, our "bootloader" is just a reprogrammer. It's not called at boot-up.
>
> We want to change this so the bootloader is called at boot-up. That way, if the app is invalid, the bootloader will wait for data on the serial port to reprogram the app. So, I want the application to set the reset vector to a specific address for where the bootloader is located, and to "ignore" its own reset address.
>
> I could write some sort of command line tool that does this, and call it as a post-build action for the application, but this seems too difficult. Can I "force" the linker set a value in flash, and not have it overwritten by the reset vector? Any thoughts?
>
>
For F1xx, F2xx, F3xx, or F4xx, you have only one "hardware" RESET vector and it is always at FFFE-FFFF. (For F5xx or F6xx, you can have two different "hardware" RESET vectors.)

The Linker relies on the Linker Command to tell it where the RESET vector is. Thus you can fool it by telling it a different address.

In the case of IAR, you can find Linker Command in files with names like: lnk430fxxx.xlc which specifies: "-Z(CODE)RESETFE-FFFF".
Just replace FFFE-FFFF with whatever you want and the Linker will place the RESET vector at where you said. But this does not change the "hardware" RESET vector(s).

--- In m..., "Robert" wrote:
>
> Hello. I saw this question asked a little while back but I didn't see anyone answer this specific question. Here's the situation. We have a custom bootloader and an application. In IAR, both builds set the reset vector to the start of that build. The location in memory is changed specified in the linker file.
>
> The interrupt vectors are used by the application only, except for that pesky reset vector. Our current process is to program the bootloader first, and then the app, so the reset vector for the app is valid. In reality, our "bootloader" is just a reprogrammer. It's not called at boot-up.
>
> We want to change this so the bootloader is called at boot-up. That way, if the app is invalid, the bootloader will wait for data on the serial port to reprogram the app. So, I want the application to set the reset vector to a specific address for where the bootloader is located, and to "ignore" its own reset address.
>
> I could write some sort of command line tool that does this, and call it as a post-build action for the application, but this seems too difficult. Can I "force" the linker set a value in flash, and not have it overwritten by the reset vector? Any thoughts?
>

We have a similar issue which was solved in a somewhat convoluted, but ultimately affective, way.

Build the bootloader and application in such a way that they will never overlap (except those pesky interrupt vectors).
Erase all segments and program the bootloader first.
Generate an image of your application using the "msp430-txt" formant (in IAR). This makes a ".txt" file. Just delete the last two bytes of the file before the "q". These are the reset vector. It's clear when you look at it. Then program the txt file "on top of" the bootloader.

If you need to debug, you can load the debugger using the "attach to running target" option. This prevents the program from being loaded, but assumes that the compiled code matches what's in your device. (Note that you can debug the app or the bootloader depending on which project you load in you IDE.)

Alternatively, you can synthesize one big txt file includes the bootloader (and its reset vector) and the application. We do this as well for our "production" images. There's probably a way to automate building this image with some simple text processing.

Good luck!
Stuart
--- In m..., "Robert" wrote:
>
> Hello. I saw this question asked a little while back but I didn't see anyone answer this specific question. Here's the situation. We have a custom bootloader and an application. In IAR, both builds set the reset vector to the start of that build. The location in memory is changed specified in the linker file.
>
> The interrupt vectors are used by the application only, except for that pesky reset vector. Our current process is to program the bootloader first, and then the app, so the reset vector for the app is valid. In reality, our "bootloader" is just a reprogrammer. It's not called at boot-up.
>
> We want to change this so the bootloader is called at boot-up. That way, if the app is invalid, the bootloader will wait for data on the serial port to reprogram the app. So, I want the application to set the reset vector to a specific address for where the bootloader is located, and to "ignore" its own reset address.
>
> I could write some sort of command line tool that does this, and call it as a post-build action for the application, but this seems too difficult. Can I "force" the linker set a value in flash, and not have it overwritten by the reset vector? Any thoughts?
>

For F1xx, F2xx, or F4xx, Stuart_Rubin's method is simple and workable. For F5xx or F6xx there is a much better way to do it. The BSL could have its own RESET vector and its own INTERRUPT vectors. The entire MAIN FLASH can be erased and rewritten the "normal" way.

--- In m..., "Stuart_Rubin" wrote:
>
> We have a similar issue which was solved in a somewhat convoluted, but ultimately affective, way.
>
> Build the bootloader and application in such a way that they will never overlap (except those pesky interrupt vectors).
> Erase all segments and program the bootloader first.
> Generate an image of your application using the "msp430-txt" formant (in IAR). This makes a ".txt" file. Just delete the last two bytes of the file before the "q". These are the reset vector. It's clear when you look at it. Then program the txt file "on top of" the bootloader.
>
> If you need to debug, you can load the debugger using the "attach to running target" option. This prevents the program from being loaded, but assumes that the compiled code matches what's in your device. (Note that you can debug the app or the bootloader depending on which project you load in you IDE.)
>
> Alternatively, you can synthesize one big txt file includes the bootloader (and its reset vector) and the application. We do this as well for our "production" images. There's probably a way to automate building this image with some simple text processing.
>
> Good luck!
> Stuart
> --- In m..., "Robert" wrote:
> >
> > Hello. I saw this question asked a little while back but I didn't see anyone answer this specific question. Here's the situation. We have a custom bootloader and an application. In IAR, both builds set the reset vector to the start of that build. The location in memory is changed specified in the linker file.
> >
> > The interrupt vectors are used by the application only, except for that pesky reset vector. Our current process is to program the bootloader first, and then the app, so the reset vector for the app is valid. In reality, our "bootloader" is just a reprogrammer. It's not called at boot-up.
> >
> > We want to change this so the bootloader is called at boot-up. That way, if the app is invalid, the bootloader will wait for data on the serial port to reprogram the app. So, I want the application to set the reset vector to a specific address for where the bootloader is located, and to "ignore" its own reset address.
> >
> > I could write some sort of command line tool that does this, and call it as a post-build action for the application, but this seems too difficult. Can I "force" the linker set a value in flash, and not have it overwritten by the reset vector? Any thoughts?
>

I would do it in this way:

//Flash a const to 0xFFFE-0xFFFF
static const uint16 entry_point @ 0xFFFE = ENTRY_POINT_ADDR

and custom the linker command file
-Z(CODE)INTVEC7E-FFFE (not override the reset vector)
-Z(CODE)RESETC-F7FD (/*someother place*/)

--- In m..., "Robert" wrote:
>
> Hello. I saw this question asked a little while back but I didn't see anyone answer this specific question. Here's the situation. We have a custom bootloader and an application. In IAR, both builds set the reset vector to the start of that build. The location in memory is changed specified in the linker file.
>
> The interrupt vectors are used by the application only, except for that pesky reset vector. Our current process is to program the bootloader first, and then the app, so the reset vector for the app is valid. In reality, our "bootloader" is just a reprogrammer. It's not called at boot-up.
>
> We want to change this so the bootloader is called at boot-up. That way, if the app is invalid, the bootloader will wait for data on the serial port to reprogram the app. So, I want the application to set the reset vector to a specific address for where the bootloader is located, and to "ignore" its own reset address.
>
> I could write some sort of command line tool that does this, and call it as a post-build action for the application, but this seems too difficult. Can I "force" the linker set a value in flash, and not have it overwritten by the reset vector? Any thoughts?
>

On 2010-04-08 01:14, josephleeinus wrote:
> I would do it in this way:
>
> //Flash a const to 0xFFFE-0xFFFF
> static const uint16 entry_point @ 0xFFFE = ENTRY_POINT_ADDR
>
> and custom the linker command file
> -Z(CODE)INTVEC7E-FFFE (not override the reset vector)
> -Z(CODE)RESETC-F7FD (/*someother place*/)

There is even a simpler way.

The INTVEC segment is designed to overlap RESET on purpose. This allows
an application to define a normal __interrupt function using the reset
vector, as in:

#pragma vector=RESET_VECTOR
__interrupt my_reset_function(void)
{
}

Of course, you still have to ensure that the reset vector (defined in
cstartup) either is suppressed, alternatively use the trick of placing
the RESET segment somewhere out of the way.

-- Anders Lindgren, IAR Systems
--
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.

Anders,

I think Jose's intention is to make F7FC-F7FD point to cstartup while leaving FFFE-FFFF un-touched.

That is not what your simpler way did.

Lichen

--- In m..., Anders Lindgren wrote:
>
> On 2010-04-08 01:14, josephleeinus wrote:
> > I would do it in this way:
> >
> > //Flash a const to 0xFFFE-0xFFFF
> > static const uint16 entry_point @ 0xFFFE = ENTRY_POINT_ADDR
> >
> > and custom the linker command file
> > -Z(CODE)INTVEC7E-FFFE (not override the reset vector)
> > -Z(CODE)RESETC-F7FD (/*someother place*/)
>
> There is even a simpler way.
>
> The INTVEC segment is designed to overlap RESET on purpose. This allows
> an application to define a normal __interrupt function using the reset
> vector, as in:
>
> #pragma vector=RESET_VECTOR
> __interrupt my_reset_function(void)
> {
> }
>
> Of course, you still have to ensure that the reset vector (defined in
> cstartup) either is suppressed, alternatively use the trick of placing
> the RESET segment somewhere out of the way.
>
> -- Anders Lindgren, IAR Systems
> --
> Disclaimer: Opinions expressed in this posting are strictly my own and
> not necessarily those of my employer.
>

On 2010-04-08 14:05, old_cow_yellow wrote:
> I think Jose's intention is to make F7FC-F7FD point to cstartup while
> leaving FFFE-FFFF un-touched.
>
> That is not what your simpler way did.

Hi!

Oh, I was trying to improve on the line:

static const uint16 entry_point @ 0xFFFE = ENTRY_POINT_ADDR

The intention of this is to provide an alternative RESET vector. I
pointed out that you can use the IAR tools to generate the interrupt
vector for you, by defining an interrupt function on the reset vector.

-- Anders Lindgren, IAR Systems
--
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.

Interesting. Just to recap, I'm trying to put two separate builds in the same memory space. I want the application to use the reset vector, and I want the bootloader to not use the reset vector, since it will get called by the application.

With this method, I can redefine the reset vector address for the bootloader to be someplace in the bootloader flash area, so that it won't mess with the actual reset vector. Of course, it won't execute until the application calls it, but that's how it's designed.

Thanks.

--- In m..., "josephleeinus" wrote:
> I would do it in this way:
>
> //Flash a const to 0xFFFE-0xFFFF
> static const uint16 entry_point @ 0xFFFE = ENTRY_POINT_ADDR
>
> and custom the linker command file
> -Z(CODE)INTVEC7E-FFFE (not override the reset vector)
> -Z(CODE)RESETC-F7FD (/*someother place*/)
>
> --- In m..., "Robert" wrote:
> >
> > Hello. I saw this question asked a little while back but I didn't see anyone answer this specific question. Here's the situation. We have a custom bootloader and an application. In IAR, both builds set the reset vector to the start of that build. The location in memory is changed specified in the linker file.
> >
> > The interrupt vectors are used by the application only, except for that pesky reset vector. Our current process is to program the bootloader first, and then the app, so the reset vector for the app is valid. In reality, our "bootloader" is just a reprogrammer. It's not called at boot-up.
> >
> > We want to change this so the bootloader is called at boot-up. That way, if the app is invalid, the bootloader will wait for data on the serial port to reprogram the app. So, I want the application to set the reset vector to a specific address for where the bootloader is located, and to "ignore" its own reset address.
> >
> > I could write some sort of command line tool that does this, and call it as a post-build action for the application, but this seems too difficult. Can I "force" the linker set a value in flash, and not have it overwritten by the reset vector? Any thoughts?
>


The 2024 Embedded Online Conference