CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

addressmod

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Dimmu



Joined: 01 Jul 2007
Posts: 37

View user's profile Send private message

addressmod
PostPosted: Fri Apr 04, 2008 3:53 pm     Reply with quote

Hi all,

I am currently using CCS 4.053 with a PIC18f97J60; with 256 kb of external RAM.

I have searched the forum but did not find the good answer to my addressmod problem : even if the declaration of external variables works fine, the compiler raises an error if I try to declare more than ~4 kb of external memory Shocked

Here is a sample of code. It compiles OK but 98% of the ram is used. If I increase the size of IDX4 to 512, then the compilation fails.
Code:

#include <18F97J60.h>

#FUSES NOWDT, WDT128, H4_SW, NODEBUG, NOXINST, STVREN, NOPROTECT, FCMEN
#FUSES IESO, PRIMARY, ECCPE, ETHLED, NOWAIT, BW16, EMCU20, EASHFT, RESERVED
#device *=16
#use delay(clock=31.500 M )


/*External RAM definition*/
#define EXT_RAM_OFFSET 0x20000
#define EXT_RAM_SIZE   0x40000

void read_ext_ram ( int32 addr, int8 * data, int nb_bytes ) {
   // some instruction in the function, not written here to keep the code small
}
void write_ext_ram ( int32 addr, int8 * data, int nb_bytes ) {
   // some instruction in the function, not written here to keep the code small
}

addressmod ( EXT_RAM, read_ext_ram, write_ext_ram, EXT_RAM_OFFSET, EXT_RAM_OFFSET + EXT_RAM_SIZE - 1 );

void main(void) {

   /*Defining some variables in EXT_RAM area*/
   int      EXT_RAM IDX0;
   int      EXT_RAM IDX1;
   int      EXT_RAM IDX2;
   int32    EXT_RAM IDX3[512];
   int32    EXT_RAM IDX4[450];

   setup_external_memory ( EXTMEM_BYTE_WRITE | EXTMEM_WAIT_0 );

   while(TRUE) {
      delay_ms ( 250 );
   }
}


If anybody knows what I forgot to do ?


Best regards,
Dimmu
Dimmu



Joined: 01 Jul 2007
Posts: 37

View user's profile Send private message

PostPosted: Sat Apr 05, 2008 1:41 pm     Reply with quote

I found the problem.

It seems that the compiler cannot allocate more than 4kb of local variables, even if they are declared in an external memory area.

As soon as I declared them as global variables, it worked fine ( at least it compiled ). Now I'll ensure that everything works fine.

Best regards,
Dimmu
Dimmu



Joined: 01 Jul 2007
Posts: 37

View user's profile Send private message

PostPosted: Sun Apr 06, 2008 2:28 pm     Reply with quote

...

After few tests, the function is too much bugged to be used right now.

Declaration of the external ram segment :
Code:
#define EXT_RAM_OFFSET 0x20000
#define EXT_RAM_SIZE   0x08000 ==> cannot assign more than 32k on one segment
void read_ext_ram ( int32 addr, int8 * data, int16 nb_bytes );
void write_ext_ram ( int32 addr, int8 * data, int16 nb_bytes );
addressmod ( EXT_RAM, read_ext_ram, write_ext_ram, EXT_RAM_OFFSET, EXT_RAM_OFFSET + EXT_RAM_SIZE - 1 );


I can manage to do a simple assignment :
Code:
external_var[i] = local_var[j];

but the other more complex tests fails :
Code:
external_var[i] = read_adc(); ==> writes incorrect value in external_var
foo(external_var); ==> the generated call to read_ext_ram makes the *data point to the addr variable
var_pointer = &external_var; ==> creates a 16 bits pointer to somewhere but I don't know where.


I think I'm gonna have to pay the support for one year to have all these bugs corrected Sad
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Sun Apr 06, 2008 9:28 pm     Reply with quote

If you can identify the problem in the assembled code you should get a faster response if you have found a bug. I would be surprised if the compiler supports using external RAM in the same way you use the internal RAM. I would expect for there to be limitations that require workarounds.
Ttelmah
Guest







PostPosted: Mon Apr 07, 2008 2:28 am     Reply with quote

If you do a search here under the old name (typemod), you may find some of the threads about this function.
Generally, the functions do work, but are more restricted than the manual suggests. For the adc value, put it into a temporary variable first. Some of the internal functions (printf in particular, and read_adc), use the source and destination variables as scratch values during the operation. Unfortunately, this gives problems if they are not in the local RAM, or accessible as if they are.
Have you actually tried using the pointer to the memory?. It certainly did work a few versions ago. The value is odd, because they add an offset to the value to clear the local RAM space, which differs from the apparent offset needed.
For a large RAM, you need to use it as if it is 'paged', assigning multiple read and write functions as needed to address sections of the physical memory. The restriction at 32K for the memory space makes 'sense', if you think in terms that addresses are 16bit values.
They also seem to use a temporary buffer locally for some transfers, restricting the sizes that can be used for some elements.
Some of the problems with these functions were discussed in the V4 problems thread, and in general I'd say that you are much better off treating the external storage more like a disk, and using a local buffer, and moving the copy of this you want, to/from the storage...

Best Wishes
Dimmu



Joined: 01 Jul 2007
Posts: 37

View user's profile Send private message

PostPosted: Mon Apr 07, 2008 5:13 am     Reply with quote

Thank you for the feedback.
I can confirm that using a temporary variable in the computation of read_adc works fine :
Code:
1) external_var[0] = read_adc(); ==> works OK
2) temp = read_adc();
   external_var[i] = temp;       ==> works OK
3) external_var[i] = read_adc(); ==> does not work

The 32k limit is not such a problem right now and I'll try to paginate the memory with multiple functions. However, in that case I think that it was useless to define an int32 variable as ADRS parameter in the read/write prototypes used with the addressmod.


My need for external memory is not to use it as usual RAM but mainly to hold big messages of ~1 kb each. I'm thus working on a workaround that should allow me to find the actual address [32 bits] of the message and then treat each byte sequentially with the TBLRD*+ and TBLWT*+ function.
The use of small variables declared in external memory shall be done with local copies in usual RAM.

main idea :
Code:
void set_external_addr ( external_variable[0] );   // the call to this function forces the reading
                                                   // of external_variable[0] and thus sets the TBLPTR
                                                   // data to the requested address
int8 read_byte_and_increment_TBLPTR ( void );      // using the TABLAT and TBLRD*+
void read_byte_and_increment_TBLPTR ( int8 DATA ); // using TABLAT and TBLWT*+



I'll try to test that this week and keep this thread updated with the results.


Best wishes,
Dimmu
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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