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

Function returns to the wrong place....

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Twain
Guest







Function returns to the wrong place....
PostPosted: Thu Aug 23, 2007 10:33 am     Reply with quote

Hello

I've the following situation in a programm for the PIC18F87J10:


int function_a(void)
{
...;
...;
} // End function_a


int function_b(void)
{
int b;
b=function_a();
} // End function_b


int function_c(void)
{
int c;
c=function_a();
} // End function_c


void Main(void)
{
int blabla, blublu;
if(...)
blabla=function_b();
else
blublu=function_c();
} // End main

to
The problem now is, that the subcall to function_a in function_c returns to function_b where it is also called! Why?

Thanks!
Urs
Twain
Guest







PostPosted: Thu Aug 23, 2007 10:36 am     Reply with quote

Forgot to mention my lst files shows these numbers:

CCS PCH C Compiler, Version 4.053, 39879 23-Aug-07 17:48

Filename: C:\Test 1WB Driver CCS\Test APP - Find Type\1WBTest.lst

ROM used: 12886 bytes (10%)
Largest free fragment is 65528
RAM used: 830 (22%) at main() level
893 (23%) worst case
Stack: 11 worst case (9 in main + 2 for interrupts)
zilog



Joined: 17 Aug 2007
Posts: 19

View user's profile Send private message

PostPosted: Thu Aug 23, 2007 11:18 am     Reply with quote

We suspect a similar problem with our code - could you please post your code, LST and SYM files, either here or to gnuffelREMOVE (at) gmail.com ? (unspam the adress)

/Daniel
Ttelmah
Guest







PostPosted: Thu Aug 23, 2007 2:09 pm     Reply with quote

Does it actually call function_a first?. As shown, since you do nothing with the values, and variables can be 'reused' in other functions, you can just generate 'function_c', by jumping to 'function_b'. The optimiser will know the code is the same, and just do this.

Best Wishes
Twain
Guest







PostPosted: Fri Aug 24, 2007 12:49 am     Reply with quote

Function_c and function_c do completely differ one from each other.

The example code is simplified for display purpose. In real the code is much more complex. Function_c is called sometimes before function_c but not always. This happens depending on the decission path in the code.

So the behavior makes no sense at all, am I right?
Twain
Guest







PostPosted: Fri Aug 24, 2007 12:59 am     Reply with quote

"Function_a":

int owBlock(int portnum, int do_reset, unsigned char *tran_buf, int tran_len)
{
static unsigned char sendpacket_owBlock[150];
int sendlen_owBlock=0;
int place=0;
int i_owBlock=0;

sendlen_owBlock=0;
// check for a block too big
if (tran_len > 64)
return FALSE;

// check if need to do a owTouchReset first
if (do_reset)
{
if (!owTouchReset(portnum))
return FALSE;
}

// construct the packet to send to the DS2480
// check if correct mode
if (UMode[portnum] != MODSEL_DATA)
{
UMode[portnum] = MODSEL_DATA;
sendpacket_owBlock[sendlen_owBlock++] = MODE_DATA;
}

// add the bytes to send
place = sendlen_owBlock;
for (i_owBlock = 0; i_owBlock < tran_len; i_owBlock++)
{
sendpacket_owBlock[sendlen_owBlock++] = tran_buf[i_owBlock];

// check for duplication of data that looks like COMMAND mode
if (tran_buf[i_owBlock] == MODE_COMMAND)
sendpacket_owBlock[sendlen_owBlock++] = tran_buf[i_owBlock];
}

// flush the buffers
FlushCOM(portnum);

// send the packet
if (WriteCOM(portnum,sendlen_owBlock,sendpacket_owBlock))
{
// read back the response
if (ReadCOM(portnum,tran_len,tran_buf) == tran_len)
return TRUE;
}

// an error occured so re-sync with DS2480
DS2480Detect(portnum);

return FALSE;
}

"Function_b":

