1. This forum section is a read-only archive which contains old newsgroup posts. If you wish to post a query, please do so in one of our main forum sections (here). This way you will get a faster, better response from the members on Motherboard Point.

IAR linker: too smart

Discussion in 'Embedded' started by Dirk Zabel, May 16, 2006.

  1. Dirk Zabel

    Dirk Zabel Guest

    I am using the IAR toolchain for our Renesas M16C based project. The
    device uses a lot of configuration data which are stored within an
    eeprom. In order to define the placement, I have something like this:
    #pragma dataseg="E2PROM_DATA"
    #define extern /* empty */
    #include "eeprom.h"
    #pragma dataseg=default
    /* EOF */
    extern __no_init unsigned char MBUS_exist;
    extern __no_init char E2_VERSION_TEXT[20];
    extern __no_init unsigned char CAN_exists;
    extern __no_init unsigned char MBUS_exists;
    /* and so on. */
    /* EOF */

    I tell the linker to place the E2PROM_DATA segment where the eeprom is
    mapped into the address space and can use the data from other c sources
    by including eeprom.h
    The linker throws away all variables in eeprom.h which are not used
    anywhere in the projet (there is NO OPTIMIZATION selected!!). This is
    really bad, since I need a stable address mapping for all configuration
    data; there might be parameters which may be needed in later software
    versions; sometimes I build testversions which do not contain all parts.
    I allways need the variables at the same adresses.

    I did already asked the IAR support, but did not get a usable answer
    (they told me to use volatile, but this does not change anything).

    I see the following approaches:
    a) define a big struct which contains all variables and put that struct
    into E2PROM_DATA
    b) put dummy references to all variables into my project
    c) define the variables in some assembler source.
    d) the IAR toolchain allows to put variables at numerically known
    addresses, I could place every variable at some pre-calculated address

    a) I would have to change all code referring to (say) E2_VERSION_TEXT to
    s.E2_VERSION_TEXT (where s is the name of the struct variable). Since my
    project contains lot of old code, this is not very good.
    b) ugly, blows up my project with "useless" code (the linker is quite
    "smart", you have to DO something with a variable or the code is
    optimized away).
    c) ugly and dangerous, I have to keep the assembler definitions and c
    declarations in sync.
    d) IMHO address calculations should be done by tools, not by programmes
    due to possible errors.

    Has anyone some better idea?

    Dirk Zabel
    Dirk Zabel, May 16, 2006
    1. Advertisements

  2. Instead of defining away extern my instinct would be to put the variable
    definitions in eeprom.c and leave the declarations in eeprom.h. Then you
    could initialize the variables in eeprom.c and have a better chance that the
    linker would leave them alone. I'm assuming that you chose not to do that
    since you have the __no_init attribute, which, I'm guessing, puts the
    variables in a non-initialized segment.

    Maybe that's the problem - have you checked to see what happens without
    __no_init? Is it because EEPROM can't be initialized?

    andrew queisser, May 16, 2006
    1. Advertisements

  3. Dirk Zabel

    Dirk Zabel Guest

    Hi Andrew,
    the __no_init is required if I use the #pragma dataseg. If I omit it, I
    get a warning and the variables are placed into the standard data segment.
    Further, EEPROM variables cannot be initialized by the compiler, linker
    or loader, as there is a special procedure required to put a value into
    the non-volatile memory.
    Of course then #define extern is debatable, but I use this trick to be
    sure that the definitions and declarations of my variables are always
    the same. In the case of the IAR toolchain, this is not strictly
    neccessary, as the compiler emits type informations and the linker
    complains if there are conflicts.

    Dirk Zabel, May 16, 2006
  4. I'd go for a) despite the hassles. While you're at it, you can
    define minimun, maximum and default values for all your parameters
    stored in e2prom. Have them initialized with defaults (factory reset),
    and keep them within defined minimum and maximum allowed values when
    users change settings etc. Run a sanity check as part of the start up.
    Things like that can make life a lot easier. Okay, you need to have
    the space for such extras, but if you can afford it...
    Frank Bemelman, May 16, 2006
  5. Dirk Zabel

    Guest Guest

    yes, and use the #define to overcome the problem of old code (if it's really
    such a problem)


    Guest, May 16, 2006
  6. Dirk Zabel

    Dirk Zabel Guest

    Well, yes, but in my project there is already another software device
    taking care of user interface, limits and default values.
    Thanks for all your comments!
    I think, this looks best so far. Quite a lot of definitions (hope there
    will be no symbol table overflow in the preprocessor), but with todays
    memory sizes it should not be a problem. And all the defintions can be
    put into one file (eeprom.h), this is nice.

    But why on earth his this linke no option to switch off unwanted

    Dirk Zabel, May 16, 2006
  7. Is the problem is in getting the EEPROM values into HEX, or does the
    linker 'reshuffle' the deck for you, by removing unused data ?

    If the latter, then you could just SUM all EE variables into one
    expression/load - that way, you get around this weakness, as the
    variables are references


    If you are lucky, and place that into a never called function, then
    then linker might throw that away (unused), but not the names :)

    Jim Granville, May 16, 2006
  8. I find it hard to believe that you asked the right question. I've
    seen IAR support answer exactly this question, when it was asked
    the MSP430 ml.
    Use the __root keyword, this is what it's for. The linker does
    garbage collection, including only those things that are actually
    used, and __root adds a "root" to the gc. A root is a thing that
    you declare to be needed even if the gc can't see it being used.

    It's documented in the manual in the same place that __no_init is.

    Clifford Heath.
    Clifford Heath, May 17, 2006
  9. Dirk Zabel

    Dirk Zabel Guest

    Thanks to Clifford Heath, the __root keyword helped.
    I should have seen this, as it is documented in the compiler reference
    manual. :-(

    The question I asked was "is there any way to prevent the linker from
    this optimization". The answer was "no, there isn't one (only -q for
    version 4.10 of the ARM compiler)". Maybe I should have asked for a
    compiler (not linker) setting, but if I had known that the linker
    options are the wrong place to look I should have found the answer by

    Anyway, thank you very much!

    Dirk Zabel, May 17, 2006
  10. Dirk Zabel

    David Brown Guest

    Any code which uses the preprocessor to redefine a keyword like "extern"
    is incorrect code. It doesn't matter whether it works or not - it's
    still so bad that any experienced reviewer would reject it outright.

    IAR support are not famed for being helpful - on the other hand, their
    tools are well known for making correct and efficient code. The
    compiler (and linker) is doing exactly the right thing - if you declare
    variables that are never used, then the compiler and/or linker is free
    to remove them - they have no effect on the running of your program.
    You might think that the declarations have an effect on the addressing
    in eeprom - but that is not true. The order you declare or define data
    has no defined effect on the order in memory. For many targets,
    compilers will re-order the data for better alignment or padding. So
    even if you manage to persuade the tools to keep the unused data, you
    are getting a false sense of security - a new compilation could
    re-arrange the data.

    The easiest way to get the effect you are looking for is to define a
    single structure for all the eeprom-based data, and ensure that it is
    linked to one specific address (solution "a" below). If you want to
    access struct members without having to add "s." in front of them, you
    could use #defines to avoid it (although it is almost certainly best to
    correct the old code rather than add hacks around it).

    Solution (b) would not work (as explained above). Solution (c) is
    perfectly reasonable (although more effort than (a)), and solution (d)
    is again possible, but lots of effort to do well.
    David Brown, May 17, 2006
  11. Dirk Zabel

    bob Guest

    While we're on the subject of linkers...

    What is it about linkers these days and relocatable code placed at
    upload time ? I can't seem to get an absolute code listing anymore.

    Freescale (code terrorist) , IAR (arm) for example.

    How are they "located" at upload time ? Can I still get listings
    with meaningful code placement ?


    bob, May 17, 2006
  12. May I ask why that label? (I am not using Freescale tools at this
    time, but one never knows.)
    Roberto Waltman, May 18, 2006
  13. Dirk Zabel

    bob Guest

    There are several things I don't like about it, but especially the DSP
    56FXXX compiler version... I couldn't get the output I wanted, like
    a decent list output file, let alone an absolute listing (which is why
    my question)
    Their support sucked for this version where I had lots of questions...
    No forums or users groups to ask questions really... When I did try
    to ask questions on a small yahoo group, no answers. And the forum
    was moderated so my question didn't show up for a few days.

    When I sent in questions to support at freescale, it would take 6 days
    to get an answer and then they wouldn't usually understand my question
    so it took another 4 to 6 days to get another answer. Not always the
    right answer.
    Other little things about the interface they need to clean up as well.

    I also just got through with a project using CW for a 9S08QG8 project
    but it didn't give me too many problems, luckily except that I was
    happy to be able to remove it the other day finally.
    However, Code Warrior leave MANY MANY entries in the windows
    registry and after uninstalling either version, I have to run a
    registry cleaner afterwards to remove all the entries. Otherwise, the
    PC will run slower. THAT's terror !

    That's part of it anyway.
    bob, May 18, 2006
  14. Dirk Zabel

    James Beck Guest

    Code Terrorist, play on the real name Code Warrior.
    Add, CW also registers itself as the default program to open about 25
    different file types. MAYBE OK, if you only used their tools, but how
    many of us use multiple tools from many different vendors. CW
    (Metrowerks) is the only tool chain that I have ever loaded that assumes
    you run only their tools. I am still finding messed up file
    associations 2 years later.

    James Beck, May 18, 2006
  15. Dirk Zabel

    bob Guest

    I believe that cleaning the registry after CW has been un-installed
    will help with the file name associations. I'd better take a look
    myself though.

    bob, May 18, 2006
  16. Dirk Zabel

    James Beck Guest

    If you have to use the CW stuff then that isn't an option.
    I have to support some older PalmOS stuff so un-installing it isn't an
    James Beck, May 18, 2006
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.