View previous topic :: View next topic |
Author |
Message |
user_1066
Joined: 10 Feb 2017 Posts: 6
|
Issue passing parameters to a function |
Posted: Fri Feb 10, 2017 4:44 am |
|
|
Hi
I've stumbled across an issue that I've not been able to get to the bottom off.
i'm calling a function declared as
Code: |
void function (int8 var1, int8 var2 , int8 var3, int8 var4, int16 var5);
|
from some calls to this function , var5 value has the same as var4's value ??
If I then place an intermediate function which then calls this function, things work fine.
Code: |
void function2 (int8 var1, int8 var2 , int8 var3, int8 var4, int16 var5)
{
function (var1, var2 , var3, var4, var5);
}
|
I've tried various combinations of #separate, the stack it not exhausted, there is still plenty of space in RAM and ROM.
Any help would be appreciated.
Many Thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Fri Feb 10, 2017 5:01 am |
|
|
The PIC (12, 16 & 18), does not have a stack for variables. So amount of stack doesn't matter at all.
What compiler version?. Always important for a problem like this. Some old versions did have problems with a lot of variables.
Can you post a small program showing the problem?.
Honestly 'some calls', suggests the problem may be a fault in the code doing the calling. Something silly like not realising that a local variable is not 'static', so may get changed between calls. |
|
|
user_1066
Joined: 10 Feb 2017 Posts: 6
|
|
Posted: Fri Feb 10, 2017 5:35 am |
|
|
Hi
I guess letting you know which compiler and hardware might have been useful.
I'm using PCD 5.068, the latest i think, but have also tried on 5.064.
The chip is a dsPIC33EP512MC806.
I've tried on another board to eliminate the hardware as the problem.
From what I can tell its a call-depth issue? I tried things like assigned new variables and calling the function with them.
The function is called from about 30 different places, and from what I can tell, its just this one particular call that's failing.
I've checked the scope of the variables, i'm passing no static vars, just parameters that are either returned from other functions or has been passed to it.
Code: |
void generic_data_changed_default( p_generic_def_t defn, generic_data_struct_t* data, int16 new_val )
{
if ( defn->dest_node_type == 5 ) {
return;
}
unsigned int8 node = getNodeForGenericDef( defn );
unsigned int8 ch = defn->channel;
send_cal_change_any( node, ch, defn->send_cmd, defn->format, new_val );
}
void send_cal_change_any(unsigned int8 to, unsigned int8 ch, unsigned int8 cmd, unsigned int8 format, int16 val)
{
// Code deleted, but "val" is now the same as format
}
|
Above is a code snippet that exhibits the problem. the send_cal_change_any () is in another source code file.
There are no compiler warnings in the code.
Thanks for any help |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Fri Feb 10, 2017 7:57 am |
|
|
Now, normally a stack overflow on a DsPIC, will cause an overflow interrupt, and if there isn't a handler for this, a reset. However if you have settings that disable this, then you could be getting such an overflow unseen. Have you expanded the stack?. Most reasonable sized code needs to (#build stack=512 would be typical). The stack is used for variables on the DsPIC.
Are their any interrupts in use?. |
|
|
user_1066
Joined: 10 Feb 2017 Posts: 6
|
|
Posted: Fri Feb 10, 2017 9:29 am |
|
|
Yes interrupts are being used, the failure happens 100% time from that call. If it happened only sometimes i would suspect interrupts.
The stack size is currently set to 0x300, but I did increase to 0x400 and still no luck. The stack overflow reset is not disabled so I would expect a reset on overflow.
I've got around the issue by leaving in the intermediate call, but i'm not sure if something else has been affected !! |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1342
|
|
Posted: Fri Feb 10, 2017 9:46 am |
|
|
When things like this happen and are consistent, I tend to look for variable overrun/overflow (as opposed to stack). I would take a look at variables that CCS places next to that parameter in memory and see how you are using them. If one is a pointer or an array, you can sometimes accidentally mishandle them (or the compiler can have a bug) which results in data spilling over into that parameter. Those type can sometimes be more consistent.
As an example, my coworker had a bug where a for loop that was supposed to go like 50 times was exiting out early at 12 times (no IF's, breaks, etc. in the loop). Come to find out he was overindexing an array which was placed in memory right next to his loop control variable. On the twelfth iteration it wrote a value that made the loop condition terminate the loop.
Variable placement locations are located in the SYM file. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Fri Feb 10, 2017 10:20 am |
|
|
As a comment to this, I note that variable 4, is dereferenced from a pointer. Try just explicitly dereferencing this single value before the call (so transfer it into a temporary variable). |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Fri Feb 10, 2017 10:30 am |
|
|
Ttelmah wrote: | As a comment to this, I note that variable 4, is dereferenced from a pointer. Try just explicitly dereferencing this single value before the call (so transfer it into a temporary variable). |
I seem to recall quite some time ago that some 5.something compiler versions had issues properly dealing with sizes of pointers and sizes of variables pointed to by pointers. |
|
|
user_1066
Joined: 10 Feb 2017 Posts: 6
|
|
Posted: Fri Feb 10, 2017 10:35 am |
|
|
mmm, that fixed it,
That item "format" in the struct is a unsigned int8, and i did try casting it before passing it over.
Could it be the way the struct is packed? I normally work on intel / arm, so I would use #pragma pack(1) to ensure that the structure is packed to byte boundry if I needed it. I'm guessing that the ccs compiler packs it to 16bit ?
Thanks for your help
Have a good weekend |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Feb 10, 2017 12:21 pm |
|
|
user_1066 wrote: |
so I would use #pragma pack(1) to ensure that the structure is packed to byte boundry |
Look in the PCD manual, in the section below. They have a 'packed'
attribute and sample code:
http://www.ccsinfo.com/downloads/PCDReferenceManual.pdf |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Fri Feb 10, 2017 1:08 pm |
|
|
I suspect the problem will actually be the opposite way round.
Why use int8 variables to your function?. The fundamental type on the chip is an int16, and these will involve extra converting when used.
So declare your function to use int16.
Then pass your int8 parameters. These will automatically be cast _and aligned_.
My suspicion is that the function is expecting an int8 'word aligned' to be passed. When it is fed the byte aligned value from the pointer, this is then not handled correctly....
Multiple int8 values declared and used as int8's will be kept byte aligned in a structure, but groups/arrays of these, will start word aligned, unless 'packed' is used, which will remove this automatic alignment. |
|
|
|