EmbeddedRelated.com
Forums

Creating a bootloader segment using IAR compiler.

Started by jkw_ee February 17, 2006
I am writting a bootloader/monitor for a project but am hung up on 
what I think is just some confusion with the compiler. 

I have no problem allocating a segment for the code in the xlinker. 
My approach was to write the bootloader as a function and assign it 
to the memory segment using the #pragma directive. The code is 
written so that the segment is not overwritten when updating the 
flash. 

I envision the processor starting up and calling the bootloader that 
listens to the UART for a period of time to see if there is an 
update. If there is not activity on the UART the bootloader then 
verifies that rest of the program is intact and begins to execue 
otherwise it just waits for an upload on the UART.  

My problem comes from when the processor starts up and the cstartup 
initialization is done. If my boot code is placed in a segment at 
0x4200 for example the code always performs some operations in 
memory space at 0x4000. Even if I change the CSTART segment address 
to match the bootloader there are a couple of branch operations that 
happen between the bootloader segment and the main code segment. 
This would be fine if a complete update was done every time and 
there never was a malfunction. What I am afraid of is the case where 
the code branches that direct the execution to 0x4200 are lost 
because of some error. 

How can I get the startup code thread to be bound together in one 
segment that I can protect? I am sure that I am missing something 
simple. I think that this can be dealt with by modifiing the CSTART 
library file but I would like to avoid that. 

Thanks for any suggestions you may have.
JW






Beginning Microcontrollers with the MSP430

jkw_ee wrote:
> I am writting a bootloader/monitor for a project
but am hung up on 
> what I think is just some confusion with the compiler. 
> 
> I have no problem allocating a segment for the code in the xlinker. 
> My approach was to write the bootloader as a function and assign it 
> to the memory segment using the #pragma directive. The code is 
> written so that the segment is not overwritten when updating the 
> flash. 
> 
> I envision the processor starting up and calling the bootloader that 
> listens to the UART for a period of time to see if there is an 
> update. If there is not activity on the UART the bootloader then 
> verifies that rest of the program is intact and begins to execue 
> otherwise it just waits for an upload on the UART.  
> 
> My problem comes from when the processor starts up and the cstartup 
> initialization is done. If my boot code is placed in a segment at 
> 0x4200 for example the code always performs some operations in 
> memory space at 0x4000. Even if I change the CSTART segment address 
> to match the bootloader there are a couple of branch operations that 
> happen between the bootloader segment and the main code segment. 
> This would be fine if a complete update was done every time and 
> there never was a malfunction. What I am afraid of is the case where 
> the code branches that direct the execution to 0x4200 are lost 
> because of some error. 
> 
> How can I get the startup code thread to be bound together in one 
> segment that I can protect? I am sure that I am missing something 
> simple. I think that this can be dealt with by modifiing the CSTART 
> library file but I would like to avoid that. 
> 
> Thanks for any suggestions you may have.

One way to do this is to see the bootloader as a stand-alone 
application, where all of it's code segments are placed in the memory 
area that should survive a boot. This would require you to have two 
projects, each with its own xlink configuration files. Also, I guess 
that you would have to custom-write the startup-code and divide up the 
responsibilities between the bootloader and the actual application.

Alternative you could try to minimize the use of special subroutines. 
First, avoid things like floating-point operations. Also, in the latest 
version of the compiler (3.40) we introduces a pragma "no_epilogue"
that 
makes sure that the entry and exit code of a function does not use 
subroutines.

     -- Anders Lindgren, IAR Systems

-- 
Disclaimer: Opinions expressed in this posting are strictly my own and
not necessarily those of my employer.

Hi,
if we call your bootloader "system" and the other part
"application", 
where do you get your application from? Normally any MSP430 IDE will 
automatically produce the system, but not the application.

If your application is written in "C" with "main()", then it
would be a 
second IDE project and produce its own startup code. The startup code is 
not reusable between system and application.

You need to keep separate data spaces and interrupt vectors and all 
other resources as well.

Another problem is debugging. If you want to use IAR IDE for debugging 
the interaction between system and application, you need to setup a 
third project that contains everything at the same time.
Regards,
D. Teuchert

jkw_ee wrote:

>I am writting a bootloader/monitor for a project
but am hung up on 
>what I think is just some confusion with the compiler. 
>
>I have no problem allocating a segment for the code in the xlinker. 
>My approach was to write the bootloader as a function and assign it 
>to the memory segment using the #pragma directive. The code is 
>written so that the segment is not overwritten when updating the 
>flash. 
>
>I envision the processor starting up and calling the bootloader that 
>listens to the UART for a period of time to see if there is an 
>update. If there is not activity on the UART the bootloader then 
>verifies that rest of the program is intact and begins to execue 
>otherwise it just waits for an upload on the UART.  
>
>My problem comes from when the processor starts up and the cstartup 
>initialization is done. If my boot code is placed in a segment at 
>0x4200 for example the code always performs some operations in 
>memory space at 0x4000. Even if I change the CSTART segment address 
>to match the bootloader there are a couple of branch operations that 
>happen between the bootloader segment and the main code segment. 
>This would be fine if a complete update was done every time and 
>there never was a malfunction. What I am afraid of is the case where 
>the code branches that direct the execution to 0x4200 are lost 
>because of some error. 
>
>How can I get the startup code thread to be bound together in one 
>segment that I can protect? I am sure that I am missing something 
>simple. I think that this can be dealt with by modifiing the CSTART 
>library file but I would like to avoid that. 
>
>Thanks for any suggestions you may have.
>JW
>
>
>
>
>
>
>
>.
>
> 
>Yahoo! Groups Links
>
>
>
> 
>
>
>
>  
>

> One way to do this is to see the bootloader as a stand-alone 
> application, where all of it's code segments
are placed in the memory 
> area that should survive a boot. This would require you to have two 
> projects, each with its own xlink configuration files. Also, I guess 
> that you would have to custom-write the startup-code and divide up 
the 
> responsibilities between the bootloader and the
actual application.

I designed a bootloader very similar to yours.  The approach that I 
chose was using Anders' recommendation above.  I works very well and 
it's easy to implement once you get your design organized.  A one 
application project with bootloader subfunction seemed like too much 
trouble.

JJS





I understand what you are saying about the problems with debugging 
when the bootloader is not included as part of the main program. 

My first instict was to call the bootloader in the __low_level_init 
file. The routine would only initialze the absolute minimum resources 
required for the bootloader and then poll the UART to avoid any 
complications with the vector table. Once the bootloader did what was 
required it would continue on to let the CSTART call the main() and 
life would be good. As mentioned the problem is the loss of the easy 
ability to debug the entire entity in one project.

I understand how to manipulate two projects and their xlink files so 
that they will not "crash" into one another. How do you control which 
one executes first and how the execution is passed between them? 
Dieters' points are good.

It seems that this is a re-ocurring topic on this forum that everyone 
has a little confusion about. Once I get this figured out I will be 
more than happy to post an example in the files area. I realize there 
are many different ways to implement a bootloader.







Hi!

jkw_ee wrote:
> I understand what you are saying about the problems with debugging 
> when the bootloader is not included as part of the main program. 
> 
> My first instict was to call the bootloader in the __low_level_init 
> file. The routine would only initialze the absolute minimum resources 
> required for the bootloader and then poll the UART to avoid any 
> complications with the vector table. Once the bootloader did what was 
> required it would continue on to let the CSTART call the main() and 
> life would be good. As mentioned the problem is the loss of the easy 
> ability to debug the entire entity in one project.
> 
> I understand how to manipulate two projects and their xlink files so 
> that they will not "crash" into one another. How do you control
which 
> one executes first and how the execution is passed between them? 
> Dieters' points are good.

The one that is executed first is the one that "owns" the reset
vector.

You can simply pass execution between them by specifying, say, an 
absolute address where the loaded image should start.

Likewise, if you need interrupt handlers in the loaded code you need a 
way to handle this. For example, you could have a table located at a 
specific address containing pointers to interrupt routines. The 
bootloader could then contain interrupt handler stubs that redirected 
the calls to the right function.


> It seems that this is a re-ocurring topic on this
forum that everyone 
> has a little confusion about. Once I get this figured out I will be 
> more than happy to post an example in the files area. I realize there 
> are many different ways to implement a bootloader.

That would be really great!

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