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.

Compiler/TMS320F28379D: C2000 SDRAM access with volatile keyword

Part Number: TMS320F28379D

Tool/software: TI C/C++ Compiler

Hi there,

I found the requirement of using "volatile" keyword for access SDRAM, ie. "far" section, is not necessary from the compiler perspective.

As found in the documentation, to access SDRAM:

  • data/array should be with "far" attribute so compiler will use 32-bit address mode to access data/array in SDRAM, because symbols are assumed to be within 22-bit address:

However, 

  • any data with far attribute needs volatile keyword to make the compiler happy

The update from SPRU514H should be sufficient to deassociate "volatile" from "far" attribute.

Since volatile keyword has its own meaning in C, adding any processor-specific use to it is not a good idea.

Please keep me updated regarding the C2000 compiler change to this issue.

Thank you!

Young

  • This situation is discussed in the application note Accessing External SDRAM on the TMS320F2837x/2807x Microcontrollers Using C/C++.  

    Thanks and regards,

    -George

  • I understand the application note. This is addressing the use cases for C2000 compiler v6.4.0 (we are at v18.1.0 as of today). I think the volatile keyword is no longer needed for the 32-bit addressing as all pointer accesses have been considered 32-bit since SPRU514H. The only exception is symbol access, which is still 22-bit by default. Thus, I would say volatile is no longer needed for this purpose.

    Consider the following cases:

    int far_data[10] __attribute__((far)); // data array in SDRAM

    To access the data array:

    1. Directly using symbol:
    far_data[0] = 10; // far attribute should make sure the compiler use 32-bit addressing

    2. Indirectly using pointer:
    int * far_data_p = far_data;
    *far_data_p = 10; // according to the release note, starting from SPRU514H, far_data_p should always be 32-bit addressing

    So, I do not see the neccessity of "volatile" keyword in any cases.

    First, the use of volatile basically prevents optimization when accessing SDRAM.

    Second, volatile keyword is a strong qualifier and cannot be mixed with regular type, ie. volaile int != int. In the case of accessing external SDRAM and internal SRAM, as a simple example, two set of APIs are needed:

    void update_data_in_sdram( volatile int * addr, int value ); // for data in SDRAM
    void update_data_in_sram( int * addr, int value ); // for data in SRAM

    If I understand correctly, the above can be avoided given that since SPRU514H all pointers are considered 32-bit addressing.
  • The volatile keyword is needed to prevent the compiler from using instructions that access data via the program bus. Example instructions are PREAD and PWRITE. Prior to 6.4 the compiler already avoided these instructions for volatile types because those instructions can't read from memory mapped peripheral registers. 

    This is mentioned in the app note that George pointed you to.

  • Hi Cody,

    Since SPRU514H, the size of pointer types has been changed to 32 bits. I do not see any reason why the compiler still uses 22-bit program bus to access memory pointed by a 32-bit pointer.

    The only exception is to access memory directly using symbol, since it is still assumed to be 22-bit for performance reason; however, __attribute__((far)) on the symbol should be explicit enough to ensure the compiler not to use 22-bit address to access this specific memory with such symbol.

    Or is there some misunderstanding I have regarding the compiler behavior?

  • The far attribute applies to the symbol, not the type. This means that once you take the address of the symbol and store it in a pointer, there is no way to know if it points to a far address. For various reasons supporting a far type attribute is difficult and poses many challenges in the language. However, the language does support volatile types and volatile for C2000 prevents accesses via the program bus. Therefore we made the decision to require all far objects be volatile. There is no way to get around this detail. All far objects must be volatile.
  • > The far attribute applies to the symbol, not the type

    Exactly. To access far symbol directly, the compiler knows to use 32-bit address.

    > This means that once you take the address of the symbol and store it in a pointer, there is no way to know if it points to a far address.

    It does not matter if the pointer is pointing to a far address or near address, as long as the compiler follows the update since SPRU514H: "The size of pointer types on C28x is now 32 bits instead of 22 bits". Why would a compiler use 22-bit program bus to access a memory pointed by a 32-bit pointer?

    To my understanding, the whole purpose of the update in SPRU514H I quoted is to have an unified memory access scheme, with the only exception of symbol access for performance reasons, which is properly addressed with __attribute__((far)).