Hi,
I have a problem with C2000 compiler, v6.4.x (tested with versions 6.4.4 and 6.4.6): the compiler issues the following error:
error: "src/ec1_lib_fwu_vrs00654/mcan/mcan_remote.c", line 113: Illegal use of intrinsic: __byte
The same project can be compiled with C2000 compiler v5.2.15 without problems.
It seems to me, that the problem is in compiler, because the problem is gone, when I comment out the line #122, but stays when I comment out the line #123 (notice, that both lines are far away from line #113 and they differ only in constants). The failure occures when -O2 (or higher) optimization is used, when -00 or -O1 is used, the code compiles correctly. I have been able to reproduce the problem on a different PC. Also, when I replace the body of function mcanRemoteFlagA() by { return 0; }, the code can be compiled.
My code look like this (with line numbers):
110
111 SETBYTE((void *) pBuffer, 0, (I16) GETBYTE((void *) aAuxBuffer, 0)); // FlagA1.Lo
112
113 nRemoteIdentStringAddr = ((U32) GETBYTE((void *) aAuxBuffer, 4) << 24u) | ((U32) GETBYTE((void *) aAuxBuffer, 3) << 16u) | ((U32) GETBYTE((void *) aAuxBuffer, 2) << 8u) | (U32) GETBYTE((void *) aAuxBuffer, 1);
114
115 // check whether remote node supports extended configuration (FlagA2):
116 if(tRemoteFlagA1.bit.fExtConfig == 1u)
117 {
118 if(mcanRemoteFlagA(nRemoteNodeNum, aAuxBuffer) == 0)
119 {
120 tRemoteFlagA2.all = 0u; // used to silence the compiler, which incorrectly thinks, that tRemoteFlagA2.all is used before setting its value at following two lines
121
122 SETBYTE((void *) &tRemoteFlagA2.all, 0, GETBYTE((void *) aAuxBuffer, 1));
123 SETBYTE((void *) &tRemoteFlagA2.all, 1, GETBYTE((void *) aAuxBuffer, 2));
124
125 retVal = LEN_IDENT_EX;
126 }
127 else
128 {
129 retVal = -1;
130 }
131
132 SETBYTE((void *) pBuffer, 1, (I16) GETBYTE((void *) aAuxBuffer, 1));
133 SETBYTE((void *) pBuffer, 2, (I16) GETBYTE((void *) aAuxBuffer, 2));
134 }
135 else
136 {
137 tRemoteFlagA2.all = 0;
138
139 retVal = LEN_IDENT;
140 }
The same code after preprocessing looks like this:
__byte(((void *) pBuffer), (0)) = ((I16) __byte(((void *) aAuxBuffer), (0))); // FlagA1.Lo
nRemoteIdentStringAddr = ((U32) __byte(((void *) aAuxBuffer), (4)) << 24u) | ((U32) __byte(((void *) aAuxBuffer), (3)) << 16u) | ((U32) __byte(((void *) aAuxBuffer), (2)) << 8u) | (U32) __byte(((void *) aAuxBuffer), (1));
// check whether remote node supports extended configuration (FlagA2):
if(tRemoteFlagA1.bit.fExtConfig == 1u)
{
if(mcanRemoteFlagA(nRemoteNodeNum, aAuxBuffer) == 0)
{
tRemoteFlagA2.all = 0u; // used to silence the compiler, which incorrectly thinks, that tRemoteFlagA2.all is used before setting its value at following two lines
__byte(((void *) &tRemoteFlagA2 . all), (0)) = (__byte(((void *) aAuxBuffer), (1)));
__byte(((void *) &tRemoteFlagA2 . all), (1)) = (__byte(((void *) aAuxBuffer), (2)));
retVal = 64;
}
else
{
retVal = -1;
}
__byte(((void *) pBuffer), (1)) = ((I16) __byte(((void *) aAuxBuffer), (1)));
__byte(((void *) pBuffer), (2)) = ((I16) __byte(((void *) aAuxBuffer), (2)));
}
else
{
tRemoteFlagA2.all = 0;
retVal = 20;
}
typedef unsigned int U16; /**< Unsigned, 16-bits wide number */
/**
* @brief Bit-field containing FlagA2 bits.
*/
typedef struct
{
U16 fMapCommand : 1;
U16 fCPU28xx : 1;
U16 fReserved02 : 1;
U16 fExtIdent : 1;
U16 fParType : 1;
U16 fFlagA3Supported : 1;
U16 fMultiNodeLoading : 1;
U16 fIdentMessage : 1;
U16 fReserved08 : 1;
U16 fReserved09 : 1;
U16 fReserved10 : 1;
U16 fReserved11 : 1;
U16 fReserved12 : 1;
U16 fReserved13 : 1;
U16 fReserved14 : 1;
U16 fReserved15 : 1;
} T_X_FLAGA2;
/**
* Union for FlagA2
*/
typedef union
{
T_X_FLAGA2 bit; /**< This allows accessing individual bits of FlagA2 */
U16 all; /**< This allows manipulation with whole FlagA2 */
} T_FLAGA2;
static U16 aAuxBuffer[5];
Any idea what is wrong?
Thanks,
Jan