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.

CCS/TMS320F28377D: An unexpected behavior happen which is a value set to 0 after assignment by no reason when i try to assign a Not Zero value to the variable,

Part Number: TMS320F28377D

Tool/software: Code Composer Studio

When running the code attached in the file below with CCS 8.3.1 and chip TMS320F28377DPTPQ.

After calling the function "testFunc" in line 66,the variable "test" should be set to the value of "collection->item.dataAddr[0]" after executed line 40.

But an unexpected behavior  happened after line 40, the "test" was set to 0,but the value of "collection->item.dataAddr[0]" should be 1.

I think the problem is due to the function "testFunc2", the return value of testFunc is a struct, and when assign the return value to "collection->item" in line 39,the point value "dataAddr" in the struct testStruct1 was ignored in the assignment. 

Can you tell me the reason why the problem happen and how to fix the problem?

U53_demo_CPU3.rar

  • Hello,
    Can you try updating your compiler version? I was able to reproduce the issue when I loaded the executable you built (built with compiler version 16.9.4.LTS). But when I rebuilt the program with compiler version 18.12.1.LTS, the issue went away. It could be a compiler issue.

    Thanks
    ki
  • Hi,

    I figured out the reason why the problem happened last night.

    The problem is that when executing line 40, in the last step in assembly language

    MOVL    XAR7, *+XAR4[2]

    The register XAR4 stored the value of "collection", after executing this step, the value of "collection->item.dataAddr" should be assigned to the
    register XAR4. The problem is that when I assigned he value of "arrayTest" to "testItem4" in line 60, the value of arrayTest isn't align to 32bit, therefore, the MOVL function cannot execute correctly.
    The function MOVL force the address aligned to 32bit.
    for example, when running the code below, the value of testItem4 should be set to 0x00040003,0x00030002,0x00020001. but the fact is that the value of testItem4 would be unexpected at least once.

    uint32_t testItem4;
    uint16_t array[5]={1,2,3,4,5};
    testItem4=*((uint32_t*)(array+2));
    testItem4=*((uint32_t*)(array+1));
    testItem4=*((uint32_t*)(array));

    I still don't find any document of the problem why the MOVL would force align the value to 32bit. Is there any document explaining this?

    Thanks

    Song

  • Hi Song,
    Did you try updating the compiler version?

    I can reproduce the issue when I build with 16.9.6.LTS
    I cannot reproduce the issue when I build with 18.12.1.LTS

    It may be a known bug that was fixed in recent compiler version. Please try the updated compiler.

    Thanks
    ki
  • Dear Ki,

    I have confirmed that the problem can be fixed by updating my compiler version to 18 or later, but the reason why the problem solved is that the address of "arrayTest" is set to the "0xB000" which is aligned to 32bit in this compiler version.

    However, the problem can be reproduced by changing the line 60 from

      testItem4=(testStruct2*)arrayTest;

    to

    testItem4=(testStruct2*)(arrayTest+1);

    The reason cause the problem mentioned in the last reply above.

    When executing the assembly language like follow:

    MOVL XARN, *B

    The value of B must aligned to 32bit,otherwise the MOVL function will force the B aligned to 32bit which will case the problem mentioned.

    But i don't know whether it is a BUG in MOVL or not.

    Thanks

    Song

  • Ah, ok. Thank you for the analysis. This certainly looks like an issue with the build tools. I will bring this thread to the attention of the compiler experts.

    Thanks

    ki

  • This is a case of user error. 

    When you write something like ...

    Hansong Lee said:
    testItem4=*((uint32_t*)(array+1));

    ... the compiler assumes the result of the pointer expression cast to the type uint32_t * is correctly aligned.  This is due to a part of the ANSI standard for C called the strict aliasing rule.  Speaking loosely, it means a memory location must be accessed by a type that is a close match to the type used to write it.  In this case, to safely access memory locations in array, you should use type uint16_t.  When you use uint32_t instead, the compiler assumes the underlying memory was written as uint32_t, and thus the alignment constraints of uint32_t are being met.

    Thanks and regards,

    -George