|
|
View previous topic :: View next topic |
Author |
Message |
uslimey
Joined: 27 Aug 2011 Posts: 22 Location: Baltimore, MD
|
Point to const struct array |
Posted: Mon Oct 31, 2011 7:23 am |
|
|
I created a typdef struct for a calibration table.
Code: |
typedef struct {
signed int16 ipVal; // filtered ADC value
float32 opVal; // corresponding real value as floating point
} calRecord;
|
I then created a const array of calibration records...
Code: |
const calRecord calDT670[144] = {
{181, 5000}, // count : temperature x 10 (k)
{225, 4900.116713},
{270, 4801.94981}....
|
If I address the table directly I can read the records without issue. The problem is that I need to create a number of these tables and access them with pointers. I can't seem to figure out how to get a pointer to point to a const struct array. Any help would be appreciated. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Mon Oct 31, 2011 8:25 am |
|
|
Use rom, rather than const. (rom, not #ROM).
It's all down to the memory structure of the PIC, and history.
The PIC, has separate memory spaces for the program and code. Not the single linear memory space of chips like the 808x, etc..
Historically older PICs, could not directly read their ROM.
So when CCS first implemented const data tables, they 'cheated', and simulated the effect, using the method that worked within the PIC limitations, and generated a program that returned the bytes required. As such though it meant that a pointer could not be constructed to these.
To help avoid this being too much of a limitation, a 'shortcut' was added to the language, where using the construct (say):
putc("fred");
resulted in the putc function being called four times, with each character in turn.
Latter when running in ANSI emulation mode, the meaning of 'const' was changed to be compliant with this, being a RAM based table, that is 'read only'. To these a pointer can be constructed, but it means that the table has to be copied into RAM at runtime. Costly on RAM space. This is what happens if you switch the compiler to ANSI mode.
However CCS also decided that on the latter chips that did allow code to access the ROM, they would implement a form that did support pointers, and this is given by using the rom keyword, rather than const keyword. It makes things slightly bulkier, since extra code has to be added to support this, but does generally work.
So you have:
CCS mode
const data tables - small but no pointer support.
rom data tables - code larger, but supports pointers.
ANSI mode
const data tables - copied to RAM, and support pointers, but uses a lot of RAM
rom data tables - stored in ROM.
You can also switch the mode of ROM storage so all const tables allow pointers, using:
#device const=ROM
This though prevents the old CCS 'shortcut' usage where calling a function that expects an integer, with a constant string, repeatedly calls the function for each character in the string.
This is documented in the readme.txt with the compiler.
Best Wishes |
|
|
uslimey
Joined: 27 Aug 2011 Posts: 22 Location: Baltimore, MD
|
pointer to const struct array |
Posted: Mon Oct 31, 2011 8:39 am |
|
|
I tried the rom method described...
Code: |
calRecord rom calDT670[144] = {
{181, 5000}, // count : temperature x 10 (k)
{225, 4900.116713},
{270, 4801.94981}....
|
I still can't get the pointer to point to the table correctly...
Maybe I am missing something... The pointer is declared as follows...
Code: |
calRecord *calData;
...
calData = calDT670;
|
I tried accessing records as follows...
Code: |
result = *calData[0].opVal /// DOESN'T WORK
result = (*calData)[0].opVal /// DOESN'T WORK
result = *calData[0]->opVal /// DOESN'T WORK
|
Any ideas? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Mon Oct 31, 2011 8:42 am |
|
|
Look at the readme.
The point is what you have is a _rom_ pointer. Remember what I said about the data space of the chip. Something has to tell the code that this is rom, not ram. So you have to construct pointers as:
rom *fred;
fred is a pointer to rom etc...
It is in the readme.
Best Wishes |
|
|
uslimey
Joined: 27 Aug 2011 Posts: 22 Location: Baltimore, MD
|
|
Posted: Mon Oct 31, 2011 8:58 am |
|
|
Tried...
rom *pointer;
resulted in a compile error... "...expecting a ("
in the ref manual the example for a pointer to a const using the follwoing syntax...
const char *cptr;
This only works with character data types...
Still stuck! |
|
|
uslimey
Joined: 27 Aug 2011 Posts: 22 Location: Baltimore, MD
|
|
Posted: Mon Oct 31, 2011 9:24 am |
|
|
Seems like the pointer to the rom struct array should be declared as follows:
Code: |
calRecord rom *calData;
calData = calDT670; //Current Record;
|
but here's the gotcha... the record values CANNOT be accessed with any of the following:
Code: |
ipValue = *calData.ipVal;
ipValue = (*caldata).ipVal;
ipValue = *calData->ipVal;
|
However if I create a new variable of the structure type I can access the members.
For example,
Code: |
calRecord LastRecord = *calData;
ipValue = LastRecord.ipVal;
opValue = LasRecord.opVal;
|
Hopefully this will help someone else!
Thanks. |
|
|
andrewg
Joined: 17 Aug 2005 Posts: 316 Location: Perth, Western Australia
|
|
Posted: Tue Nov 01, 2011 12:48 am |
|
|
uslimey wrote: | Code: |
ipValue = *calData.ipVal;
ipValue = (*caldata).ipVal;
ipValue = *calData->ipVal;
|
|
For the first, the dot has precedence over the asterisk, so the code is effectively: Code: | ipValue = *(calData.ipVal); | which isn't going to work. The second variant should work, but as you're trying to dereference a rom pointer, I could understand that not working given the PIC architecture.
The third variant is also wrong, it should simply be: Code: | ipValue = calData->ipVal; | I would expect that to work.
Having said all that, I've frequently found your workaround of assigning a structure to a temporary local RAM variable to be extremely helpful in cutting down code size, and for that reason is my preferred method in most cases. _________________ Andrew |
|
|
|
|
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
|