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.
We have an issue while compiling a code for a piccolo MCU (F28035) with
the last version of the compiler (v6.1.3).
We have a function starting this way (messagetype is a 69 words structure):
void RS_HeartBeat(Uint16* data, Uint16 ndata)
{
struct messagetype message;
Uint32* codechecksumpt;
int i;
message.id = 250;
...
}
When looking at the assembly, we have the following instructions:
MOVB AL,#0 ; [CPU_] |1185|
SUBB FP,#4 ; [CPU_U]
MOVL XAR5,XAR4 ; [CPU_] |1179|
MOVB *+FP[5],#250,UNC ; [CPU_] |1183|
ADDB SP,#70 ; [CPU_U]
We notice that the assignment "message.id = 250;" is done before the
change of the stack pointer.
It happens that an interrupt occurs between
MOVB *+FP[5],#250,UNC ; [CPU_] |1183|
and
ADDB SP,#70 ; [CPU_U]
In this case, the value of 250 is lost.
We have this issue with those compilation options:
-v28 -ml -mt -O2 --symdebug:none
--include_path="C:/ti/ccsv5/tools/compiler/c2000_6.1.3/include" --gcc
--diag_warning=225 --display_error_number --diag_suppress=9
--issue_remarks --optimizer_interlist --single_inline
--remove_hooks_when_inlining --opt_for_speed=5 -k --c_src_interlist
Is this behaviour normal? What should we do to prevent that kind of issues?
I'm not a C2000 expert, but that does look like a bug. I'm not able to reproduce the problem from the test case given; I would need to see the complete body of RS_HeartBeat, as well as the type definitions that it uses.
Thank you for your reply:
I did a simplified RS_HeartBeat function which also presents the issue.
Definition of the structure:
#define MAX_DLENGTH 64 /**< max number of data words in a message*/
/// The message type structure.
struct messagetype {
int16 id; ///< message identifier
int16 sid; ///< serialization identifier
int16 dlength; ///< number of data bytes
Uint16 time_lastsent; ///<time message sent in ms
Uint16 sentcounter; ///<number of times message has been sent
Uint16 data[MAX_DLENGTH]; ///<actual message data if any
};
Simplified function in C
void RS_HeartBeat2(Uint16* data, Uint16 ndata)
{
struct messagetype message;
int i;
message.id = 250;
if (RS_Lock) {
message.sid = 1;
} else {
message.sid = 0;
}
message.dlength = 2+ndata;
//OK it's not nice but since the programmed checksum is not known at compile time
//the optimizer replaces the value of codechecksum (a constant) and we end up with a bad value
//this is why this is needed
for (i=0;(i<ndata)&&(i<MAX_DLENGTH-2);i++){
message.data[i+2]=data[i];
}
}
Corresponding ASM
.sect ".text"
.global _RS_HeartBeat2
;----------------------------------------------------------------------
; 1204 | void RS_HeartBeat2(Uint16* data, Uint16 ndata)
;----------------------------------------------------------------------
;***************************************************************
;* FNAME: _RS_HeartBeat2 FR SIZE: 72 *
;* *
;* FUNCTION ENVIRONMENT *
;* *
;* FUNCTION PROPERTIES *
;* 0 Parameter, 69 Auto, 2 SOE *
;***************************************************************
_RS_HeartBeat2:
;** 1208 ----------------------- message.id = 250;
;** 1211 ----------------------- message.sid = RS_Lock != 0u;
;** 1215 ----------------------- message.dlength = ndata+2u;
;** 1219 ----------------------- if ( !ndata ) goto g5;
MOVL *SP++,XAR2 ; [CPU_]
MOVZ AR2,SP ; [CPU_]
MOVW DP,#_RS_Lock ; [CPU_U]
MOVB XAR5,#0 ; [CPU_]
SUBB FP,#4 ; [CPU_U]
;----------------------------------------------------------------------
; 1206 | struct messagetype message;
; 1207 | int i;
;----------------------------------------------------------------------
MOVL XT,XAR4 ; [CPU_] |1205|
;----------------------------------------------------------------------
; 1208 | message.id = 250; //
; 1209 | // codechecksumpt = (Uint32*) &(codeinfo.code_checksum);
; 1210 | if (RS_Lock) {
;----------------------------------------------------------------------
MOVB *+FP[5],#250,UNC ; [CPU_] |1208|
;----------------------------------------------------------------------
; 1211 | message.sid = 1;
; 1212 | } else {
; 1213 | message.sid = 0;
;----------------------------------------------------------------------
MOV AH,@_RS_Lock ; [CPU_] |1211|
ADDB SP,#70 ; [CPU_U]
MOVB XAR5,#1,NEQ ; [CPU_] |1211|
;----------------------------------------------------------------------
; 1215 | message.dlength = 2+ndata;
; 1216 | //OK it's not nice but since the programmed checksum is not known at co
; | mpile time
; 1217 | //the optimizer replaces the value of codechecksum (a constant) and we
; | end up with a bad value
; 1218 | //this is why this is needed
;----------------------------------------------------------------------
MOVB AH,#2 ; [CPU_] |1215|
ADD AH,AL ; [CPU_] |1215|
MOV *+FP[6],AR5 ; [CPU_] |1211|
;----------------------------------------------------------------------
; 1219 | for (i=0;(i<ndata)&&(i<MAX_DLENGTH-2);i++){
;----------------------------------------------------------------------
CMPB AL,#0 ; [CPU_] |1219|
MOV *+FP[7],AH ; [CPU_] |1215|
BF $C$L266,EQ ; [CPU_] |1219|
; branchcc occurs ; [] |1219|
;*** ----------------------- #pragma MUST_ITERATE(1, 65535, 1)
;*** ----------------------- #pragma LOOP_FLAGS(256u)
;*** ----------------------- L$1 = (int)ndata-1;
;** 1219 ----------------------- i = 0;
ADDB AL,#-1 ; [CPU_]
SETC SXM ; [CPU_]
MOV PL,#0 ; [CPU_] |1219|
MOVZ AR6,AL ; [CPU_]
$C$L265:
;*** -----------------------g3:
;** 1219 ----------------------- if ( i >= 62 ) goto g5;
MOV AL,PL ; [CPU_]
CMPB AL,#62 ; [CPU_] |1219|
BF $C$L266,GEQ ; [CPU_] |1219|
; branchcc occurs ; [] |1219|
;** 1220 ----------------------- *((long)(i+2)+5L+&message) = data[i];
;** 1219 ----------------------- ++i;
;** 1219 ----------------------- if ( (L$1 = L$1-1) != (-1) ) goto g3;
;*** -----------------------g5:
;*** ----------------------- return;
;----------------------------------------------------------------------
; 1220 | message.data[i+2]=data[i];
;----------------------------------------------------------------------
MOVZ AR4,SP ; [CPU_U] |1220|
MOV ACC,AL ; [CPU_] |1220|
MOVL XAR7,XT ; [CPU_] |1220|
SUBB XAR4,#69 ; [CPU_U] |1220|
ADDL XAR7,ACC ; [CPU_]
MOVB AL,#2 ; [CPU_] |1220|
ADD AL,PL ; [CPU_] |1220|
MOV ACC,AL ; [CPU_] |1220|
ADDB ACC,#5 ; [CPU_] |1220|
ADDL XAR4,ACC ; [CPU_]
MOV AL,PL ; [CPU_]
PREAD *+XAR4[0],*XAR7 ; [CPU_] |1220|
ADDB AL,#1 ; [CPU_] |1219|
MOV PL,AL ; [CPU_] |1219|
BANZ $C$L265,AR6-- ; [CPU_] |1219|
; branchcc occurs ; [] |1219|
$C$L266:
SUBB SP,#70 ; [CPU_U]
MOVL XAR2,*--SP ; [CPU_]
LRETR ; [CPU_]
; return occurs ; []
Thank you, now I can reproduce the problem. I've submitted SDSCM00046991 to track this issue.