CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

CCS compiler if-statement problem
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
zilog
Guest







CCS compiler if-statement problem
PostPosted: Thu Aug 09, 2007 4:11 pm     Reply with quote

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







PostPosted: Thu Aug 09, 2007 4:18 pm     Reply with quote

To clarify my previous post, what I mean is the

" } else if (CheckCommResultCache) { " statement
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 09, 2007 4:33 pm     Reply with quote

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








PostPosted: Thu Aug 09, 2007 5:04 pm     Reply with quote

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







PostPosted: Fri Aug 10, 2007 2:55 am     Reply with quote

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







PostPosted: Fri Aug 10, 2007 11:08 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 10, 2007 11:36 am     Reply with quote

what version compiler are you using?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 10, 2007 11:39 am     Reply with quote

Post your #fuses statement(s).
zilog
Guest







PostPosted: Fri Aug 10, 2007 12:12 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 10, 2007 12:32 pm     Reply with quote

Try running it without the PLL, and run it at 10 MHz.
Ttelmah
Guest







PostPosted: Fri Aug 10, 2007 12:48 pm     Reply with quote

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







PostPosted: Fri Aug 10, 2007 1:07 pm     Reply with quote

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







PostPosted: Fri Aug 10, 2007 3:11 pm     Reply with quote

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







PostPosted: Sat Aug 11, 2007 2:26 am     Reply with quote

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







PostPosted: Sat Aug 11, 2007 5:40 am     Reply with quote

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?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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