|
|
View previous topic :: View next topic |
Author |
Message |
peterfreedom
Joined: 12 Sep 2003 Posts: 12 Location: Val-d'or, Quebec, Canada
|
#LOCATE NOT COMPILING PROPERLY |
Posted: Mon Dec 08, 2003 7:57 am |
|
|
Hi! I'm experiencing some problems with the CCS compiler using the #Locate instruction. I have two 2 dimension arrays and when I compiled the program CCS gives me some bad results.
If I compile my program with these instructions:
byte buffer[6][9];
byte screan_buffer[6][9];
CCS tells me that I have used 78% of the RAM.
if I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x20
byte screan_buffer[6][9];
#locate screan_buffer = 0xA0
CCS tells me that I have used 78% of the RAM.
If I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x120
byte screan_buffer[6][9];
CCS tells me that I have used 47% of the RAM.
And finally, if I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x120
byte screan_buffer[6][9];
#locate screan_buffer = 0x190
CCS tells me that I have used 17% of the RAM.
In the last 2 cases, the microprocessor (16F877) does not run the program.
How can this happen? Thanks to you all. |
|
|
Ttelmah Guest
|
Re: #LOCATE NOT COMPILING PROPERLY |
Posted: Mon Dec 08, 2003 8:11 am |
|
|
peterfreedom wrote: | Hi! I'm experiencing some problems with the CCS compiler using the #Locate instruction. I have two 2 dimension arrays and when I compiled the program CCS gives me some bad results.
If I compile my program with these instructions:
byte buffer[6][9];
byte screan_buffer[6][9];
CCS tells me that I have used 78% of the RAM.
if I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x20
byte screan_buffer[6][9];
#locate screan_buffer = 0xA0
CCS tells me that I have used 78% of the RAM.
If I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x120
byte screan_buffer[6][9];
CCS tells me that I have used 47% of the RAM.
And finally, if I compile my program with these instructions:
byte buffer[6][9];
#locate buffer = 0x120
byte screan_buffer[6][9];
#locate screan_buffer = 0x190
CCS tells me that I have used 17% of the RAM.
In the last 2 cases, the microprocessor (16F877) does not run the program.
How can this happen? Thanks to you all. |
You need to add #device *=16 at the top of your program.
By default, the compiler uses 8bit pointers to RAM, which reduces the code size needed to access an address. These no not allow you to talk to addresses above 0xFF. When you locate your arrays below this address, 47% of the available RAM is used by these, and any other storage. When you locate the arrays above this point, the compiler assumes that _you_ are going to access them yourself (you can do this using the 'read_bank', and 'write_bank' instruction). Without 16 bit pointers enabled, or you manually coding the accesses with these instructions, the data is no longer accessable by the program, and hence it won't work.
So you can either switch to using 16 bit pointers (which is what the *=16 tells the compiler to do), or manually code the accesses. The former will increase the code size significantly (every RAM access will now have to assume that a bank swithc may be needed), while the latter is more work.
Look at the manual section entitled:
Why does the compiler show less RAM than there really is?
Best Wishes |
|
|
peterfreedom
Joined: 12 Sep 2003 Posts: 12 Location: Val-d'or, Quebec, Canada
|
Thank you very much |
Posted: Mon Dec 08, 2003 9:29 am |
|
|
Thank you very much for your help. It made a big difference.
Correct me if I'm wrong, but in another topic somebody told me that the maximum dimension of one array would be 96 bytes (6X16). CCS would not be able to jump from one Memory Bank to an other in the same array! Is this TRUE?
Thanks again. |
|
|
Ttelmah Guest
|
Re: Thank you very much |
Posted: Mon Dec 08, 2003 10:11 am |
|
|
peterfreedom wrote: | Thank you very much for your help. It made a big difference.
Correct me if I'm wrong, but in another topic somebody told me that the maximum dimension of one array would be 96 bytes (6X16). CCS would not be able to jump from one Memory Bank to an other in the same array! Is this TRUE?
Thanks again. |
Yes.
It is not only that it can't jump banks, but also the addresses have to be sequential. Unfortunately, since there are function registers mapped into the start of each bank, the largest contiguous lump of RAM available is that from a single bank. On the 16F877, this is 96 bytes (though banks 2 & 3, have 112 sequential addresses, the top 16 of these talk to memory already used on bank0).
It is worth remembering that you can save ROM, by not using the *=16 syntax, and you could combine this with your own 'wrapper' function for read_bank, to access memory how you want. Something like:
const int bank[17] = {1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3};
const int addr[17] = {0xA0,0xB0,0xC0,0xD0,0xE0,
0x90,0xA0,0xB0,0xC0,0xD0,0xE0,
0x90,0xA0,0xB0,0xC0,0xD0,0xE0 };
int read_byte(int row,int col) {
return read_bank(bank[col],addr[col]+row);
}
Will allow you to access all the memory in the upper banks as if it was a 16*17 array, with 'row' accepting values from 0-15, and 'col' accepting values from 0-16.
Obviously the arithmetic can be modified to allow the addressing to be from any numbers you want, but you can also see that the conversion needed to access bytes in the right bank and address, is not minor (to include this as standard, would make the code a lot bulkier).
You could do code to access the entire upper memory as if it was sequential with something like:
int read_upper_byte(int address) {
if (address>=0xB0) return read_bank(3,address-0x20);
else if (address>=0x50) return read_bank(2,address+0x30);
else return read_bank(1, 1,address+0xA0);
}
If I have got this right, it should allow you to access almost the entire area of memory above 0xFF, as one block of memory with 256 addresses (it will miss the top 16 useable bytes). Again you can see that the address translation is not minor...
Best Wishes |
|
|
peterfreedom
Joined: 12 Sep 2003 Posts: 12 Location: Val-d'or, Quebec, Canada
|
Are you sure about that structure? |
Posted: Mon Dec 08, 2003 1:16 pm |
|
|
Thanks Ttelma. I studied your last post and I'm wondering if I understand it.
Normaly the read_bank instruction need to have the bank number from 0-3 and the offset from 0 to 0x59 (for bank 1, 2 and 3) and 0 to 0x49 (for bank 1).
This way, accesing Row 0, Column 0 would give read_bank(1,0xA0) and accesing Row 15, Column 16 would give read_bank(3,0xEF) if I understand well.
I was wandering if it should be written like this instead:
const int bank[17] = {1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3};
const int addr[17] = {0x00,0x10,0x20,0x30,0x40,
0x00,0x10,0x20,0x30,0x40,0x50,
0x00,0x10,0x20,0x30,0x40,0x50};
int read_byte(int row,int col) {
return read_bank(bank[col],addr[col]+row);
}
This way, accesing Row 0, Column 0 would give read_bank(1,0) and accesing Row 15, Column 16 would give read_bank(3,0x5F). I think that this is the way to acces RAM via the read_bank instruction.
I also think that I should reserve those memory location with the #reserve instructuction? ? What is your opinion? |
|
|
Ttelmah Guest
|
Re: Are you sure about that structure? |
Posted: Mon Dec 08, 2003 3:15 pm |
|
|
peterfreedom wrote: | Thanks Ttelma. I studied your last post and I'm wondering if I understand it.
Normaly the read_bank instruction need to have the bank number from 0-3 and the offset from 0 to 0x59 (for bank 1, 2 and 3) and 0 to 0x49 (for bank 1).
This way, accesing Row 0, Column 0 would give read_bank(1,0xA0) and accesing Row 15, Column 16 would give read_bank(3,0xEF) if I understand well.
I was wandering if it should be written like this instead:
const int bank[17] = {1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3};
const int addr[17] = {0x00,0x10,0x20,0x30,0x40,
0x00,0x10,0x20,0x30,0x40,0x50,
0x00,0x10,0x20,0x30,0x40,0x50};
int read_byte(int row,int col) {
return read_bank(bank[col],addr[col]+row);
}
This way, accesing Row 0, Column 0 would give read_bank(1,0) and accesing Row 15, Column 16 would give read_bank(3,0x5F). I think that this is the way to acces RAM via the read_bank instruction.
I also think that I should reserve those memory location with the #reserve instructuction? ? What is your opinion? |
You are right, I was generating the actual address to be used, since in the past I have done this in assembler.
No, you don't need to #reserve the addresses, if you leave out the *=16. The whole point is that the C itself will only then access bank0, and it leaves you free to treat bank1,2 & 3, as your own memory. The read_bank and write_bank instructions become the only ones that will set the bank to a value other than zero, keeping the rest of the code as small as possible.
Best Wishes |
|
|
peterfreedom
Joined: 12 Sep 2003 Posts: 12 Location: Val-d'or, Quebec, Canada
|
Thank you very much Ttelma |
Posted: Tue Dec 09, 2003 6:39 am |
|
|
People like you make this forum priceless. |
|
|
|
|
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
|