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.

TMS320F28388D: C28x Compiler: SDRAM struct members designated initialization is using PREAD instruction

Part Number: TMS320F28388D


Hello,

in our project we are extensively using SDRAM memory. Recently we encounter a problem when using designated initializers of a struct members, when the struct itself is located in SDRAM.
The sample code is below:

typedef struct {
	uint16_t array[5];
} tsArray;

typedef struct {
	tsArray var;
} tsVar;


__attribute__((far)) volatile tsVar Global;

void main(void)
{
    //System init & SDRAM initialization is here
    
    //struct members initialization uses PREAD instruction & causing crash in some cases:
    Global.var = (tsArray) { .array = {0, 1, 2, 3, 4} };

    //manual struct initialization not using PREAD:
    uint16_t i;
    for (i=0; i<5; i++)
    	Global.var.array[i] = i;


    while(1)
    {  }
}

The designated initialization is using PREAD instruction, which I belive is forbidden for far SDRAM variables - according to this application note:
https://www.ti.com/lit/an/spraby4/spraby4.pdf

In our case the struct is very large and the code crashes at the struct members initialization. Then we inspected the generated assembly and saw the PREAD instructions.

Is this a compiler bug?

Best regards,
Andy

  • Hello Andy,

    From your code, what parts of the struct are living in far memory? Looking at examples of structure declarations from the app note:

    Does your use case fall into case 4? You can try making the fields volatile and seeing if the compiler is able to avoid PREADs correctly.

    Best regards,

    Omer Amir

  • Hello Amir,

    the whole structure lives in far memory. In the example above we do not have any pointers in the structure. Regardless of the fact if the struct members itself are declared volative (both var and array) or not, the compiler uses PREAD instruction.
    You can easily reproduce this piece of code on your side.
    Is this a bug?

    Best regards,
    Andy

  • Andy, referring this to our compiler team to take a look.

  • Thank you for notifying us of this problem, and for supplying a concise test case.  I can reproduce the same behavior.  I filed the entry EXT_EP-11462 to have this investigated.  You are welcome to follow it with that link.

    The best workaround is to not build the affected source file(s) with the option --unified_memory.  If your code is organized as a Code Composer Studio project, you can use File Specific Options to remove that build option only from those files.

    Thanks and regards,

    -George

  • This is not a bug, however, we will be updating the user guide wording to better clarify below subtlety.

    Struct assigns from non-volatile to volatile can use RPT with PREAD which uses the program bus for reading the non-volatile source operand:
       RPT       #4
    || PREAD *XAR4++,*XAR7

    Struct assigns from volatile to non-volatile can use RPT with PWRITE which uses the program bus for writing to the non-volatile destination operand:
       RPT        #4
    || PWRITE *XAR7,*XAR4++

    The provided test case that generates an RPT with PREAD is doing a struct assign from a non-volatile instance of non-volatile struct tsArray to a volatile struct.

  • Hi Greg,
    thanks for the explanation.
    But this suggests that the crashes we observed are not related with this. And the crashes were gone if we split one large function with such initialization to two smaller ones (still with --unified_memory).
    We need to investigate it further.

    Regards,
    Andy

  • An update about the crash cause.

    The crash resulted from a stack overflow. The initializers ate all the stack space. It seems counterintuitive because I would assume that the initialization would be a simple copy from Flash to SDRAM struct member:

    FLASH -> SDRAM

    Instead, there is an intermediate step with the stack:

    FLASH -> STACK -> SDRAM

    Why is that?
    Is there a way to avoid this intermediate step?

    Best regards,
    Andy

  • Is there a way to avoid this intermediate step?

    I couldn't find one.  So, I filed the entry EXT_EP-11470.  You are welcome to follow it with that link.  Note this does not report a bug, but an inefficiency.  The generated code works, but wastes memory.

    Thanks and regards,

    -George

  • Thank you.