• AVR Freaks

Hot!Bootloader: Program in flash memory does not start at address 0x00

Author
erding
New Member
  • Total Posts : 15
  • Reward points : 0
  • Joined: 2019/05/29 00:25:37
  • Location: 0
  • Status: offline
2021/03/03 08:26:27 (permalink)
0

Bootloader: Program in flash memory does not start at address 0x00

Hello,

I am using MPLAB X v5.35 and XC8 v2.10 with C99. My controller is a PIC18F25K20.

I am building a bootloader and came across the issue, that the generated code does not start at address 0x00, but at address 0x600, see the following .hex file usage map of a minimal example:

00000000: 1111----1111------------11111111--------------------------------
00000600: 11111111111111111111111-1111111111111111111111111111111111111111 Program starts at 0x600
00000640: 1111111111111111111111111111------------------------------------
00200000: 11111111-------------------------------------------------------- LocID
00300000: 11111111111111-------------------------------------------------- Config
 


I do not have a code-offset activated. When checking my other projects I saw, that for the larger ones that use ~90% flash, the program starts at 0x00. A smaller projekt at ~10% flash usage has a bit of code after 0x00, then nothing and then resumed at 0x600. The larger ones do not have a gap around 0x600.

Then I generated a bootloader project with MCC et voilà, the code is about 5% and starts at 0x00. That is what I also need. If anyone wants to reproduce: Start a new project, open MCC, select the bootloader generator, generate the minimal amount of necessary modules and generate, then compile. Works straight away. I did not alter any default values.
I based my own bootloader on the MCC bootloader, so a lot of things are actually the same.

In order to eliminate the project config from this problem, I created a completely fresh project and altered nothing on the config. I copied my code over, compiled, but the address starts at 0x600 again. Then I deleted my code and copied the generated code over, the address starts again at 0x00. So it is not a problem in the project config. It should be something in the source code itself.

I also use the default config bytes at address 0x00300000, meaning that I deleted the corresponding header file, to eliminate this from the problem.

Then I noticed the following: If I comment out this part in the generated bootloader, then the address does not start at 0x00 anymore, but at the very end of the flash memory.

 
asm ("psect intcode,global,reloc=2,class=CODE,delta=1");
asm ("GOTO " str(NEW_INTERRUPT_VECTOR_HIGH));
asm ("psect intcodelo,global,reloc=2,class=CODE,delta=1");
asm ("GOTO " str(NEW_INTERRUPT_VECTOR_LOW));
 


However, this code is identical in my project and the generated one. Changing the address of the new vectors does not change anything.

I am clueless on how the compiler/linker decides where to place the program in the flash memory.

What do I have to do to make sure, that the program starts at address 0x00?

If more information is needed, please ask. Thanks a lot in advance and best regards.
 
 
Update:
I looked at the listing file and saw the following:

...
 95                              psect   smallconst
 96  000600                     __psmallconst:
 97                              opt callstack 0
 98  000600  00                  db  0
 99  000601                     STR_1:
100  000601  0A                  db  10
...

 
psmallconst has something to do with string literals. I removed my only source of string literals (debug) from the project, then my program starts at 0x00. But attention: simply not including is not enough! I have no idea why, but even if the files are completely not included, string literals are generated in the listing file. You need to exclude those files from the project.
I added a random string to the generated project and then also the program does not start at 0x00 anymore, but at 0x600.
I am still not sure how to handle this properly.
 
post edited by erding - 2021/03/03 09:13:59
#1

