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

How to automatically locate RAM buffers?

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



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

How to automatically locate RAM buffers?
PostPosted: Thu Nov 11, 2004 4:22 am     Reply with quote

I'm having some troubles using the #locate instruction. I want to place several of my larger buffers at the end of the RAM area with the compiler calculating the physical addresses at compile time. If I decide to change the size of one buffer, the other buffers are automatically moved to new locations. is there any way to realize this?

Using #locate in combination with simple constant arithmetic failed me with several compiler errors.

Below is an example of what I want to achieve:
Code:

#locate RxBuffer   = 0x400
#locate HugeBuffer1 = RxBuffer + sizeof(RxBuffer)             // Error: A numeric expression must appear here
#locate HugeBuffer2 = HugeBuffer1 + sizeof(HugeBuffer1)
#locate HugeBuffer3 = HugeBuffer2 + sizeof(HugeBuffer2)
etc
Ttelmah
Guest







PostPosted: Thu Nov 11, 2004 5:58 am     Reply with quote

Unfortunately, this is an area, where the compiler does not match it's paperwork...
In your case I can understand 'sizeof' not working, since this is potentially a 'C' function, and the manual says that the address for #locate should be a constant. However I have tried in the past, by 'reserving' the area, and then using the #byte directive to place elements there, which (given the manual for #byte, says that the location may a 'C variable, or constant'), should work, but still gives an error.
One way round, is to access the arrays using pointers. You can then set these to addresses in your reserved area, at runtime, rather than during compile. So something like:
Code:

struct buff64 {
   int8 b[64];
};
struct buff32 {
   int8 b2[32];
};
typedef struct buff64 *bptr64;
typedef struct buff32 *bptr32;

bptr64 buffptr;
bptr32 buffptr2;

#define MYRAM 0x400;
#RESERVE 0x400:0x4FF

Then in the initialisation:

Code:


   buffptr=(bptr64)MYRAM;
   buffptr2=(bptr64)(buffptr+sizeof(struct buff64));

Then you can use the C shortcut (->), and use buffptrand buffptr2 to access the arrays with:
buffptr->b[n];

Changing the declared sizes for the structures, should automatically be reflected in the locations where the pointers are 'aimed'.
It'd be rather nice, if the #locate, had an ability like #org, to change temporarily to use the selected memory area for a group of variables one after the other, and then switch back to using the normal allocations.

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Nov 11, 2004 7:00 am     Reply with quote

Thanks TTelmah. Your solution is a nice start for designing a dynamic memory allocation system, but is too much for my simple goal. For optimization purposes I have to allocate some buffers at a fixed memory location. From past experience I know it is very easy to create overlapping buffers and I'm trying to find a simple solution for minimizing programmer's errors.

I do realize that my example of the #locate instruction using the sizeof operator is not perfect, but it shows nicely what I want to achieve. The manual states:
Quote:
Syntax: #locate id=x

Elements: id is a C variable,
x is a constant memory address

It comes down to figuring out what CCS's definition is of a 'constant memory address'.
Other compilers I used had clever preprocessors which could resolve many constructions at compile time. I tried several combinations but haven't found a working set yet.
Code:
int8 Buffer[0x100];
#locate Buffer      = 0x500        // OK

#locate Buffer      = 0x500+0x10   // Error: Expecting a declaration

#locate Buffer      = (0x500+0x10) // Error: Expression must be a constant or simple variable

int8 MyBufPtr = 0x500;
#locate Buffer      = MyBufPtr    // compiles, but buffer not in symbol list.

char* MyBufPtr = 0x500;
#locate Buffer      = MyBufPtr    // compiles, but buffer not in symbol list.

const char* MyBufPtr = 0x500;
#locate Buffer      = MyBufPtr    // compiles, but buffer not in symbol list.

Am I overlooking other constructions to achieve my goal of setting the ROM locations at compiler time?
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Thu Nov 11, 2004 9:14 am     Reply with quote

This works for me.
Code:
int8  RegisterMap[256];
#locate RegisterMap = 0x100     //Through 0x1FF
int8 REG_1000_L;
#locate REG_1000_L = RegisterMap
int8 REG_1000_H;
#locate REG_1000_H = RegisterMap + 0x01


I would guess you could do something like this.
Code:

Int8 RxBuffer[64]
#locate RxBuffer   = 0x400
Int8 HugeBuffer1[64]
#locate HugeBuffer1 = RxBuffer + 64
Int8 HugeBuffer2[64]
#locate HugeBuffer2 = HugeBuffer1 + 64
Int8 HugeBuffer3[64]
#locate HugeBuffer3 = HugeBuffer2 + 64
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu Nov 11, 2004 12:19 pm     Reply with quote

Thanks Neutone! This helps a lot.

Too bad only addition is allowed, other constructs are still failing:
Code:
int8 Buffer[100];
int8 Buffer2[10];
#locate Buffer  = 0x500 + 10       // v3.212: OK
#locate Buffer  = 0x500 - 10       // V3.212 Error: Expecting a declaration
#locate Buffer  = (0x500 + 10)     // V3.212 Error: Expression must be a constant or simple variable
#locate Buffer  = 0x500 + sizeof(Buffer2) // V3.212 Error: A numeric expression must appear here


I also found a bug, adding a value of 0x100 or larger to a referenced variable uses only the lower byte:
Code:
Int8 Buffer[64];
#locate Buffer   = 0x200 + 0x101    // ok
Int8 HugeBuffer1[64];
#locate HugeBuffer1 = Buffer + 0x101  // Error: uses only lower byte

Listfile
Code:
...
004     @SCRATCH
301-340 Buffer
302-341 HugeBuffer1       // Should have started at 0x402
F80     PORTAbits
...
RossJ



Joined: 25 Aug 2004
Posts: 66

View user's profile Send private message

PostPosted: Sun Nov 21, 2004 6:11 pm     Reply with quote

Have you considered the typemod instruction?

e.g.

Code:
typemod <,,,0x200,0x3FF> himem;

int8 himem buffer1[64];
int8 himem buffer2[64];


buffer1 will get allocated at 0x200.
buffer2 will get allocated at 0x240.
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Sun Nov 21, 2004 6:32 pm     Reply with quote

The funny thing is typemod has been in the Readme.TXT file for a long time, but it is not mentioned in the new manual that was recently released.
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