View previous topic :: View next topic |
Author |
Message |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
How to automatically locate RAM buffers? |
Posted: Thu Nov 11, 2004 4:22 am |
|
|
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
|
|
Posted: Thu Nov 11, 2004 5:58 am |
|
|
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
|
|
Posted: Thu Nov 11, 2004 7:00 am |
|
|
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
|
|
Posted: Thu Nov 11, 2004 9:14 am |
|
|
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
|
|
Posted: Thu Nov 11, 2004 12:19 pm |
|
|
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
|
|
Posted: Sun Nov 21, 2004 6:11 pm |
|
|
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
|
|
Posted: Sun Nov 21, 2004 6:32 pm |
|
|
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. |
|
|
|