This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Custom bootloader & autoinitialzation function

Other Parts Discussed in Thread: MSP430F47166, MSP430F2232

Hi,

I am programming a custom bootloader for my application. From now I have split my memory into two sections, one for the boot and the other one for the user program. After a reset, the bootloader is always executed and decide if the user program need to be upgrade or not. If not the application runs, else the  bootloader erases the entire section user program + IT vectors+Reset  and rewrite the new code (received from UART) into this section.

The problem is that the autoinitialization functions (_c_int00, auto_init, memcpy)  are called before my "main"(in the bootloader) and are in the SECTION flash. Unfortunately these function may be erased after a reset if a problem occurs between erasing and rewriting in the upgrage mode. In this case even my bootloader wouldn't be execute because "main" would not be called  which would leads to a crash of the micro.

My question is, Is there a linker command to put these autoinialization functions in my section bootloader without modified all of them files using :

_Pragma("CODE_SECTION(_c_int00, \".boot\")")

A solution would be to do my one initialization function but it appears a bit tricky to me.

 

MCU: MSP430F47166

SW: CCS v4

Thanks

  • Hi,

       I understand what you are trying to accomplish, but I think the method you are doing so might not be optimal.  Are you trying to have one CCS project that contains both Boot Loader and Application code?

      If so, I would recommend splitting them into two projects.  This way, you can make a custom linker file (.cmd) for both the BSL and for the Application code, and ensure the memory locations do not overlap.  You would only need to make 2 custom linker command files.  This way, both applications also get their own initialization functions.

      The only tricky part would be interrupts.  In this case, the bootloader would get the 'real' interrupt table, whereas the application could have a secondary interrupt table within it's application space.  Interrupts would then breifly go through the bootloader, and be passed on to the application code (if valid) to via the interrupt talbe within the application code space.

      This approach would greatly simplify creating future versions of the application code.

  • If you write your bootloader in the very same project as the application and in C, you could as well put the code into the normal text segment and do not bother about the boot segment at all.

    The trick of the (original) bootloader is that it is called BEFORE the reset vector is called and the C specific stuff is initialized. It has to be a completely self-content project, not relying on the reset vector or anything that is done automatically for the c programmer by compiler/linker.

    I just finished my own flash-based bootloader that works on any device where the boot section isn't writable at all. It requires 1kb of flash at 0xfc00 and adds an additional latency of 4 cycles to any ISR. It is actually not a complete bootloader but rather a boot-updater. It checks the upper flash for a valid image of a new firmware revision, and if found, copied the image to the lower flash (skipping the 1KB it uses itself). after doign so, it erases the image. So if the copy job fails (power loss or whatever) it will try again and again until it succeeded.
    The image itself is stored in upper flash during normal operation from an arbitrary source (e.g. RF-module, SD card, serial/SPI high-speed connection or whatever).
    So the device will always recover to a working condition.

    The trick is that the vector table at 0xff80 points to a jump table at 0xfc00. This jump table does indirect jumps on 0xfb80, where the C compiler will place its vector table. The reset vector at 0xfffe, however, points to the boot-updater at 0xfd00, which in turn will do its job (if required) and jump indirectly over 0xfbfe into the applications reset function. All that's needed is to move the vector section in the linker from 0xff80 to 0xfb80 (shortening the text section accordingly) and, well, write the copy code in assembly language.

    Since while updating the area 0xfc00-0xffff is never erased (no mass erase/bank erase), there's always a working updater and either a working application or a valid image present. There's no critical state (not even for a microsecond) in which an interruption would make the device non-functional.

  • Thank you for your answers, I mixed both ideas and It works from now...but I still have to enable interrupts and to move interrupt vector, not straightforward staff I think ... I don't know if I can do it with the linker

  • Emilien BENHARD said:
    not straightforward staff I think ... I don't know if I can do it with the linker

    No, it really isn't. At least for the GNU linker, which I use with mspgcc, there are quite exhaustive documentations and examples available in the net. I guess the CCE and IAR linker command scripts are similar, but I don't know.

    After all, a proper bootloader isn't straightforward stuff too and not a mainstream application. So the typical development environments aren't set up to support it easily.

  • Can you give me your C code for example? I'm doing the same thing now and stuck for a two weeks.

    thanks in advance

  • Hi Jens-Michael ,

    Jens-Michael Gross said:
    I just finished my own flash-based bootloader that works on any device where the boot section isn't writable at all. It requires 1kb of flash at 0xfc00 and adds an additional latency of 4 cycles to any ISR. It is actually not a complete bootloader but rather a boot-updater. It checks the upper flash for a valid image of a new firmware revision, and if found, copied the image to the lower flash (skipping the 1KB it uses itself). after doign so, it erases the image.

    I was wondering if you could share the code that you wrote as I will be doing the same thing on msp430f2232. I need to update the firmware through RF. Hence, my current goal is to obtain the new FW bytes through RF ( time is not an issue) and store them at a specific part of flash and upon startup, bootloader comes in handy and checks if a valid FW is written and then replace the old FW w the new one. 

  • mil meh said:
    I was wondering if you could share the code that you wrote

    Unfortunately, almost all code I wrote for MSP belongs to my company, so I cannot share it. Par tof it is in inline assembly anyway, written for mspgcc, so it won't compile under IAR or CCS and wouldn't be easy to port. (MSPGCC inline assembly contains hints to the compiler about clobbered registers and the expected format of input and output parameters, which other compilers don't have)

  • That's fine. Thnx anway

**Attention** This is a public forum