View previous topic :: View next topic |
Author |
Message |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
How to define a specific location for a variable in RAM? |
Posted: Thu Oct 26, 2017 8:07 am |
|
|
I have a routine that clean GPR RAM excepts some specific bytes and I need to set the address of some variables at those address locations in RAM to avoid been erased when the cleanRAM routine runs but I don't remember how to do it.
Another question is, Is possible to put some code before the CCS start its own initialization variable code?
I mean, I know that CCS add some code to init the variables that has been defined its value and type outside the code.
Example.
Code: | long x=14;
long z= 489;
long a;
void cleanRAM()
{
....
....
}
void main()
{
a=(x*2)+(z*5);
}
|
The variables x and z will be initialized before main code runs, and I need to add the cleanRAM routine before the main and initialization runs so I get zero on every uninitialized variable.
Is that possible? _________________ Electric Blue |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 19831
|
|
Posted: Thu Oct 26, 2017 8:42 am |
|
|
A global variable (which the ones you show outside the main are), is _not_ initialised, unless you give it an initialisation value. So your 'a' variable will be left exactly as it is by the compiler.
This is how you can declare things that remain the same in the event of (for example) a watchdog reset. So you code as:
Code: |
int16 x;
int16 z;
int16 a; //as a comment avoid sizes like 'long'. These change
//with different compilers. Use sizes that are 'defined'.
void main()
{
if (restart_cause()==NORMAL_POWER_UP)
{
x=14;
z=489; //Initialise the variables.
}
a=(x*2)+(z*5);
}
|
Will initialise x & z on the first boot, but will leave them unchanged
on subsequent restarts.
You need to check the include file for your processor for the 'restart_cause' defines.
#locate puts a variable at a specific address. |
|
 |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Thu Oct 26, 2017 9:27 am |
|
|
Thanks for your answer.
There is any way to put code before the main and global variable initialization?
I read that in other compilers like gcc you can use
Code: | void beforeMain (void) __attribute__((constructor)); |
But that doesn't work on CCS.
Now I'm reading about #build precompiler instruction. _________________ Electric Blue |
|
 |
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Fri Oct 27, 2017 4:47 am |
|
|
E_Blue wrote: | There is any way to put code before the main and global variable initialization? |
No, as far as I can see there is no way to do that in CCS C.
The directive #ZERO_RAM forces non-initialised global variables to zero, null or blank.
Personally I not a fan of #zero_ram and have never used it. Instead I ensure that I initialise all variables that need to have a known value at start up and leave the rest uninitialised, setting them in code when required. The lack of initialisation is a flag to me and future maintainers that they will be set in later code as required. As it turns out, my coding style means that generally most of my globals do not need initialising. It is always useful to know what your starting conditions are, i.e. your variables initial values, and many inexperienced programmers will assume a value (often they assume zero, which may well not be correct, especially after warm starts) which often leads to problems, e.g. obscure bugs that only happen under specific circumstances, later. |
|
 |
temtronic
Joined: 01 Jul 2010 Posts: 9475 Location: Greensville,Ontario
|
|
Posted: Fri Oct 27, 2017 8:23 am |
|
|
I've used #zero_ram before as it zeros al the RAM in the PIC. The problem with RAM is that when the PIC powers up RAM can be set in any state.
If YOU forget to initialize a variable and use it's contents, it'll be wrong causing weird things to happen.
don't know how many variables he wants to keep but you could store into EEPROM or an RTC-RAM, then read them back after the 'clearRAM' function has been done. I use the RAM in the RTC all the time as it's battery backed. You can also use LCD module memory..some have 'non displayable ' RAM in them !
Jay |
|
 |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Wed Nov 01, 2017 2:18 pm |
|
|
Finally I solved by not initializing anything outside the code.
The problem that I found was
Code: | char USB_STRING_DESC_OFFSET[3]; |
Which is initialized outside of the code, so if I clean up the whole RAM that variable will be all zeroes and the USB CDC port will not work.
So now I just initialize all the variable after cleanRAM subroutine and works OK; even some mysterious bugs has been disappeared. _________________ Electric Blue |
|
 |
|