|
|
View previous topic :: View next topic |
Author |
Message |
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
compiler acts like typemode is using internal memory |
Posted: Fri Jun 23, 2006 10:54 am |
|
|
The memory stats at the end of a compile make this program look as tho the typemod is using up 18F452 memory.
It shouldn't be, they are using external FRAMS.
http://www.ccsinfo.com/faq.php?page=addressmod
Why does it look like it is?
btw. I put in stub function so you can watch this if you don't have a FRAM.
Code: | #include <18F452.H>
#use delay(clock=40000000)
#fuses h4,nowdt,noprotect,nolvp
#use rs232(baud=19200,xmit=PIN_C0,invert,stream=DEBUG,disable_ints) // stderr(same as debug)
#case
#zero_ram
int8 ERRORS;
#define FRAM_CHIPS 4
//#include <FM24C256.C>
BOOLEAN wr(int32 address,char *data,int16 size);
BOOLEAN rd(int32 address,char *data,int16 size);
//--------------------------------------------------------------------//
//CCS quote
//The address can be 24 bits but the range needs to be 16 bits.
//So you can do 0x10000 to 0x1ffff.
typemod <,rd,wr,0x0000,0xFFFF>FRAM1;//24 bit address ,16 bit range
//====================================================================//
void main(void)
{
int32 FRAM1 w[255];// <--------- This is the problem, uses eternal FRAM memory
int32 r;
int8 x;
setup_adc_ports(NO_ANALOGS);set_tris_a(0);set_tris_b(0);set_tris_c(0);set_tris_d(0);set_tris_e(0);
//init_fram();
printf("Start\n\r");
x=0;
do{
r=(int32)x;
w[x]=(int32)x;//typecast important
//r=w[x];
//if(w[x]!=(int32)x)printf("%LU=%LU\n\r",x,r);
x++;
}while(x!=0);
printf("\n\rDONE !\n\r");
while(1)
{
}
}
BOOLEAN wr(int32 address,char *data,int16 size){
//These are external FRAMS ((No 18F452 mem used))
fprintf(DEBUG,"a=%lu s=%lu\n\r",address,size);
return(TRUE);
}
BOOLEAN rd(int32 address,char *data,int16 size){
//These are external FRAMS ((No 18F452 mem used))
fprintf(DEBUG,"a=%lu s=%lu\n\r",address,size);
return(TRUE);
}
|
|
|
|
Ttelmah Guest
|
|
Posted: Fri Jun 23, 2006 2:43 pm |
|
|
Everything you show here, _will_ use internal RAM. it is up to the routines wr, and rd, to pass the values _on_ to the external memory, at the address specified. The difference comes when you call the routines multiple times with different values/addresses, the same internal RAM is used, just with a different address/values passed to the functions.
The function provides an interface, to allow you to treat the external memory as if it was local, but a local buffer is used to provide the bridge between the two memory areas.
Best Wishes |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Fri Jun 23, 2006 2:54 pm |
|
|
I don't understand.
I thought that if you provide typemod with read and write functions, the compiler works as if the memory is external.
see second paragraph of the above faq link.
ex:\drivers\d41256.c
Why would the compiler mirror(local buffer) all the external FRAM variables internally?
I thought it was just tracking pointers and memory usage.
Why have a BIG array defined in external memory, just to have it mirrored internally? |
|
|
Ttelmah Guest
|
|
Posted: Sat Jun 24, 2006 2:27 am |
|
|
It doesn't 'mirror them all locally', it generates a local RAM copy of the data you want to send, and then calls the wr function, with this copy, and the address this is to go to in the target chip. If you call the function again, the same RAM buffer is used, but with a different address passed. Similarly on retrieval, it calls the function with an address, and expects your routine to retrieve the data from this address,and return it. Effectively it is like having a large vat of water and a bath. It uses a bucket, to move water backwards and forwards between the vat and the bath. The 'vat' is the external memory, and the 'bath' the local memory, with the 'bucket', being a small local buffer used to perform the transfer. When the wr, and rd routines are called, they are given the location of the 'bucket' in local memory (the character pointer), and the address in the external memory to/from which this has to be put/read. At the point the wr routine is called, everything is in local memory , and it is up to this routine to put the data into the remote memory. When rd is called, it has the job of fetching data from the 'address' in the remote memory, and putting this into the local memory buffer. At the end of the day, there has to be a local memory area used like this, or how can the data actually be transferred?. Without the buffer, it'd be just like trying to move the water directly from vat to bath, without using any intermediate storage (no spoon, bucket etc.). While this is possible on processors where the memory bus is externally accessible (using DMA - effectively a hosepipe in the analogy), the PIC does not support this, so a temporary intermediate buffer has to be used...
However just as in the analogy, the 'vat', can be huge compared to the size of the bucket.
Best Wishes |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Sat Jun 24, 2006 1:04 pm |
|
|
OK. Getting a clearer picture.
I thought NO buffer was needed. Functions are called only on rd/wr thus
local=external;//(rd)local has to be defined already.
or
external=12;//(wr)12 is defined and sent to functions.
to me no extra buffer is needed.
OK tho.
So to recap. My line
int32 FRAM1 w[255];//
is actually using internal PIC memory up even tho I say it is in FRAM1 defined
as external. OK got it. Not happy about it,.. but I understand.
Could just using pointers and malloc get me away from using up the PIC ram? |
|
|
Guest
|
|
Posted: Sat Jun 24, 2006 6:27 pm |
|
|
I´m interested in this topic, so i´m asking... how muck memory is being used to buffer the data trasfer? If he declares an array of 256 bytes in external memory and it needs 4 bytes do serve as a "buket", ok.. but if it needs 256 bytes, there´s no point in having external memory! So my question is: hou much is beig used to buffer? (Ok, i´m being lazy, i should just grab this code and compile it to find, but... it´s easier to ask first |
|
|
Ttelmah Guest
|
|
Posted: Sun Jun 25, 2006 2:55 am |
|
|
The point is that the transfer routine is handed the address (4 bytes locally), a pointer to the data you are asking it to transfer (the size of this is dependant on the PIC involved, and the actual size of the area _you_ point it at), and a two byte 'size' value. However there is no extra 'hidden' buffer. At this point all the data is local to the PIC (it has to be, or you can't work with the values). You can handle a 128KB 'external' array (or even larger), with only eight bytes of local storage if required. The point is that at the moment of transfer, the data you are transferring, has to exist 'locally' in the RAM, as do all the values to control the transfer, so the call to the transfer routine has 'local' values to work with, but there does not have to be a buffer matching the size of the external data involved. In a sense (from my original analogy), there only needs to be a local 'teaspoon', to handle transfers to/from a remote 'swimming pool'. :-)
Best Wishes |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Sun Jun 25, 2006 2:10 pm |
|
|
Right, Right, right. This is sounding better and better.
How I thought of it is (from faq)..
ext_flash_read(int32 addr, int8 *ram, int8 bytes)
means 4bytes for in32, 2bytes for pointer, 1byte for size.
7 bytes. Even some more if tracking a bunch of pointers....
BUT...
compiler says
RAM used: 1037 (68%) at main() level
1070 (70%) worst case
and lets say int32 FRAM1 array[256] thats 256*4=1024
those are quite close. But that means its counting external defined memory as the internal PIC memory.
take out the int32 FRAM1 array
RAM used: 12 (1%) at main() level
14 (1%) worst case
Which seem more resonable.
Maybe its just the way its calculated, that I don't get. |
|
|
Ttelmah Guest
|
|
Posted: Mon Jun 26, 2006 2:29 am |
|
|
I think what is happening, is that the system generates a buffer equal to the 'size' of the largest element you place into the memory. It is a pity if so, but I just tried the experiment, of generating one 64 byte array, and then four 64 byte arrays. The RAM useage, on the test program, was 184 bytes, rising to 204 bytes (which included a few other test variables etc.).
So, less RAM, than the amount of external storage, but more than might be expected..
Effectively, it appears the size of the array you setup, determines the 'spoon' used. I have allways tended to use smaller blocks, so this has not been a problem, but it does restrict the utility rather...
Best Wishes |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Mon Jun 26, 2006 10:51 am |
|
|
I think I figured something out!!!!
Put the big array outside of main and its happy.
Put it local to main and I get big memory usage.
Lesson: Define it with global scope. |
|
|
|
|
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
|