TMS320F28379D: Compiler gets the address of struct member wrong

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

Hi I was looking ahead to the weekend, when my code started to fail in a wired way.

During initialization I assign the same address to a member of two structs, both of the same type.

But during debugging I saw that one of the members did not get the new value, at the same time another struct close by got a strange value....

I narrowed it down to the compiler calculationg a wrong address, for one of the memebers.

The C-code snippet.

image.png

The related assembly, as shown in the debugger

image.png

And the same assembly highlighted, bacause the collers in CCS dark-mode is a bit broken ;-)

image.png

And a snippet of the memory layout

image.png

The assembly for write to the first struct is:

`08cf80:   A83C        MOVL         @0x3c, XAR4`

with the DP = 0x5f4, the `@0x3c` points to address 0x17d3c, which matched the structs mambers location in memory.

But the assembly for write to the second struct is:

`08cf81:   A804        MOVL         @0x4, XAR4`

with the still being DP = 0x5f4, the `@0x4` points to address 0x17d04, which don't match the structs member, but instead writes to the area where the variables `_localSyslogDoneQueueNextReadIdx` and `level`. As you can also see the debugger highlighted in the momory view.

As far as I can see the correct assembly should have been:

`08cf81:   A844        MOVL         @0x44, XAR4`

It's close to the weekend, so I did not have the time to setup a demo project, also I don't know what triggered this bug, so it might be difficult (read: take a lot of time).

My compiler seetings:

cl2000" --cmd_file="diagnostic_options.opt"  -v28 -ml -mt --cla_support=cla1 --float_support=fpu32 --tmu_support=tmu0 --vcu_support=vcu2 -O1 --fp_mode=relaxed  --obj_directory="Src" --cmd_file="syscfg/board.opt" --cmd_file="syscfg/device_cmd.opt" --cmd_file="syscfg/c2000ware_libraries.opt"  --define=FLASH_LAYOUT=LOW  -DLNK_TIME= "Main.c"

cmd_file="diagnostic_options.opt":

--diag_error 10247
--diag_warning 183
--diag_warning 195
--diag_warning 225
--diag_warning 2709
--diag_suppress 10205
--diag_suppress  383
-pdr
-pdv 
-pden

cmd_file="syscfg/board.opt":

-I"C:/ti/c2000Ware/C2000Ware_5_01_00_01/device_support/f2837xd/common/include/"
-I"C:/ti/c2000Ware/C2000Ware_5_01_00_01/driverlib/f2837xd/driverlib/"
-DCPU2

cmd_file="syscfg/device_cmd.opt"

-DCMDTOOL
-DRUN_IN_FLASH

cmd_file="syscfg/c2000ware_libraries.opt" is empty

And for completenes here is the state of the registers, 

image.png

Edit: Forgot the compiler version:

cl2000 -version
TMS320C2000 C/C++ Compiler v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D

