This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Code Loader - Jumping to Compiler Startup Code

Hello,

AN112 provides three different methods for code loader designs.

However, we are considering having our Code Loader jump to the compiler's C_C51Startup function of our Main Application instead of its Main function. This would allow us to leverage the functionality that the compiler's startup code provides (clearing data; initialization of globals, statics; setting stack pointer; etc.).

Also, our Code Loader (and many others) never needs to run after it passes control to the Main Application. So we believe that we would not need to ensure that the data areas for the two applications do not overlap.

These two ideas seem to work well together. The C_C51Startup should ensure that the data area is initialized before the Main function of the Application runs even if it overlaps the data area of the Code Loader.

Are there any problems or drawbacks in the Code Loader jumping to the Application's C_C51Startup function and having the data areas of the Code Loader and Application overlap? It seems simpler and safer to us.

Parents
  • Sorry, AN112 is provided by the device manufacturer (Silicon Labs).

    However, my questions are more related to the Keil compiler startup code and boot strategies. Once again:
    1. Is it better for the Boot Loader to jump to the Application's C_C51STARTUP routine instead of jumping to the Application's Main function? It seems to me that jumping to the C_C51STARTUP routine is preferable since the application can have all of its globals, statics and stack pointer initialized.
    2. If the boot loader jumps to the Application's C_C51STARTUP routine instead of jumping to the Application's Main function and control is never passed back to the Boot Loader, then is it safe to allow the data areas of the Boot Loader and Application to overlap?

Reply
  • Sorry, AN112 is provided by the device manufacturer (Silicon Labs).

    However, my questions are more related to the Keil compiler startup code and boot strategies. Once again:
    1. Is it better for the Boot Loader to jump to the Application's C_C51STARTUP routine instead of jumping to the Application's Main function? It seems to me that jumping to the C_C51STARTUP routine is preferable since the application can have all of its globals, statics and stack pointer initialized.
    2. If the boot loader jumps to the Application's C_C51STARTUP routine instead of jumping to the Application's Main function and control is never passed back to the Boot Loader, then is it safe to allow the data areas of the Boot Loader and Application to overlap?

