View previous topic :: View next topic |
Author |
Message |
lukeevanslx
Joined: 11 Jun 2012 Posts: 14
|
How to Declare an Uninitialised Variable |
Posted: Mon Jun 11, 2012 5:00 pm |
|
|
Hi
Using CCS for PIC 18F.
How do I declare an uninitialised variable?
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
lukeevanslx
Joined: 11 Jun 2012 Posts: 14
|
|
Posted: Mon Jun 11, 2012 5:38 pm |
|
|
Thanks for that.
I've re-read the material.
Nowhere does it explicitly say how to declare a variable that is uninitialised.
OK, so to declare without initialisation is something like:
int iMyVar; //=0; <-- no initialisation.
But this does not preclude c-startup from setting the RAM location to some value (usually 0).
The trick is, I want iMyVar to persist through reset. How is this type of variable declared?
Thanks again. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 11, 2012 5:45 pm |
|
|
Quote: | OK, so to declare without initialisation is something like:
int iMyVar; //=0; <-- no initialisation.
But this does not preclude c-startup from setting the RAM location to some value (usually 0).
|
It will set it to 0 in the start-up code if you declare it as 'static'. |
|
|
lukeevanslx
Joined: 11 Jun 2012 Posts: 14
|
|
Posted: Mon Jun 11, 2012 5:56 pm |
|
|
Thanks.
Am I to understand then, that variables which are not declared as 'static', are not touched by startup code? This is not explicitly stated.
Usually a non-standard compiler directive such as __no_init (and similar, or #pragma) is used for this purpose.
Please advise. |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Jun 11, 2012 6:05 pm |
|
|
the rules are:
if static - it will be inited
if declared in the form byte x=13;
then at startup and after a reset x=13
the form byte y;
has an unknown value that is not touched by a reset
at least as i understand it.
that leaves open the ability to SET a value in arbitrary code
in runtime for y and have the value you set survive a "hot" reset |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 11, 2012 6:05 pm |
|
|
It may depend on the PIC and the compiler version. I tested it with
a 16F877 with vs. 4.132.
You can do your own tests. Set the .LST file format for "Symbolic" mode.
Then look at the .LST file after you compile a short test program. Look
for any ASM code statement that does a CLRF on your variable. If it does
that, then it's clearing it. |
|
|
lukeevanslx
Joined: 11 Jun 2012 Posts: 14
|
|
Posted: Mon Jun 11, 2012 6:15 pm |
|
|
The #byte and #word (etc) options looked like the best options for guaranteeing behaviour.
However the variable I wish to persist is a struct.
"It may depend on the PIC and the compiler version." ??
Feature request?
Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 11, 2012 6:19 pm |
|
|
You need to write test programs and look at the .LST file to see the
compiler behavior. You also need to look at the data sheet for your
PIC to see what happens to RAM after a reset (of various types).
There is a table in the data sheet that will tell you this. I don't want
to do these tests and reading for you. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Tue Jun 12, 2012 12:59 am |
|
|
It has been pretty fixed for many versions, and is exactly as asmboy says.
The one thing he missed, is that if you have #ZERO_RAM, then this forces _all_ variables to zero, _before_ the standard initialisation code.
I've used variables just declared, and not initialised in code with the ability to recover from a watchdog timeout, for something like ten years+, and all CCS compilers (that have actually worked - no guarantees on the low 4.xxx versions), have stuck to the rules, and a simply declared variable, is not initialised.
There is one other 'caveat'. Remember that _local_ variables (ones inside subroutines), can be re-using RAM that is also used in other routines 'higher' up the tree of routines. These can _never_ be relied on to be uninitialised.
Best Wishes |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Jun 12, 2012 8:21 am |
|
|
Quote: |
the ability to SET a value in arbitrary code
in runtime for y and have the value you set survive a "hot" reset |
I have used this "feature" for some time ;-)) |
|
|
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Tue Jun 12, 2012 10:45 am |
|
|
@asmboy:
ive done it too, specifically for setting modes.. this allows me to use the reset button as a mode switch and ON/OFF
if you declare:
Code: | INT Y;
... do some code...
Y=3;
... more code... |
then press reset button on MCLR.... Y will still be 3
Edit:
by ON/OFF i mean.. checking the value of Y and going to sleep or not.
G _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19529
|
|
Posted: Tue Jun 12, 2012 1:00 pm |
|
|
So, three of us at least now, doing this without problems.
I'd guess the most likely problem, as already mentioned, is perhaps trying to use a local variable this way. That won't work. Only variables that are global, or declared in the 'main', have memory physically 'reserved' for them.
Best Wishes |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1615 Location: Central Illinois, USA
|
|
Posted: Wed Jun 13, 2012 6:04 am |
|
|
Ttelmah wrote: | So, three of us at least now, doing this without problems.
I'd guess the most likely problem, as already mentioned, is perhaps trying to use a local variable this way. That won't work. Only variables that are global, or declared in the 'main', have memory physically 'reserved' for them.
|
Make that 4. I've also been using this feature in battery powered "must sleep" apps for years now.
as mentioned, can't #zero_ram and then just declare global structs..
(one app does exactly that -- it runs a schedule that's brought out of sleep every minute by the PIC's clock) _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
lukeevanslx
Joined: 11 Jun 2012 Posts: 14
|
|
Posted: Wed Jun 13, 2012 4:27 pm |
|
|
Thanks all.
That makes at least 5 people now holding their breath that the compiler doesn't change its behaviour in a future revision.
*Not* declaring a variable as static says nothing about about the c-startup sequence; likewise, it cannot be explicitly inferred that *not* using #zero_ram will not set the value of any variable to some value on startup. The current behaviour is weakly inferred in the negative sense by the absence of two type modifiers. This is not a an explicitly documented behaviour. The current situation is a serendipitous workaround. Have you checked your .lst files to be sure, or just observed intended behaviour over a number of reset cycles?
I tried checking my .lst file for accesses to my persistent struct. Here, as I expect, I do not see any references explicitly to it. Again, through a negative, the absence of an explicit access to my variable, is it reasonable to infer it is not touched in a some other memfill (etc) operation? No, this is not reasonable.
An explicit, documented compiler/linker directive would provide the feature, while guaranteeing performance. |
|
|
|