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
Creating a bootloader segment using IAR compiler.
Started by ●February 17, 2006
Reply by ●February 17, 20062006-02-17
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.
Reply by ●February 17, 20062006-02-17
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
>
>
>
>
>
>
>
>
>
Reply by ●February 17, 20062006-02-17
> 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
Reply by ●February 17, 20062006-02-17
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.
Reply by ●February 20, 20062006-02-20
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.