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.

c2000, CGT 6.4.5 creates different code as 6.2.11: Union copy fails (CAN register)

Other Parts Discussed in Thread: CONTROLSUITE

Hi

Short: TM320F28335, reading eCAN Msg Box by copying union MDH (part of MBOX struct)  fails with CGT 6.4.5

Reason: generated code seems not to work

Edit: PREAD is "read from program memory" command? But the read address is data and defined in page 1 in cmd file.

This C-Code (see difference: 1st line with access of .all, 2nd line access of union)

PtrMsg->MDL.all = PtrMBox->MDL.all;
PtrMsg->MDH = PtrMBox->MDH;

generates (with CGT 6.1.10 / 6.2.11) this asm:

PtrMsg->MDL.all = PtrMBox->MDL.all;
MOVL         ACC, *+XAR5[4]
MOVL         *+XAR4[4], ACC

PtrMsg->MDH = PtrMBox->MDH;
MOVL         ACC, *+XAR5[6]
MOVL         *+XAR4[6], ACC

This does copy the content of addres 0x6146 (MBOX content of msg box 8) to my local union. -> all OK!


With CGT 6.4.5 the same C code leads to this asm

PtrMsg->MDL.all = PtrMBox->MDL.all;
MOVL         ACC, *+XAR5[4]
MOVL         *+XAR4[4], ACC

PtrMsg->MDH = PtrMBox->MDH;
ADDB         XAR1, #6 ; this makes point XAR1 to correct destination in my local union
ADDB         XAR7, #6; this makes XAR7 point to correct source 0x6146 which is mbox data
RPT         #1
|| PREAD       *XAR1++, *XAR7; this read fails! no data copied from 0x6146 to my local union

Question: Why?

Thank you & regards

Roger

MBOX is found in TI headers for c2000 (DSP2833x_ECan.h)

