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.

CCS Linker Commands; Placing App. routines at specific address.

Hi Thomas Mitnacht,

My question is not about the BSL...

I want to know how to tell the compiler to segment my code into two or more parts, and then tell the linker to place a certain segment at  a specific address. Can you respond with a specific example for say 2 segments below ?

void C_Code_A ( void) {

// Code Segment A

 }

void C_main (void ) {

//Code Segment B

 }

Thanks.

Bhal

************

I am new to CCS and TI MSP430. Have used Keil compiler before.

I am trying to use a bootloader in C which can get data from a serial port and
update the Flash with application code.

I did this in Keil toolset by using simple linker commands to locate the App.
code at always the same address. The bootloader copied the new code to this
address and then could be signaled to jump to it..

I have read many of the posts but can't find how to do this on MSP430. Maybe
that is because I can't find the CCS linker commands and how to tell the linker
to do this..

Is this possible in CCS and MSP430 ?

Any help that anyone can provide would be much appreciated..

Thanks.

Bhal Tulpule

  • Hello Bhal,
    May be you have a look at the Memory Programming User Guide. Almost any MSP430 has a build in Boot Strap Loader (BSL).

    Best Regards,
    Thomas Mitnacht

  • Bhal,

    See the attached code. There are 2 files in there that you would need to modify.

    1. The command linker file (.cmd). You would need to modify your command linker file to allocate the memory that you intend to put the function too.

    2. Set your function to be compiled inside a specified memory location. For example:

    #pragma CODE_SECTION(C_main,".codeSegmentB")

    void C_main(void) {


    }

    Regards,

    William

    RunningfromRAM_CCE.zip
  • While the BSL is a nice thing, it requires a critical handling of RST and TEST signals and is therefore only suitable if you have direct access tot he device and a proper connector. Even if you can call the BSL from within your application so you can just use an existing serial connection (if the proper port pins are wired), it might leave the device in a nonworking condition where there is no application code that will invoke the BSL and you end up requiring a direct access to the chip through a dedicated connector.

    Therefore many people (including me for he next product generation) decided to make theit own bootloaderm which will accept the new code in any way (SPI, radio transmission, USB, even SD-Card), buffer it in an unused flash area until received completely and correctly, and then copy the buffered content over to the 'working area'. If something goes wrong while receiving the new firmware, the old one is still in effect, and if the copying process is interrupted, the own bootloader will automatically kick in after device reset (without BSL entry sequence), check for an unfinished transfer of the buffered data and either copy again or jump to the applicaiton reset vector.

    It would be a good thing if the TI Bootloader would not only check for the BSL entry sequence but also for an FFFF value at 0xfffe, which means that there is no application code loaded at all. This way a simple serial connection (e.g. by a transparent wireless serial bridge) could be used without need for handling RST and TEST, as long as no application code is loaded/teh device has been erased. For other update sources, an own bootloader is still necessary.

    To do you own bootloader, it is necessary to define/alter some segments for the linker. So the compiler-generated vector table is laoded at e.g. 0xfd80, a (static) array of indirect jumps to it is generated at 0xfe00, 0xff00 holds the copy function and at 0xff80 is a static vector table pointing to the jump array. It adds some clock cycles to the interrupt latency, but ensures that you'll never end up with a nonworkign device, as the area from 0xfe00 to 0xffff is never erased and always hlds the same values, so the bootloader is always functional and can continue an started update even with a power-fail in the middle of the last try.

    Unfortunately I cannot tell how to set up and use different segments with IAR or CCE, as I'm mspgcc user.

    So the question of the OP is a valid one the way it was asked. And it is (unfortunately) still unanswered.

  • Hi all,

       While Jens-Michael Gross is correct for 1/2/4xx devices with the above text, things were changed with the BSL in the 5xx devices to specifically address the 'wish list' he mentions.

       BSLs can now be customized to communicate via any desired protocol as they reside in a protected flash area and can be reprogrammed with custom firmware.

       Additionally, BSLs can now customize the criteria used for an invoke.  Indeed, in the USB BSL, we use a blank RESET vector as an indicator to say the BSL should be started, allowing a blank device to be programmed.

       For more info on this, please see application report: SLAA450

  • Lane Westlund said:
    While Jens-Michael Gross is correct for 1/2/4xx devices with the above text, things were changed with the BSL in the 5xx devices to specifically address the 'wish list' he mentions.  BSLs can now be customized to communicate via any desired protocol as they reside in a protected flash area and can be reprogrammed with custom firmware.

    Sorry to correct you, but for the 54xx devices (non-A), the BSL is still fixed due to a silicon bug (BSL area cannot be programmed). Moreover, the BSL entry sequence is so tight in timing, that you cannot use e.g. an USB serial converter to provide the entry sequence.
    Since the A devices are significantly more expensive, it's a tradeoff: more latency time and own bootloader or higher production cost. If you care for in-field-programming at all.

    On the 54xxA devices, you can indeed download your own customized BSL, and I'm glad to hear that there are prebuilt bootloaders available now which are automatically started if the device is empty. Good ideas are often encountered by more than one person. :)

    But if you don't use a 54xxA or 55xx, you need the information provided by William Goh.

  • Jens-Michael Gross said:
    Sorry to correct you, but for the 54xx devices (non-A), the BSL is still fixed due to a silicon bug (BSL area cannot be programmed).

    You are absolutely right.

    Jens-Michael Gross said:
    Moreover, the BSL entry sequence is so tight in timing, that you cannot use e.g. an USB serial converter to provide the entry sequence.

    This bug is affecting the F54xxA silicon but not F54xx silicon. You can still use a normal USB serial converter to provide the entry sequence for F54xx.

    Regards,

    William

     

  • William,

    THanks for your response.

    What I basically want to do is to put my "bootloader" in SEG_A and everything else, i.e. all application code,  in SEG_B.

    From the information provided and some more reading of the C/C++ manuals it seems that, since my code is entirely in C, I would have to place the above Pragma in front of each and every function. That's a lot of functions.... Is there any alternative to this, like placing the Pragma at the top of a file ?

    Also how do I force all c_lib and other automatically invoked functions into this one of these segments ?

    Regards.

    Bhal Tulpule

  • Again, I can only speak for the mspgcc.

    For the c_lib there's no chance. It has been compiled with standard 'text' segment location. Unless you manually change the segment entry inside the c_lib binary, there's no (easy) way to tell the linker to handle the libraries text segment differently to the other code file's text segment. (there might be a chance to make some nasty twists in the linker scripts, but I'm not sure)

    For compiling a whole source file into a different segment, there might be a compiler parameter that you can apply to this single code file. Or maybe you can separate your bootloader into a separate project forming a library and compile this project with a different default segment for code. Then include the library to your application code project.

    But it's easiest to just 'shrink' the segment info for the default text segment, create a second segment in the 'freed' area and then apply the pragma onyl to the function in the bootloader.

    e.g. limit the size of the text segment so it goes only to 0xf7ff instead of 0xff7f, create a new segment 'boottext' in the area 0xf800-0xff7f and compile all functions for the bootloader with the appropriate pragma. It shouldn't have that many and it's a one-time-job.

  • Bhal,

    If the bootloader code and the rest of the code can be separated into different source files, the allocation can be controlled in the linker command file in the following way:

    Say the bootloader code is in file bootloader.c, and rest of the code is in main.c.

    SECTIONS
    {
       .bootcode : { bootloader.obj (.text)} > SEG_A
       .maincode : {main.obj (.text)} > SEG_B
    }

    If the code is in more than one source file, multiple object files can be listed there as well.

    You can control placement of runtime library functions in a similar manner.

    SECTIONS
    {
    .rtstest : { --library=rts430.lib(.text) } > SEG_B
    }

    The MSP430 Assembly Language Tools Users Guide, http://www.ti.com/lit/slau131, Section 7.8 contains details and syntax for controlling your sections placement.

**Attention** This is a public forum