Link problems with embOS 3.82b and IAR 5.40.2+, AT91SAM7S256 - serious!

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • Link problems with embOS 3.82b and IAR 5.40.2+, AT91SAM7S256 - serious!

    I am trying to build an app to launch from ROM, but run all but my startup code from RAM. There is no example like this included with embOS. IAR has an app note that suggests that is easy to do in 5.40.2 and later. Sadly, the linker tries to be a little too "smart" and this causes some problems. The problem is that the linker makes a decision about what code is needed for startup, and then no matter what, that code is not located in RAM. There seems to not be any way to locate it in RAM and have it get copied by the IAR startup process. Something is causing the linker to want to place everything from rtosinit into ROM. So for example, the interrupt handlers get located in ROM and the system fails badly on the first system clock tick if ROM is not available. It would appear from the IAR docs, and my tracing the ASM through to the call to main, that everything from main and later should be copied to RAM. Without the source package I don't have much visibility into the reason why this is not happening. Does anyone have some insight into this, if not actual knowledge of why it happens and how to work around ?
    Any suggestions will be much appreciated.
    George
    PS - I just copied the demo application Start_AT91SAM7S256 provided with embOS 3.82b and added "readonly" to the initialize by copy line. It becomes "initialize by copy (readonly, readwrite)". This is sufficient to demonstrate the problem. After building, the map file shows many important runtime functions in ROM. For example, OS_irq_handler(), OS_Error(), and OS_Idle().

    The post was edited 1 time, last by gpontis ().

  • The problem is caused by the function __low_level_init() which we placed into the RTOSInit file.
    This function is the first one called by the startup code, before any segments are initialized and before any code is copied into RAM.
    Therefore, the function has to be located in ROM.
    Unfortunately, the linker places the whole RTOSInit module into ROM, not only the __low_level_init() function and the other functions called from there.
    You might do the following:
    1. Rename the function __low_level_init() in RTOSInit and declare the function as static.
    2. Call the new renamed function from OS_InitHW() as first operation, or right after the call of OS_IncDI().
    This modification should ensure that no embOS function is linked to run in ROM.
    Alternatively, you might remove the __low_level_init() function and the other functions called by __low_level_init() from RTOSInit and place them into a separate file.
    This file would of course be linked into ROM, but that should not hurt, as the code is executed only once after reset.
    When you eliminate the __low_level_init() function, system startup time might be slightly longer,
    because the oscillator and the PLL are not initialized right at the start.
    Best regards,
    Armin
  • Many thanks for this clarification Armin. I followed this through and it solved everything. I had already been on the track of low_level_init and moved that plus _InitRTT into a separate file. The call to _InitVIC was more problematic due to references to interrupt handlers. After your explanation I removed the InitVic reference from low_level_init and now call it from the beginning of main. I marked some one-time initialization routines in RTOSINIT as section icode which saved a meaningful amount of RAM.
    While working on the startup code I noticed a significant inefficiency in low_level_init. The second line of code configures the on-chip flash controller for 3 wait states. The datasheet for this SAM7S, and also the SAM7X, notes that the part never needs more than 1 wait state even at the maximum clock rate. If you change this from 3 to 1 wait state it will greatly speed up programs that are running out of ROM. I have not timed it but an improvement up to a factor of 2 should be possible.