int owAccess(int portnum)
{

static unsigned char sendpacket_owAccess[9];

int i_owAccess;

// reset the 1-wire
if (owTouchReset(portnum))
{
// create a buffer to use with block function
// match Serial Number command 0x55
sendpacket_owAccess[0] = 0x55;
// Serial Number
for (i_owAccess = 1; i_owAccess < 9; i_owAccess++)
sendpacket_owAccess[i_owAccess] = SerialNum[portnum][i_owAccess-1];

// send/receive the transfer buffer
if (owBlock(portnum,FALSE,sendpacket_owAccess,9))
{
// verify that the echo of the writes was correct
for (i_owAccess = 1; i_owAccess < 9; i_owAccess++)
if (sendpacket_owAccess[i_owAccess] != SerialNum[portnum][i_owAccess-1])
return FALSE;
if (sendpacket_owAccess[0] != 0x55)
return FALSE;
else
return TRUE;
}
}

// reset or match echo failed
return FALSE;
}

"Function_c"

int owOverdriveAccess(int portnum)
{
static unsigned char sendpacket_ODA[8];
int i_ODA;
int bad_echo = FALSE;

// make sure normal level
owLevel(portnum,MODE_NORMAL);

// force to normal communication speed
owSpeed(portnum,MODE_NORMAL);

// call the 1-Wire Net reset function
if (owTouchReset(portnum))
{
// send the match command 0x69
if (owWriteByte(portnum,0x69))
{
// switch to overdrive communication speed
owSpeed(portnum,MODE_OVERDRIVE);

// create a buffer to use with block function
// Serial Number
for (i_ODA = 0; i_ODA < 8; i_ODA++)
sendpacket_ODA[i_ODA] = SerialNum[portnum][i_ODA];

// send/receive the transfer buffer
if (owBlock(portnum,FALSE,sendpacket_ODA,8))
{
// verify that the echo of the writes was correct
for (i_ODA = 0; i_ODA < 8; i_ODA++)
if (sendpacket_ODA[i_ODA] != SerialNum[portnum][i_ODA])
bad_echo = TRUE;
// if echo ok then success
if (!bad_echo)
return TRUE;
}
}
}

// failure, force back to normal communication speed
owSpeed(portnum,MODE_NORMAL);

return FALSE;
}

The "danger-zone" is the function call to owBlock(). in owOverdriveAccess. After processing owBlock jumps back to the owAccess function. This only happens to owBlock, the functions before which are also called in b and c are not affected.
[/b]
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 24, 2007 1:00 am     Reply with quote

Since there seems to be some question about the J-series, either with
the chip or the compiler, I suggest that people who have problems with
it should test their code on a "non J-series" PIC chip. Re-compile for
the new chip and see if you still have the problems.
Twain
Guest







PostPosted: Fri Aug 24, 2007 1:21 am     Reply with quote

Recompiling sounds good but unfortunately i don't have the proper hardware for that. I have a demoboard with a 18F8722 but without the necessary peripherals (1-wire bus transceiver and 1-wire bus net).
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 24, 2007 2:24 am     Reply with quote

The 18F87J10 and 18F8722 have nearly the same pinout. There are a
few differences. It may not matter if you're not using those pins.

Ideally you would use an 18F87J10 board without the PIC installed,
and then solder some short jumper wires over to the 18F8722 board
to connect the 1-wire chips to the 18F8722 (and power and ground as
well).
Twain
Guest







PostPosted: Fri Aug 24, 2007 8:36 am     Reply with quote

I tested the 1-wire circuitry together with the 8722 demoboard. I found the exact same behavior as found in the original 87J10 design.
Twain
Guest







PostPosted: Fri Aug 24, 2007 9:20 am     Reply with quote

I tested some further measures and have now the feeling that everything is as it should be. I obviously put the debug cursor at a position within owBlock where the program counter went not to in the current owBlock call from owOverdriveAccess but in the next done from owAccess.

Shame on me...

Thanks for your inputs anyway.
Ttelmah
Guest







PostPosted: Fri Aug 24, 2007 9:58 am     Reply with quote

One question.
Are you using the external memory bus?.
There is a hardware erratum, on these chips, when using the tblrd instruction, with the external memory bus, with wait states enabled, that can result in the stack being incremented, which _will_ give a return to the wrong location...

Best Wishes
Twain
Guest







PostPosted: Fri Aug 24, 2007 10:40 am     Reply with quote

I use the external memory bus indeed. But with no wait states.

Thanks anyway for this useful input.
Ttelmah
Guest







PostPosted: Fri Aug 24, 2007 12:18 pm     Reply with quote

I'd double check that the bits controlling the wait states, are being configured correctly, or try setting them deliberately to the faulty state!. I have known the erratas to be 'wrong', and the behaviour is suspiciously like what is being described.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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