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.

Using "far" declaration

Other Parts Discussed in Thread: MSP430F5419

I am using CCSv4.1 designing a product in C for an MSP430F5419.  To keep backward compatibility I need to have a global struct in a fixed position in RAM.  I have modified the linker file to reduce the RAM space used by .bss and assigned some of it to my own RAM section.  I then use the #pragma DATA_SECTION(...) to position the struct in this section.

This seems to work fine - looking at the memory shows my struct is placed where I want it and access seems to work fine.  The C compiler user guide slau132d states in section 5.8.4 that:

"If you allocate a global variable using a DATA_SECTION pragma and you want to reference the variable in C code, you must declare the variable as extern far". 

Unfortunately using the "far" keyword in my code (for the struct and also for other variable types) throws up compiler errors - it seems not to be recognised as a keyword.  I have the same problems using IAR Kickstart. 

Am I OK in this application to ignore the recommended use of the "extern far" declaration?

 

Thanks,

Chris.

  • I cannot help you with the 'far' problem (I think this is only required when using the large data model with possible data locations above 64k).

    But I wonder why you need to do all this effort. What backward compatibility? It is a RAM location we are talking about. So if you power up the device, the area is blank. And since the only one (normally) accessing this data is the firmware, and the firmware is not dynamically loaded from an external source without resetting the system, it does not make any difference where this structure is locate. Just let the linker decide where to put it and teh code will use this location and all is well.

    After thinking about it again, maybe I have a clue why you have problems with the declaration:

    Other than with a normal variable declaration, those with the DATA_SECTION pragma are actually defined at this space and explicit code is generated immediately. So this kind of definition can only be placed in a .c file, not a header file, and the variable must be propagated tot he rest of the program using an extern declaration. With the 'far' modifyer as the compiler cannot determine on its own where the final location will be (in- or outseide the lower 64k).
    So the 'extern far' does not belong to the variable definition (with the pragma) but to an additional variable declaration (without the pragma).

  • The backward compatibility is due to redesigning an existing product (the old processor is becoming obsolete) but wanting to keep the PC software that communicates with the firmware unchanged (including some of the hard-coded memory access operations).  Not an ideal solution, but the best of the available options.

    I understand why the "extern far" could be required for accessing memory in a large-memory model, my problem is that when declaring "extern far unsigned char wibble" in my header file the compiler throws up errors.

  • Well, without  seeing the exact code that throws the error and the exact error message, I have no idea. And it might be possible that the error shows up only in a certain context (usage of the header file and code in teh C file etc).

  • The variable is initially declared as follows:

    #pragma DATA_SECTION(wobble, ".fixedram")
    unsigned char wobble;

    Following my understanding of the user guide the extern declaration used is:

    extern far unsigned char wobble;

     

    The error messages are:

    warning: explicit type is missing ("int" assumed)

    error: expected a ";"

     

    If I use "extern unsigned char far wobble" I get the same error message (but not the warning about the type specifier for obvious reasons).  Basically it is not recognising the word "far" as a keyword but assuming it to be the name of a variable.

     

    I have also tried using various other declarations including far pointers as seen in C programming examples scattered across the web e.g. "unsigned char far* wob;" but still get the same error messages.  Have I missed something?  Is "far" simply not supported by the compiler - I know it is considered a non-standard keyword but as it is in the user guide it must work in some context surely...?

     

    Thanks,

    Chris.

  • It seems that you're right and the compiler simply does not recognize the far qualifier. And perhaps this is not necessary at all anymore and the part in the docs is from CCS 2.x or even before.

    If your data is located in the lower 64k, then there is no need to declare it far, as it isn't. It's near and a 16 bit access will be fine under all circumstances.
    If the data is outside teh lower 64k, then you'll need to activate the large memory model in the project options. But then all variables are autoimatically considered far and accessed by 20 bit pointers. So no need to declare it far once more.

    The only problem is that libraries compiled with normal (small) memory model won't work if the program passes far references. The functions will simply misinterpret the 20 bit parameters. If passed by registers, only the lower 16 bits will be used, if passed on stack, the library function will completely misinterpret the 32 bit references and confuse its parameters.
    In case of the CLIB, the comiler knows the memory model by the project settings and therefore the linker will link the proper version of the library. (at least I hope so)

**Attention** This is a public forum