struct MBOX {
   union CANMSGID_REG     MSGID;
   union CANMSGCTRL_REG   MSGCTRL;
   union CANMDL_REG       MDL;
   union CANMDH_REG       MDH;
};

  • To understand what has occurred, I need a test case which allows me to generate the same assembly output.  Please preprocess the source file and attach it to your next post.  Indicate which line numbers are related to the problem.  Also show exactly how the compiler is invoked.

    Thanks and regards,

    -George

  • Hi George

    Thank you for you reply.

    Based on TI example delivered with controlSuite:

    C:\ti\controlSUITE\device_support\f2833x\v140\DSP2823x_examples_ccsv5\ecan_a_to_b_xmit

    Change CGT to 6.4.5

    Modify main function with:
    declare local variable at top of main function

    struct MBOX MyMsg;

    add this code

      MyMsg.MDL.all =  ECanaMboxes.MBOX25.MDL.all;
      MyMsg.MDH =  ECanaMboxes.MBOX25.MDH;

    results in:

    132           MyMsg.MDL.all =  ECanaMboxes.MBOX25.MDL.all;
    MOVW         DP, #0x187
    MOVL         ACC, @0xc
    MOVL         *-SP[4], ACC

    133           MyMsg.MDH =  ECanaMboxes.MBOX25.MDH;
    MOVZ         AR4, @SP
    SUBB         XAR4, #2
    MOVZ         AR4, @AR4
    RPT          #1
    || PREAD        *XAR4++, *XAR7

    Here's a zip:

    Thank you!

    Roger

    Example_2823xEcanA_to_B_Xmit.zip

  • You build with the switch --unified_memory (-mt for short).  According to the compiler manual ...

    this allows the compiler to generate RPT PREAD instructions for most memcpy calls and structure assignments

    This is not new behavior on the part of the compiler.  Earlier versions of the compiler could also use PREAD in this situation.  That this didn't occur is only a matter of luck.  

    Build without --unified_memory, and the PREAD instruction is not used.

    As for why your device does not support PREAD being used in this fashion, I recommend you start a new thread in the C2000 device forum.  Or, if you prefer, I can move this thread into that forum.

    -George

  • Hi George

    Ok, this does clarify why the compiler does create the PREAD.

    One big question is:

    Why does 28335 not support PREAD access in this case. --> Yes please move this thread to C2000, thank you!

    @C2000 Pro:

    With in the example above the compiler 6.4.5 does create code which does not work correctly? What is your advice?

    Disable -mt?

    Not use 6.4.x?

    If I do a grep 'PREAD' over all asm file in my project with CGT 6.1.10 I find 51matches, in asm files generated wIth 6.4.5: 58 matches.

    Thank you & regards

    Roger

    Edit:

    Datasheet of 28335 says: ... Peripheral Frame 1 ... memory maps are restricted to data memory only.  A user program cannot access these memory maps in program space. 

    Is this the reason?

  • Hello TI
    Sorry for bumping this, but these questions are still pending:
    - Why does PREAD of MBOX memory always result in 0 (zero)?
    - Why does CGT 6.4.x create a PREAD if this does not work?
    Thank you!
    Roger
  • Hi Roger,

    PREAD will not work for this:
    MyMsg.MDH = ECanaMboxes.MBOX25.MDH;

    CGT 6.4.x is compiling the above using a PREAD because you are using a unified memory map. You need to disable the unified memory map.

    PREAD cannot access the memory maps of the peripherals. It must be designated Data space, and MOV must be used to read from the registers.

    Please disable unified memory map and this should work.

    sal
  • Hi Sal

    Thank you for your message.

    If I would disable unified memory, the CGT will no longer create the PREAD for other struct copies too (which currently work of course and are performant).

    Is there not a way to tell the CGT to not use PREAD for peripheral memory maps only? I'm a bit surprised that this is not done automatically...

    Roger

    By the way: all TI examples for 28335 (control suite) are using unified memory model.

  • Hi Roger,

    Please see www.ti.com.cn/.../spru430f.pdf

    I do not think the Program Read Bus is connected to this memory space, hence it is returning nothing.

    MOVZ AR4, @SP
    SUBB XAR4, #2
    MOVZ AR4, @AR4
    RPT #1
    || PREAD *XAR4++, *XAR7

    Do you have any optimizations turned on? I wonder if the unified memory flag with an optimization flag is causing the compiler to generate more efficient code with the PREAD... Although I doubt this because PREADs should not be generated when accessing volatile memory. This may be a compiler bug. I will get back to you on this.

    For now, please turn off the unified memory model flag. This will prevent the compiler from using PREAD on Data memory.

    DSP2833x_Headers_nonBIOS.cmd puts the Peripheral Registers in Page 1 which is Data Memory. A non-unified memory model will prevent the compile from generating PREADS to Page 1 Data.

    sal
  • Roger,

    Are you getting a warning by writing: MyMsg.MDH = ECanaMboxes.MBOX25.MDH; ?

    You should be writing: MyMsg.MDH.all = ECanaMboxes.MBOX25.MDH.all;

    I am surprised you are not getting an error or at least a warning. If you do this, this should also fix your problem.

    BTW, you are correct that the Peripheral memory space is not on the Program Read Data Bus (PRDB).

    sal
  • I have rebuilt your project and noticed that when not using the ".all" to access ECanaMboxes.MBOX25.MDH and MyMsg.MDH, the PREAD is generated and is trying to access the address in XAR7.  It looks to be also pointing to the peripheral memory space which is not accessible using PREAD.

    So there are a couple problems.

    • You should be using .all to access the union (i.e. all of the register)
    • The compiler did not recognize that the address it was accessing was volatile because of the incorrect C coding.

    I have made the changes to add .all to the sructs and the assembly is corrected.  It accesses the correct memory space and it uses MOVL.

    Hope this helps.

    sal

  • Hi Roger,

    I also just found this e2e.ti.com/.../439228

    Try using a newer compiler.

    sal
  • HI Sal

    Thank you for all your replies!

    • I do not get any warning for assigning one union to another (of same type). I do even think that this is ok. It should not create a warning, because assigning unions of same type should be supported by compiler I thought (like struct assignement).
    • I tried 6.4.6 too, same behavior as 6.4.4 / 6.4.5
    • PREAD is also created without optimizations (-Ooff)
    • I was curious: I tried to copy a volatile struct of MBOX to a struct MBOX  (this is one level up, the struct which contains the MDH union). The compiler does also create a PREAD. So this would also fail if used in the real sw. But C should support struct copy (even deep copy)...
    • The above test with struct copy fails too with CGT 6.2.11, 6.1.10 (compiler creates PREAD). So this seems really be a matter of luck that we did not run into troubles before... (as George Mock said).
    • I will check if the -mt could be disabled in my project, not sure if it has an impact to performance...

    What would be great is: The compiler knows that the the source for my copy is in peripheral memory area and does automatically NEVER use PREAD. Could perhaps be done with chek of volatile as you mentioned?

    Regards,

    Roger

  • Hello,

    This topic seemst to be the very same problem as one I posted a few months ago:

    e2e.ti.com/.../422482

    The release note of 6.4.4 explicitely states that it's supposed to be fixed:

    -------------------------------------------------------------------------------
    FIXED SDSCM00051601
    -------------------------------------------------------------------------------
    Summary : The C28x compiler uses a RPT PREAD loop when copying volatile structs

    Release Notes:
    PREAD instructions should not be emitted when accessing volatile data.


    Also, assigning a struct or a union to copy it is perfectly valid code, it should work (and used to before CGT 6.4) even without the .all
  • This does seem to be a compiler bug.  I have posted it to the compiler forum.

    Thank you for your help and for your patience.

    sal

  • You can see this recent post. It is indeed a compiler bug and should be fixed.

    e2e.ti.com/.../1613702

    sal
  • Thank you Sal!

    I've seen SDSCM00052255 which files this issue.

    Best regards
    Roger
  • Hi George,

    Please see this topic: e2e.ti.com/.../422482

    "Using PREAD on a volatile struct is a known bug, SDSCM00051601. The bug is fixed in C2000 6.4.4".

    The bug does not appear to be fixed yet, since the compiler happily generates PREAD for volatile structs and unions.

    Pierre
  • Hi Pierre

    Yes you are right. 6.4.4 does mention it is fixed, but it is not.

    I tested it with 6.4.9 and here it is fixed! (compiler will create memcpy calls instead of PREAD, at least with the code I did check).

    Roger