TMS320C2000 C/C++ Parser v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 EABI C/C++ Parser v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 C/C++ File Merge v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 C/C++ Optimizer v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 G3 C/C++ Codegen v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 Assembler v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 Embed Utility v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 C Source Interlister v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 Linker v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 Absolute Lister v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 Strip Utility v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 XREF Utility v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 C++ Demangler v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 Hex Converter v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 Name Utility v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 Object File Display v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D
TMS320C2000 Archiver v22.6.0.LTS
Build Number 1WF5K-2LI-RZASS-TAQ-C08D

  • Update

    It appears to happen at link-time

    If I add the `--keep_asm` to the compilation of the file

    I find this in the asm file

    ;***************************************************************
    ;* FNAME: DebugLog_Init                 FR SIZE:   0           *
    ;*                                                             *
    ;* FUNCTION ENVIRONMENT                                        *
    ;*                                                             *
    ;* FUNCTION PROPERTIES                                         *
    ;*                            0 Parameter,  0 Auto,  0 SOE     *
    ;***************************************************************
    
    ||DebugLog_Init||:
    ;* AR4   assigned to $O$C1
    	.dwcfi	cfa_offset, -2
    	.dwcfi	save_reg_to_mem, 26, 0
    	.dwpsn	file "D:/gsrc/DebugLog.c",line 215,column 5,is_stmt,isa 0
    $C$DW$226	.dwtag  DW_TAG_TI_branch
    	.dwattr $C$DW$226, DW_AT_low_pc(0x00)
    	.dwattr $C$DW$226, DW_AT_name("LogBuffer_Init")
    	.dwattr $C$DW$226, DW_AT_TI_call
    
            LCR       #||LogBuffer_Init||   ; [CPU_ALU] |215| 
            ; call occurs [#||LogBuffer_Init||] ; [] |215| 
            MOVW      DP,#||localLogBuffer|| ; [CPU_ARAU] 
            MOVL      @||localLogBuffer||,XAR4 ; [CPU_ALU] |215| 
            MOVW      DP,#||localiAfeChannel||+2 ; [CPU_ARAU] 
    	.dwpsn	file "D:/gsrc/DebugLog.c",line 217,column 5,is_stmt,isa 0
            MOVL      @||localiAfeChannel||+2,XAR4 ; [CPU_ALU] |217| 
    	.dwpsn	file "D:/gsrc/DebugLog.c",line 218,column 5,is_stmt,isa 0
            MOVL      @||localSyslogChannel||+2,XAR4 ; [CPU_ALU] |218| 
    	.dwpsn	file "D:/gsrc/DebugLog.c",line 222,column 5,is_stmt,isa 0
    $C$DW$227	.dwtag  DW_TAG_TI_branch
    	.dwattr $C$DW$227, DW_AT_low_pc(0x00)
    	.dwattr $C$DW$227, DW_AT_name("iAfeLog_Init")
    	.dwattr $C$DW$227, DW_AT_TI_call
    
            LCR       #||iAfeLog_Init||     ; [CPU_ALU] |222| 
            ; call occurs [#||iAfeLog_Init||] ; [] |222| 
    	.dwpsn	file "D:/gsrc/DebugLog.c",line 224,column 5,is_stmt,isa 0
            MOV       AL,#1000              ; [CPU_ALU] |224| 
            MOVB      AH,#0                 ; [CPU_ALU] |224| 
            MOVL      XAR4,#||PrintDemoLines|| ; [CPU_ARAU] |224| 
    $C$DW$228	.dwtag  DW_TAG_TI_branch
    	.dwattr $C$DW$228, DW_AT_low_pc(0x00)
    	.dwattr $C$DW$228, DW_AT_name("Scheduler_AddTaskMs")
    	.dwattr $C$DW$228, DW_AT_TI_call
    
            LCR       #||Scheduler_AddTaskMs|| ; [CPU_ALU] |224| 
            ; call occurs [#||Scheduler_AddTaskMs||] ; [] |224| 
    $C$DW$229	.dwtag  DW_TAG_TI_branch
    	.dwattr $C$DW$229, DW_AT_low_pc(0x00)
    	.dwattr $C$DW$229, DW_AT_TI_return
    
            LRETR     ; [CPU_ALU] 
            ; return occurs ; [] 
    	.dwattr $C$DW$225, DW_AT_TI_end_file("D:/gsrc/DebugLog.c")
    	.dwattr $C$DW$225, DW_AT_TI_end_line(0xe2)
    	.dwattr $C$DW$225, DW_AT_TI_end_column(0x01)
    	.dwendentry
    	.dwendtag $C$DW$225

    Specific this part:

    That looks to be correct

    If I disassemble the obj file I see this

    DebugLog_Init:
       LCR          0x000000
    
       MOVW         DP, #0x0
    
       MOVL         @0x0, XAR4
       MOVW         DP, #0x0
    
       MOVL         @0x2, XAR4
       MOVL         @0x2, XAR4
       LCR          0x000000
    
       MOV          @AL, #0x03e8
    
       MOVB         AH, #0x0
       MOVL         XAR4, #0x000000
    
       LCR          0x000000
    
       LRETR     

    This des not look correct, but as it is just missing the symbols, I assume it's the disassembler, that throws away unresolved symbols

    Now if i run dis2000 on the out file I find the wrong assembler code

    DebugLog_Init:
       LCR          0x08f38c
    
       MOVW         DP, #0x468
    
       MOVL         @0x26, XAR4
       MOVW         DP, #0x5f4
    
       MOVL         @0x3c, XAR4
       MOVL         @0x4, XAR4
       LCR          0x08f949
    
       MOV          @AL, #0x03e8
    
       MOVB         AH, #0x0
       MOVL         XAR4, #0x08ccf2
    
       LCR          0x08ef95
    
       LRETR 

    NB: [OFF TOPIC} I still miss asm as an option when selecting language, when I inserted the above code samples.

  • Thank you for all the information.  Unfortunately, I need a bit more.  For the source file that contains the function DebugLog_Initplease follow the directions in the article How to Submit a Compiler Test Case.

    Thanks and regards,

    -George

  • Here is a zip with the pp file, and also the cmd file as I use some section directives in the code.

    I have made a clean demo project, showing the error, let me know if you like that sent to, and how.

    BTW. from the pattern, it looks like somewhere in the compiler code there is a mixup of hex and decimal. it looks like it inserts the new DP, when off set passes 0x64, and not 64...;-)

    Compiler_error_demo.zip

  • Unfortunately, you preprocessed the wrong file.  Please try again.  Be sure the source file sent contains the implementation of the function DebugLog_Init.

    Thanks and regards,

    -George

  • No I moved the lines that creates the problem into main, so there is no more a function named  DebugLog_Init.

  • I see some things that look wrong.  But I suspect I see a different problem from the one you first experienced.  Instead of working on what might be the wrong problem, I want be certain I am working on the right problem.  And for that, I need you to develop a test case based on the source file (not main.c) that contains the implementation of the function DebugLog_Init.  For that source file, please follow the directions in the article How to Submit a Compiler Test Case.

    Be sure to include all of the compiler options, exactly as the compiler sees them.  In an earlier post you show these options ...

    cl2000" --cmd_file="diagnostic_options.opt"  -v28 -ml -mt --cla_support=cla1 --float_support=fpu32 --tmu_support=tmu0 --vcu_support=vcu2 -O1 --fp_mode=relaxed  --obj_directory="Src" --cmd_file="syscfg/board.opt" --cmd_file="syscfg/device_cmd.opt" --cmd_file="syscfg/c2000ware_libraries.opt"  --define=FLASH_LAYOUT=LOW  -DLNK_TIME= "Main.c"

    But that does not show --abi=eabi, which sets the ABI (application binary interface).  The way data pages are handled is different between the older COFFABI and the newer EABI.  It is all but certain you use EABI, because C2000Ware ended support for COFFABI about 5-10 years ago.

    Thanks and regards,

    -George

  • And for that, I need you to develop a test case based on the source file (not main.c) that contains the implementation of the function DebugLog_Init.  For that source file, please follow the directions in the article How to Submit a Compiler Test Case.

    I did exactly develop a test case, where I removed all non relevant code, but where I still see the problem.

    I don't understand what the obsession on DebugLog_Init is about. But to not wat another time-zone rotation. I have moved the lines back into a function named DebugLog_Init, and even separated it to another file, as you for some reason don't want main.c.

    I made a makefile to build it, so you clearly can see all options, and yes the --abi option was missing in my first post, sorry about that, and yes we build to eabi.

    I packaged it all in  DP_bug_demo.zip DP_bug_demo.zip

    In DUT.zip is the pp file with the Debuglog_init function DUT.zip

    The maefile contain a disassembly step too

    When I look at the disassembly I see this:

    DebugLog_Init:
       MOV          @AL, #0x5a5a
    
       MOV          @AH, #0xa5a5
    
       MOVW         DP, #0x2c5
    
       MOVL         @0x2e, ACC
       MOVW         DP, #0x2c0
    
       MOVL         @0x24, ACC
       MOVL         @0x2c, ACC
       MOVL         @0x34, ACC
       NOP          
       MOVL         @0x3c, ACC
       MOVL         @0x4, ACC
       MOVL         @0xc, ACC
       MOVW         DP, #0x2c1
    
       MOVL         @0x1c, ACC
       MOVL         @0x24, ACC
       MOVL         @0x2c, ACC
       MOVL         @0x34, ACC
       NOP          
       MOVL         @0x3c, ACC
       MOVL         @0x4, ACC
       MOVL         @0xc, ACC
       MOVL         @0x14, ACC
       MOVW         DP, #0x2c2
    
       SPM          #0
       MOVL         @0x1c, ACC
       MOVL         @0x24, ACC
       MOVL         @0x2c, ACC
       MOVL         @0x34, ACC
       MOVL         @0x3c, ACC
       MOVL         @0x4, ACC
       MOVL         @0xc, ACC
       MOVL         @0x14, ACC
       MOVW         DP, #0x2c3
    

    It's clear that the update of DP happens too late.

    NB The NOP's I inserted as someone suggested it might help, but it made no difference.

    I tried with all levels of optimization, on several versions of the compiler, including the newest, all with same result.

  • Thank you for the test case.  I am able to reproduce the same result.  I filed the issue EXT_EP-13386 to have this investigated.  You are welcome to follow it with that link.

    I appreciate all the work you did to provide the test case.  That said, I am confident that meeting this request ....

    For the source file that contains the function DebugLog_Initplease follow the directions in the article How to Submit a Compiler Test Case.

    ... would require much less work.

    Thanks and regards,

    -George

  • Nice, thanks. I will follow it.

    But I will ask that in the meantime, if You find a workaround, or at least a way to detect(1) if we have this issue somewhere else in our code. That You will keep me updated.

    (1)Except manually checking all the assembler code ;-)

  • Martin,

    Please see workaround details in the Jira for tracking this issue:
          https://sir.ext.ti.com/jira/browse/EXT_EP-13386

    Regards,
    Greg

  • Thanks :-)