|
|
View previous topic :: View next topic |
Author |
Message |
Herbert
Joined: 20 Jul 2008 Posts: 32 Location: Brisbane, Australia
|
Function return point in code changes |
Posted: Sun Jan 10, 2010 2:20 am |
|
|
Hi,
I am finding that a function of mine goes off into the never-never in some cirumstances and not in others. This function had been working for a long time and now is showing unusual behavior.
I am using PCWH vers 4.104 and its debugger.
Are there any suggestions as to how I might attack this one to figure out the problem -
The difference in behavoir is dependent on the difference of two lines of code on compilation. The code is - Code: |
void Write_G_Configuration_To_EEPROM()
{
#define LStorage ((struct G_Configuration*)Temp1 )
int16 Structure_Size;
int8 i, Temp1[100];
Structure_Size = Sizeof( struct G_Configuration );
LStorage->Version = Current_EEPROM_Version; //AAAA
// LStorage->GC_F_F = F_F; //BBB
i = 0; //debugging
#undef LStorage
}
|
With the code as is, it runs as expected and if I follow it through and look at the debugger "Stack" tab on function exit, the list is entirely what I expect.
If I disable line //AAA and enable line //BBB, then it doesn't work as expected. Again, going through step by step I find the function exit, on the "Stack" tab, is now A5824 and it gives a warning that this is not a valid address.
Looking at the listing, shows the //BBB line generates this code
Code: |
.................... LStorage->GC_F_F = F_F;
4BC4: MOVLW 8A
4BC6: MOVWF FFF
4BC8: MOVWF 01
4BCA: MOVLW 07
4BCC: MOVF 01,W
4BCE: MOVLW 07
4BD0: MOVWF xF0
4BD2: MOVLW 8A
4BD4: MOVWF xEF
4BD6: BTFSC 3F.0
4BD8: BRA 4BE6
4BDA: MOVFF 7F0,FEA
4BDE: MOVFF 7EF,FE9
4BE2: BCF FEF.0
4BE4: BRA 4BF0
4BE6: MOVFF 7F0,FEA
4BEA: MOVFF 7EF,FE9
4BEE: BSF FEF.0
|
I don't understand how the stack can be corrupted, by this code.
Please let me know if you have any suggestions. Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jan 10, 2010 2:50 am |
|
|
For a problem like this, always tell us what PIC you're using.
Post your #fuses.
Do you have vs. 4.099 or can you download it ? If so, try it. |
|
|
Ttelmah Guest
|
|
Posted: Sun Jan 10, 2010 3:23 am |
|
|
Get things clear in your head.
'Integer arithmetic', implies 'no decimals', implies no possible results for sin/cos etc.....
Only with _scaled_ integers, do results for things like sin/cos exist.
For most applications, if you are only using (say) 2 digits), and coding for speed, then the fastest solution, is a lookup table. Just code your own. There have been several posted examples here for some specific applications.
For three digits, a 2 digit lookup, and linear interpolation is usually the simplest . There have been interpolation examples posted here as well.
You need to decide what scaling you want to use, and what accuracy you need, then people may be able to help.
Best Wishes |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Jan 10, 2010 4:06 am |
|
|
The shown code is actually modifying the stack, but I don't understand why. Looks like a compiler bug.
Code: | 4BC4: MOVLW 8A
4BC6: MOVWF FFF ; TOSU SFR register |
|
|
|
Herbert
Joined: 20 Jul 2008 Posts: 32 Location: Brisbane, Australia
|
|
Posted: Sun Jan 10, 2010 5:08 am |
|
|
PCM, yep for sure, I always forget something -
Code: |
#include <18F2620.h>
#device ICD=TRUE //When TRUE, debugging code is inserted
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES INTRC //Internal RC Osc
#FUSES NOPROTECT //Code not protected from reading
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV21 //Brownout reset at 2.1V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#use delay(clock=16000000)
//#use delay(type=xtal, clock=16000000)
#USE RS232(UART1)
|
Can't download 4.099, don't have current rights.
Ttelmah, thanks for the random thoughts! I suspect it is mean't for another topic. Did the other topic get my reply?
FvM - I see your point and its a good one at that. It does seem those bits of code should not be there.
Looks like I might have to pass this one on to CCS, unless there is something I am totally missing still.
Thanks very much for the thoughts, even Ttelmah (LOL). |
|
|
Ttelmah Guest
|
|
Posted: Sun Jan 10, 2010 5:39 am |
|
|
Ttelmah wrote: | Get things clear in your head.
'Integer arithmetic', implies 'no decimals', implies no possible results for sin/cos etc.....
Only with _scaled_ integers, do results for things like sin/cos exist.
For most applications, if you are only using (say) 2 digits), and coding for speed, then the fastest solution, is a lookup table. Just code your own. There have been several posted examples here for some specific applications.
For three digits, a 2 digit lookup, and linear interpolation is usually the simplest . There have been interpolation examples posted here as well.
You need to decide what scaling you want to use, and what accuracy you need, then people may be able to help.
Best Wishes |
Don't know why this appeared here, I posted it to the thread about integer arithmetic......
A hiccup somewhere. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Jan 10, 2010 5:40 am |
|
|
Quote: | Looks like I might have to pass this one on to CCS. |
Basically yes. Actually, I never found PCH writing to register 0xFFF (TOSU) in any of my projects.
I guess, using the large array Temp1[100] inside the function may bring on the issue. You can check the *.sym file,
if all variables are assigned correctly.
I also wonder what you are trying to achieve in your code. It seems to me, that LStorage is an uninitialized
pointer, so LStorage->GC_F_F = F_F most likely writes out of bounds. |
|
|
Herbert
Joined: 20 Jul 2008 Posts: 32 Location: Brisbane, Australia
|
|
Posted: Sun Jan 10, 2010 6:02 am |
|
|
FvM,
because of the #define I think I am acheiving the same as -
Code: |
((struct G_Configuration*)Temp1 )->GC_F_F = F_F;
|
Where F_F is a global variable. So I am storing the global into the structure which is later stored to eeprom. By replacing the code explicitly (with the line above) I still get the same compiled result.
Reducing the array to 40 bytes still generates the same code. And this function had worked with a previous version of the compiler.
Thinking about it, I can probably use "Sizeof( struct G_Configuration )" in the declaration to define the array size (Temp1) more exactly.
Checking the sym file shows the array space is as it should be and appears in a reused area.
Thanks for your further thoughts. |
|
|
Herbert
Joined: 20 Jul 2008 Posts: 32 Location: Brisbane, Australia
|
|
Posted: Sun Jan 10, 2010 6:17 am |
|
|
FvM,
have looked at an archived copy of my development folder and the .LST file does not have the offending two bytes as part of the code. When I recompile that archived folder(with 4.104), the new .LST file has those two bytes added in. Game, Set and Match, as they say. Looks like a compiler fault.
Cheers for your help. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun Jan 10, 2010 7:14 am |
|
|
Yes, more newly introduces V4.104 have been already reported in the forum.
Regarding the construct
Code: | ((struct G_Configuration*)Temp1 )->GC_F_F = F_F; |
I forgot, that Temp1 is equivalent to &Temp1[0]. So the data can be expected to be written to the memory
area defined by Temp1[100]. Defining an item of the struct base type would be clearer, I think. |
|
|
|
|
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
|