|
|
View previous topic :: View next topic |
Author |
Message |
zilog Guest
|
CCS compiler if-statement problem |
Posted: Thu Aug 09, 2007 4:11 pm |
|
|
I am having troubles with the last else if-statement which sometimes happens even when the condition is false!
The log from running this says:
ERROR, Chain_FUCommCheckResultTime occured in an impossible state
state->mainGroup: 2, state->secondGroup: 2, Chain_FULastCodeQueried: 51, CheckCommResultCache: 0
The code is attached below (snipped from its original context), anyone have any hints? I am having similar problems with other if-statements as well :/
Code: |
int1 ChainFUCommunicationRoutine(struct ChainFUControlParams *state, struct ChainFUStatusParams *status)
{
int1 bRetVal = TRUE;
int1 bStartTimer = FALSE;
unsigned int8 CheckCommResultCache;
CheckCommResultCache = Chain_FUCommCheckResultTime; //cache
//Send commands and requests
if ((state->mainGroup == 0) && !CheckCommResultCache) { //rpm -->
output_high(PIN_D1);
send_CommandToFU(2, (signed int32)(state->rpm));
output_low(PIN_D1);
state->mainGroup = 1;
Chain_FULastCodeQueried = 2;
bStartTimer = TRUE;
} else if (((state->mainGroup) == 2) && CheckCommResultCache) { //last command was one of the subgroups
state->mainGroup = 0;
bRetVal = FALSE; //two transactions in total have been made
if (Chain_FULastCodeQueried == 1) {
if (FUCommStatus != FU_ACK) {
Chain_FULastDir = 2; //trigger DIR transfer
printf(Maxputc, "didn't receive ACK for DIR command\n\r");
}
} else if (Chain_FULastCodeQueried == 210) {
if (FUCommStatus != FU_ACK) {
printf(Maxputc, "didnt receive ACK for V-Boost command\n\r");
Chain_FULastVBoost = 0xFFFF; //trigger new transmission of VBoost
}
} else if ((Chain_FULastCodeQueried == 55) && (FUCode != 55)) {
if (FUCommStatus != FU_ACK) { //this was write command
printf(Maxputc, "didn't receive ACK for ERROR reset command\n\r");
}
} else if ((Chain_FULastCodeQueried == 0) && (FUCode == 0)) {
if (FUCommStatus != FU_ACK) {
printf(Maxputc, "didn't receive ACK for MODE command\n\r");
}
} else {
switch (state->secondGroup) {
case 0: //last was secondGroup 3, Motor temperature
if ((FUCommStatus == FU_VAL) && (FUCode == 18)) {
status->MotorTemperature = (unsigned int16)FUValue;
status->MotorTemperature_Updated = TRUE;
} else
printf(Maxputc, "didn't receive a response for Motor temperature\n\r");
break;
case 1: //last was secondGroup 0, I_dclink
if ((FUCommStatus == FU_VAL) && (FUCode == 16)) {
status->ILink = (unsigned int16)FUValue;
status->ILink_Updated = TRUE;
} else
printf(Maxputc, "didn't receive a response for I_dclink\n\r");
break;
case 2: //last was secondGroup 1, status word
if ((FUCommStatus == FU_VAL) && (FUCode == 51)) {
status->StatusWord = (unsigned int16)FUValue;
status->StatusWord_Updated = TRUE;
} else
printf(Maxputc, "didn't receive a response for status word\n\r");
break;
case 3: //last was secondGroup 2, error code
default:
if ((FUCommStatus == FU_VAL) && (FUCode == 55)) {
status->Error = (unsigned int8)FUValue;
status->Error_Updated = TRUE;
} else
printf(Maxputc, "didn't receive a response for error code\n\r");
break;
}
}
} else if (((state->mainGroup) == 1) && CheckCommResultCache) {
//last command was rpm, send a new command from one of the subgroups. Must be here because of the timer.
if ((Chain_FULastCodeQueried == 2) && (FUCommStatus != FU_ACK))
printf(Maxputc, "didn't receive ACK for RPM command\n\r");
state->mainGroup = 2; //must transfer rpm in every second call
//we have been told to reset this register
if (state->doResetErrorCode) {
state->doResetErrorCode = FALSE;
Chain_FULastCodeQueried = 55;
send_CommandToFU(55, 0);
//we have been told to write mode again
} else if (state->doRewriteMode) {
state->doRewriteMode = FALSE;
Chain_FULastCodeQueried = 0;
if (state->dir == 1)
send_CommandToFU(0, 3);
else
send_CommandToFU(0, 5);
//update V-Boost
} else if (Chain_FULastVBoost != state->vBoost) {
Chain_FULastVBoost = state->vBoost;
Chain_FULastCodeQueried = 210;
send_CommandToFU(210, (signed int32)(state->vBoost));
//check if DIR has changed, if so, higher priority
} else if (Chain_FULastDir != state->dir) {
Chain_FULastDir = state->dir;
Chain_FULastCodeQueried = 1;
send_CommandToFU(1, (signed int32)(state->dir));
} else { //continue with the rest in round robin fashion
switch (state->secondGroup) {
case 0: //I_dclink <send_EnquiryToFU>secondGroup = 1;
break;
case 1: //Status word <send_EnquiryToFU>secondGroup = 2;
break;
case 2: //Error code <send_EnquiryToFU>secondGroup = 3;
break;
case 3: //Motor temperature <default>secondGroup = 0;
break;
}
}
bStartTimer = TRUE;
} else if (CheckCommResultCache) {
printf(Maxputc, "ERROR, Chain_FUCommCheckResultTime occured in an impossible state\n\r");
printf(Maxputc, "state->mainGroup: %u, state->secondGroup: %u, Chain_FULastCodeQueried: %Lu, CheckCommResultCache: %u\n\r", state->mainGroup, state->secondGroup, Chain_FULastCodeQueried, CheckCommResultCache);
}
if (bStartTimer) {
disable_interrupts(INT_TIMER1);
Chain_FUCommCheckResultTime = FALSE;
Chain_FUCommCheckResultCnt = 40; //20ms
Chain_FUCommCheckResultCntGo = TRUE;
enable_interrupts(INT_TIMER1);
}
return bRetVal;
}
|
|
|
|
zilog Guest
|
|
Posted: Thu Aug 09, 2007 4:18 pm |
|
|
To clarify my previous post, what I mean is the
" } else if (CheckCommResultCache) { " statement |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 09, 2007 4:33 pm |
|
|
Quote: |
The log from running this says:
ERROR, Chain_FUCommCheckResultTime occured in an impossible state
state->mainGroup: 2, state->secondGroup: 2, Chain_FULastCodeQueried: 51, CheckCommResultCache: 0 |
Is this being run in Proteus ? |
|
|
Guest
|
|
Posted: Thu Aug 09, 2007 5:04 pm |
|
|
PCM programmer wrote: | Quote: |
The log from running this says:
ERROR, Chain_FUCommCheckResultTime occured in an impossible state
state->mainGroup: 2, state->secondGroup: 2, Chain_FULastCodeQueried: 51, CheckCommResultCache: 0 |
Is this being run in Proteus ? |
No.
The log was taken using an ordinary terminal program. |
|
|
Ttelmah Guest
|
|
Posted: Fri Aug 10, 2007 2:55 am |
|
|
Comment one. Try disabling the interrupts, before your test. You obviously have a timer interrupt running, that is changing some of these values, is it possible that this is clearing or modifying the value between the test, and the printf?.
Second comment, try explicit 'bracketting' and value testing. So something like:
Code: |
} else {
disable_interrupts(int_timer1);
if (CheckCommResultCache!=0) {
printf(Maxputc, "ERROR, Chain_FUCommCheckResultTime occured in an impossible state\n\r");
printf(Maxputc, "state->mainGroup: %u, state->secondGroup: %u, Chain_FULastCodeQueried: %Lu, CheckCommResultCache: %u\n\r", state->mainGroup, state->secondGroup, Chain_FULastCodeQueried, CheckCommResultCache);
}
}
|
I have seen a couple of oddities in older compiler versions, where the zero flag gets incorrectly carried forward, giving unexpected results, unless one explicitly tests like this.
Best Wishes |
|
|
zilog Guest
|
|
Posted: Fri Aug 10, 2007 11:08 am |
|
|
I have tried adding {} to everything, also testing with statements like "if (a != 0)" etc, but the same problem remains.
I have also spottet another problem - function calls randomly return erroneous values (more than one function). I have debugged that inside the functions the values are as they should, but when the callee gets the return value, it sometimes is all scrambled - like if something else writes over the memory location where the return value is placed.
What should I do? The entire project is at stake if I cant get this problem resolved shortly. |
|
|
kevcon
Joined: 21 Feb 2007 Posts: 142 Location: Michigan, USA
|
|
Posted: Fri Aug 10, 2007 11:36 am |
|
|
what version compiler are you using? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 10, 2007 11:39 am |
|
|
Post your #fuses statement(s). |
|
|
zilog Guest
|
|
Posted: Fri Aug 10, 2007 12:12 pm |
|
|
I have tested to shut down interrupts during all this block of if-statements and function calls. Still borks.
Maybe the if statement is not the problem, but there *are* occational (weird) error in function value return.
PCWH 4.049, also tried going back to 4.039
Code: | #fuses H4_SW, NOWDT, STVREN, NOXINST |
Using 10MHz xtal, PLL x4.
Tried optimization levels 0, 9 and 11.
PIC18F66J15.
Stable 2,5V VDD and clock verified. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 10, 2007 12:32 pm |
|
|
Try running it without the PLL, and run it at 10 MHz. |
|
|
Ttelmah Guest
|
|
Posted: Fri Aug 10, 2007 12:48 pm |
|
|
If it still fails without the PLL (on some chips, there are odd behaviours if the crystal is slightly overdriven, when the PLL is used), then I'd be suspicious of a memory 'leak'. Perhaps, using pointers somewhere, and talking beyond the size of the addressed value. The chip has no memory controller, and no protection at all for this. Have you checked on the list file, the stack size?.
Best Wishes |
|
|
zilog Guest
|
|
Posted: Fri Aug 10, 2007 1:07 pm |
|
|
Tried without the PLL, also tried with 8MHz xtal + PLL, even tried varying voltage up and down, still we find the same error. |
|
|
zilog Guest
|
|
Posted: Fri Aug 10, 2007 3:11 pm |
|
|
Ttelmah, could you elaborate on when xtal is overdriven, in conjunction with the PLL?
We have changed the xtal to another type, no change, but maybe Iĺl try a series resistor to lower the drive level.
We have checked what we could think of could overwrite anytning.
It may be noted also, that it sometimes reboots, (but much more seldom than the other problems occours) but what causes it we have not tracked down. |
|
|
Ttelmah Guest
|
|
Posted: Sat Aug 11, 2007 2:26 am |
|
|
This varies between PICs, and especially between chip batches. On the earliest PICs with the PLL, it was a common problem. Basically, oscillators that ran fine without the PLL, when the PLL was enabled, sometimes gave very 'odd' behaviours, with the chip giving random errors. Adding a series resistor, solved the behaviour, and was a common fix.
However if your code shows the same problem, with the PLL disabled, then this is not your problem. I still would put my money on a memory 'leak'. My guess is that a function somewhere is overwriting part of the compiler's scratch memory.
Best Wishes |
|
|
zilog Guest
|
|
Posted: Sat Aug 11, 2007 5:40 am |
|
|
Thank you Ttelmah
Unfortunately without the PLL the program is running too slow to execute normally, as during normal execution it need to continously communicate with two other processors. So the test result from running without PLL is unusable, sorry i was wrong to state that before.
We will innvestigate both adding a resistor, and check memory usage.
But shoulnt a decent compiler check memory usage itself?
How can we tell where the compiler scatch memory is located? |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|