Children
  • The boot loader should not call main(), since you may need to change the startup script.

    If main never returns, you can let the boot loader share memory with the application - as long as the application doesn't try to configure the memory to keep it's value after a reboot.

  • let the watchdog time out and get a REAL reset.

    Many have been 'surprised' when they did a reset by software. e.g. this little pesky SFR is not in the reset state.

    Erik

  • The "best" surprise is when interrupts are still enabled (because the SFR keeps their contents) and the initialization code plays with a couple of settings and gets an interrupt without a valid stack.

  • AN112 is provided by the device manufacturer (Silicon Labs).

    which, by the experience of many, means likely to fail.

    The SILabs AN code is usually full of bugs.
    Here is an example from another SILabs code I just stumbled over, have a look. It just does not work, but if you only run the code 'as is' the error has no effect, but expand the code and BOOM!!!//Clear Message Objects
    void clear_msg_objects (void)
    { SFRPAGE = CAN0_PAGE; CAN0ADR = IF1CMDMSK; // Point to Command Mask Register 1 CAN0DATL = 0xFF; // Set direction to WRITE all IF registers to Msg Obj for (i=1;i<33;i++) { CAN0ADR = IF1CMDRQST; // Write blank (reset) IF registers to each msg obj CAN0DATL = i; }
    }

    read it and weep.

    1. Is it better for the Boot Loader to jump to the Application's C_C51STARTUP routine
    NO, use the watchdog and get a real reset!!!

    2. If the boot loader jumps to the Application's C_C51STARTUP routine
    It will, most lilkely 'surprise' you, use the watchdog and get a real reset!!!

    WHAT ABOUT NOT HAVING A REAL RESET DO YOU NOT UNDERSTAND?

    Erik

    PS the above re SILabs appnote code does not in any way reflect an opinion that AN code from others is any better.

  • The SILabs AN code is usually full of bugs.
    Here is an example from another SILabs code I just stumbled over, have a look. It just does not work, but if you only run the code 'as is' the error has no effect, but expand the code and BOOM!!!//Clear Message Objects

    void clear_msg_objects (void)
    {
      SFRPAGE = CAN0_PAGE;
      CAN0ADR = IF1CMDMSK; // Point to Command Mask Register 1
      CAN0DATL = 0xFF; // Set direction to WRITE all IF  registers to Msg Obj
      for (i=1;i<33;i++)
      {
        CAN0ADR = IF1CMDRQST;//Write blank (reset) IF registers to each msg obj
        CAN0DATL = i;
      }
    }
    

    read it and weep.

    In the early morning not even a mandatory preview can save me :(

    Erik

  • Eric et al,

    I think you may not understand my question (or I am not understanding your responses). We have two different applications in flash. On reset, our Boot Loader will run and normally (if an Application update is not required) jump to our Main Application.

    So, my question is with regards to the best/safest way to jump from the Boot Loader to our Main Application. Silicon Labs suggests the Main function, we are considering the C_C51Startup function. Which is better or do you have a third (better) option? Performing a reset will just return execution back to the start of the Boot Loader.

    Joe

  • Yes, I did understand your question.

    See my answer from 31-Jul-2007 11:26.

  • Yes, Per I believe that you did answer my question early in this thread. But I am confused by the subsequent posts which implied that I should be doing a reset. Clearly, this is not what I should be doing is it? Are the answers to my two original questions "Yes" and "Yes"?

    Specifically, Eric wrote the following:
    1. Is it better for the Boot Loader to jump to the Application's C_C51STARTUP routine
    NO, use the watchdog and get a real reset!!!

    2. If the boot loader jumps to the Application's C_C51STARTUP routine
    It will, most lilkely 'surprise' you, use the watchdog and get a real reset!!!

    Can I safely ignore his posts or am I missing something?

  • Erik is talking about something else - that a program that doesn't feel "well" should not try to jump to the startup code in an attempt to reset/repair itself. That is way dangerous, and a real hardware reset should be performed.

    Your original problem was how a boot loader should start a downloaded application. It should not jump to main(). Instead, all downloaded versions should contain their own startup code that should be called from the boot loader. That is required, to make sure that a bug in the startup code may be corrected by downloading new startup code. Also, the symbol main() may not be at a fixed location. Depending on what changes to do to the source, the linker may move it forward or backward.

    The startup code is responsible for setting up initialized variables. If the boot loader jumps directly to main(), the application code must initialize variables instead. If c++, the startup code is responsible for constructing global C++ objects. The startup code also adjusts any heap.

  • So, my question is with regards to the best/safest way to jump from the Boot Loader to our Main Application
    NOT TO JUMP, BUT TO LET THE WARCHDOG TIME OUT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    Can I safely ignore his posts or am I missing something?
    You, as anyone else can choose to "ignore his posts" but what is your resistance to doing the right thing? letting the watchdog time out is dead simple.

    If you absolutotally have to 'jump' then do as follows:
    get a hold of the lkist of SFRs in your chip, run a routine that reset them all to the reset value and then jump to startup. in that routine you may find some 'surprises' if the initializatrion is not done in the right order, but with a couple of weeks of work you can probably ghet it to where only one miss will be discovered after you have released the product.

    Silicon Labs suggests the Main function
    try it and WEEP. all SILabs code is 'tested' as is and when you use it in any other way you WILL find the bugs.

    Erik

  • I think you may not understand my question (or I am not understanding your responses). We have two different applications in flash. On reset, our Boot Loader will run and normally (if an Application update is not required) jump to our Main Application.

    NOW I get it, I would never expect anyone to default to running the bootloader.

    you are, in my opinion, doing it backwards.

    think about doing this: On reset, our Application will run and if an Application update is required set the required flag or whatever that will invoke the bootloader and do a FULL reset. When the bootloader is done it will reset the required flag or whatever that will invoke the bootloader and do a FULL reset.

    This way there will be no 'interaction'

    the "flag or whatever" must, of course, be non-volatile.

    Erik