4 Replies Related Threads

    Aussie Susan
    Super Member
    • Total Posts : 3857
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: Bootloader: Program in flash memory does not start at address 0x00 2021/03/04 18:48:19 (permalink)
    +2 (2)
    Have a look at Section 5 of the data sheet for that MCU where it shows the layout of the FLASH memory.
    Basically the bottom addresses contain the reset vector and the ISR vectors. Therefore while the HEX file may have values being loaded in to the FLASH memory starting at 0x0000, that is not code. The reset vector typically points to the start of the actual code - as you say you are using C then that will be the start of the C runtime that will eventually jump to your 'main()' function.
    How the compiler (or more accurately the linker) lays things out in memory can be seen in the map file.
    As you are starting to find out, using a bootloader adds a whole level of complexity to things. I always recommend that you leave adding a bootloader into a application until everything else is completely sorted out. I see you are  a new member here - I have no idea of your overall embedded experience - but I would advise you to not play with bootloaders until you really know what is going on.
    Susan
    #2
    trossin
    Super Member
    • Total Posts : 72
    • Reward points : 0
    • Joined: 2006/06/02 11:31:50
    • Location: 0
    • Status: offline
    Re: Bootloader: Program in flash memory does not start at address 0x00 2021/03/04 20:44:42 (permalink)
    0
    Yes. Bootloaders are a bit of a pain to implement due to memory mapping and startup routines. You can look at my assembly language boot loader here:

    https://www.sites.google....n/home/electronics/pic

    Scroll down a bit and click on the “Serial port PIC Bootloader”. I support some 16F, 18F and dsPIC processors. I have PIC and Visual Studio source code that you can look at.

    The big secret is that I found is that I relocate the reset address down into my bootloader and replace it with the address of my code. I also have to reserve the end of flash memory for the bootloader code. I do this in the linker config for each application that I write that uses the bootloader.
    #3
    trossin
    Super Member
    • Total Posts : 72
    • Reward points : 0
    • Joined: 2006/06/02 11:31:50
    • Location: 0
    • Status: offline
    Re: Bootloader: Program in flash memory does not start at address 0x00 2021/03/08 10:42:10 (permalink)
    0
    Another thing I noticed about XC8 when I switched over from SourceBoost is that it places the program starting at location 4 if you have an interrupt routine but will pack at to the end of memory if you do not. For example, if you have 2000 words of flash and your program takes up 500 words, it will place it between 1500 and 1999 if you don’t use interrupts. If you do, it will place it between 4 and 503. Location 0 and 1 will have a go to 4 or 1500.

    Not nice.

    That is why I put my bootloader at the end of flash and tell the linker not to use that memory
    #4
    erding
    New Member
    • Total Posts : 15
    • Reward points : 0
    • Joined: 2019/05/29 00:25:37
    • Location: 0
    • Status: offline
    Re: Bootloader: Program in flash memory does not start at address 0x00 2021/03/18 00:53:18 (permalink)
    0
    Hello!
    Sorry for my late reply, I am still getting 503 http errors on the forum when using my default browser.
     
    Thanks for your replies!
     
    I figured out, why my program did not start at 0x00. I saw in the .lst file, that a psect called "smallconst", was used. According to the compiler manual, if any string literals or consts are used, it places those above the highest RAM address in the ROM. There are a few more details. I use string literals for debugging and that's why my code did not start at address zero. When I removed my string literals, my code started at zero. I do not used interrupts in the bootloader, so there are also no gaps in the code thereafter.
     
    @Susan: I have done some work with the PIC, I am hopefully able to get it right :) I know that the actual code does not start at 0x00, but the reset vectors. Please see my answer to trossin below. Thank you for your advise.
    @trossin: Sadly I am bad at reading assembly, it usually takes me quite a while to decipher the meaning. My code I want to flash is around 25kB. I started this bootloader project using the MCC generated bootloader and went from there. It puts the reset vectors further back in the flash, e.g. 0x1000. Then I create a code offset of 0x1000 in my actual project. This worked immediately, once I figured out the other pitfalls (e.g. enabling flash write in the config ._.). Maybe this approach might be interesting for you, too.
     
    Here is the code for the reset and interrupt vector remapping, which is a 1:1 copy of the MCC genereated bootloader:
    #define NEW_RESET_VECTOR          0x1000
    #define NEW_INTERRUPT_VECTOR_HIGH 0x1008
    #define NEW_INTERRUPT_VECTOR_LOW  0x1018
     
    // This code is not in any function.
    //
    asm("psect intcode,global,reloc=2,class=CODE,delta=1");
    asm("goto " str(NEW_INTERRUPT_VECTOR_HIGH));
    asm("psect intcodelo,global,reloc=2,class=CODE,delta=1");
    asm("goto " str(NEW_INTERRUPT_VECTOR_LOW));

    // This part is called when the bootloader is done.
    //
    STKPTR = 0x00;
    asm("goto " str(NEW_RESET_VECTOR));

     
    Best regards!
    post edited by erding - 2021/03/18 00:56:22
    #5
    Jump to:
    © 2021 APG vNext Commercial Version 4.5