View previous topic :: View next topic |
Author |
Message |
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
#ORG AUTO=0 |
Posted: Fri Jan 22, 2010 7:40 am |
|
|
AUTO=0 in a #ORG statement does not seem to reset RAM usage to low memory in my application.
At the moment I have RAM enough so I don't mind -- is the compiler clever enough to realise I have enough RAM so does not bother to reset variables to low memory?
I am using PCH
Bill
=========================================
My application looks like:
[Global Variable declarations]
[Functions]
main
#ORG LOADER_ADDR+MAIN_SIZE, LOADER_END AUTO=0
[More global variables I expect to see in low ram]
[More functions] |
|
|
bilko
Joined: 17 Oct 2003 Posts: 24 Location: Dorset, UK
|
|
Posted: Wed Jan 27, 2010 7:41 am |
|
|
Further to this.
If I tell the bootloader to use more ram it still does NOT re-use low ram if I say AUTO=0 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 27, 2010 12:53 pm |
|
|
If you can post a very small (20 lines) compilable test program
that shows the problem, then we can maybe offer some help.
Also post your compiler version. |
|
|
mlee
Joined: 29 Jul 2010 Posts: 2
|
|
Posted: Thu Jul 29, 2010 12:53 pm |
|
|
I have run into the same problem and it seems to happen on a lot of target processors. Working with a very basic source (see code below) I found that the auto=0 only seems to work for NON global variables. If global variables are used the compiler seems to start its "Low Memory" right after the last global variable location.
This gets to be a real issue if a large number of global variables or large global displays are defined as the "Low Memory" no longer is in the intended location.
The below code was compiled with Version 4.105
Code: |
#include <18F2520.h>
#device adc=8
#org 0x500, 0x600 auto=0
void test_function()
{
int8 test1;
int8 test2;
int8 test3;
test1 = test2+test3;
}
int8 array1[128];
int8 array2[128];
void main()
{
int8 array3[128];
int8 array4[128];
test_function();
while(1);
}
|
Below is an excerpt from the variable map file for the above code that shows were the variables ended up. The test variables end up overlapping the main function variables staring at 105, right AFTER the global variables array1 and array2.
Code: |
000 @SCRATCH
001 @SCRATCH
001 _RETURN_
002 @SCRATCH
003 @SCRATCH
004-083 array1
084-103 array2
104-183 MAIN.array3
105 test_function.test1
106 test_function.test2
107 test_function.test3
184-203 MAIN.array4 |
Not sure if this is intended operation or not, but to me it seems that if the manual says it will place it in low memory then I would expect it to place it in the low memory regardless of what else was defined to be in that memory. I assumed this is why the manual warns about only using this option if the program is not expected to return from the function call (due to the data getting corrupted). |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Fri Jul 30, 2010 2:38 am |
|
|
Remember an ORG remains in force till the next ORG.
The 'point' about auto=0, is that it allows you to declare a function, using variables in part of memory, and then declare another using the same memory area (so that RAM can be re-used by a bootloader for example).
Code: |
#include <18F2520.h>
#device adc=8
#org 0x500,0x600 auto=0
void dummy(void) {
//This function will re-use the RAM area already used by main
int16 array2[10];
array2[1]=array2[2]*array2[3]; //Pointless
}
#org default //Switch to using the default allocation
void main(void) {
int16 array[20];
array[1]=array[2]*array[3]; //Pointless but forces scratch to be used.
while (TRUE);
}
|
The #org default tells main to use the default origins. Otherwise the one defined by the earlier ORG will still be in force
Compile this, and you will find array2, and array1, are both using the same memory area (one byte different....).
Best Wishes |
|
|
mlee
Joined: 29 Jul 2010 Posts: 2
|
|
Posted: Fri Jul 30, 2010 8:45 am |
|
|
Ttelmah,
I have updated my code to use the #org default as you indicated and yes you are correct as to the way it compiles. However, your code doesn't declare any global variables. This code below has some global variable arrays.
Code: |
#include <18F2520.h>
#device adc=8
int8 array1[128];
int8 array2[128];
int8 array3[128];
#org 0x500, 0x600 auto=0
void test_function()
{
int8 test1;
int8 test2;
int8 test3;
test1 = test2+test3;
}
#org default
void main()
{
int8 array4[128];
int8 array5[128];
test_function();
while(1);
}
|
Now the variables test1, test2 and test3 get placed in memory after the first three global arrays placing them at 185,186, and 187. They overlap array4 which is the local variable in main.
I understand your point of saying that one purpose of this directive is to allow a function to reuse RAM so that if you have a function that will not run during normal operation (such as a bootloader) you don't have to give up resources by having them permanently reserved for this function.
on the other hand the compiler manual states:
Quote: |
The RAM for a ORG'ed function may be reset to low memory so the local variables and scratch variables are placed in low memory. This should only be used if the ORG'ed function will not return to the caller. The RAM used will overlap the RAM of the main program. Add a AUTO=0 at the end of the #ORG line.
|
Which implies to me that the variables should then be placed in low memory so that the function can more easily access them. I would think this is the other 'point' of auto=0, to allow more compact/efficient code to be created for a function such as a bootloader.
The locations where these test variables have been stored is not in low memory due to it reserving the global variable space. The reason I even ran into this is that I use quite a few global variables in this particular code and also have a custom bootloader in a #ORG... auto=0 location. All worked fine until I needed to make an update and adding one global integer variable was enough to push the memory locations for my bootloader partially into the next range of RAM. This grew the code size of my bootloader in order to access these variables and made it too large to fit into the area I had alloted for it in the #org statement causing it to no longer compile.
Had the auto=0 portion actually written the variables in low memory over the global variables I would have been fine. My current work around is to just specifically locate the variables in low memory using #byte commands. This works, it's just a little more cumbersome and creates a little more risk for creating bugs in software. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19498
|
|
Posted: Fri Jul 30, 2010 9:54 am |
|
|
The manual is quite clear. "Local, and scratch variables". Nothing about 'global'. The whole point about 'Global' variables, is that they are _global_, so you can't re-use the memory area they occupy.
Best Wishes |
|
|
|