View previous topic :: View next topic |
Author |
Message |
mcman
Joined: 23 Jan 2007 Posts: 8 Location: Corvallis, OR
|
RAM Allocation problem? |
Posted: Thu Feb 01, 2007 5:44 pm |
|
|
PIC: 18F8722
Compiler: CCS PCH version 3.245
Problem:
I have an application that was working just fine. I added an array to the application and noticed some abnormal behavior with the application, not related directly to the array (array is not being utilized). What adding the array does do is push my RAM consumption over 50%. Looking at the sym file, I can see that some variables are now allocated to bank 8 (above 800h). If I add to the array size and push my RAM allocation even higher, I can make the 'abnormal' application behavior go away. So, there seems to be certain RAM allocations above 800h that can cause me problems.
Looking a little harder, I noticed in my sym file where a global variable, related to the 'abnormal' behavior, was mapped between 04F and 06E. This is partially in the Access RAM bank, partially out. I did a #locate to locate the variable out of the Access Bank, and now all of my problems went away.
Two things, then, seems to cause trouble. Some combination of variable assignments in Bank0 (perhaps especially in the Access Bank area below 060h) and Bank8.
Does this make sense to anyone? Can anybody tell me how I may have gotten myself into trouble? Should I be seeking to #locate certain items... items that the compiler may not allocate in the best manner?
Thank you in advance.... |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Fri Feb 02, 2007 12:07 am |
|
|
When an array is used with a variable index the indirect addressing registers have to be used. The address of the indexed variable is loaded to the indirect addressing register and then the array element is either read from or written to. If Arrays are located on bank boundary's they will use less code to load the address of the element to be addressed. I have seen the compiler locate variables with increased effectiveness over time but its not as good as doing it by hand and most of the time the compiler does just fine.
For example an array located at 0100H
To access array element x the compiler will load the indirect addressing registers with 1 and x
For example an array located at 0110H
To access array element x the compiler will load the indirect addressing registers with 1 and x+10
For an array that spans more than a single bank it's more complicated. I have seen this cause a lot of extra code that did not work as well. If you need an array of more than 256 bytes your still better off with the array aligned to a bank boundary.
If you look at the sym file and see an array of less that 257 bytes that spans two banks you should manually locate it at a memory bank boundary. For any other variable that spans a bank boundary just locate it within a single bank. |
|
|
mcman
Joined: 23 Jan 2007 Posts: 8 Location: Corvallis, OR
|
|
Posted: Fri Feb 02, 2007 11:09 am |
|
|
Thank you for your reply! Per your guidelines, I need to reassign several arrays.
Just to be clear, the array assignment that seems to be causing me grief is one that is located entirely within Bank 0, but spanning both the Access RAM below 060h and the GPR area. Relocating the array using #locate solved my problems.
Do you have any recommendations regarding what gets mapped by the compiler into the Access RAM area? My understanding is that it is advantageous to map variables into the Access RAM area because it allows for efficient access (no need to specify BSR). Any idea what might happen when an array gets mapped half in Access RAM and half out? Seems like that might be a no-no. |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Fri Feb 02, 2007 5:53 pm |
|
|
mcman wrote: | My understanding is that it is advantageous to map variables into the Access RAM area because it allows for efficient access (no need to specify BSR). |
This is only true for directly accessed variables. For an array there is no advantage from locating it in the Access RAM area unless you hard code the index for array operations.
These two statements compile very differently. The first one uses direct addressing because it can, it takes less code and its faster. The second one used indirect addressing because it has to, it takes longer to execute and it takes more code space.
x=Array[1];
instead of
x=Array[y];
mcman wrote: | Any idea what might happen when an array gets mapped half in Access RAM and half out? Seems like that might be a no-no. |
I don't know of any issues with arrays in Access RAM but if you have an array in Access RAM then some other variable that could benefit from being located in Access RAM is not getting that benefit. |
|
|
|