![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
DireSpume
Joined: 07 Jan 2013 Posts: 31
|
const pointer not working |
Posted: Wed Feb 06, 2013 7:59 pm |
|
|
I can apparently pass a rom uint32 array (as a rom pointer) to a function and index into it correctly. But if I pass a rom char array, it will not index correctly. Can anyone explain what is going on here? I'm using PCH 4.140.
The code below gives the following output (NUL is 0, i.e. a bogus character):
RomChar, RomChar
NUL, h, 50
Code: |
typedef unsigned int32 uint32;
rom char str2[] = "RomChar";
rom uint32 Data[3] = { 40, 50, 60 };
void PrintNTime(rom char* str, rom uint32* ptr)
{
printf(str);
printf(", %s\r\n", str);
printf("%c, %c, %lu\r\n", str[4], str2[4], ptr[1]);
}
void main()
{
while(1)
{
delay_ms(1000);
PrintNTime(str2, Data);
}
}
| [/code] |
|
![](templates/subSilver/images/spacer.gif) |
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Thu Feb 07, 2013 2:39 am |
|
|
1) The "rom" qualifier has no effect in CCS C.
2) The manual includes this entry:
"How can a constant data table be placed in ROM?
--------------------------------------------------------------------------------
The compiler has support for placing any data structure into the device ROM as a constant read-only element. Since the ROM and RAM data paths are separate in the PICĀ® , there are restrictions on how the data is accessed. For example, to place a 10 element BYTE array in ROM use:
BYTE CONST TABLE [10]= {9,8,7,6,5,4,3,2,1,0};
and to access the table use:
x = TABLE [i];
OR
x = TABLE [5];
BUT NOT
ptr = &TABLE [i];
In this case, a pointer to the table cannot be constructed.
Similar constructs using CONST may be used with any data type including structures, longs and floats.
Note that in the implementation of the above table, a function call is made when a table is accessed with a subscript that cannot be evaluated at compile time."
The problem here being that the string constant is treated as a constant string, not as a variable char array that's had a copy of a constant string written to it. To get the effect you probably are looking for you need to
a) define a variable char array big enough and then explicitly copy the constant string to it using strcpy or similar or b) include the directive #device PASS STRINGS=IN_RAM which according to the manual is "a new way to pass constant strings to a function by first copying the string to RAM and then passing a pointer to RAM to the function." In other words doing the same thing as a) except the compiler does the copying for you.
RF Developer |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Thu Feb 07, 2013 12:36 pm |
|
|
Er, No.....
rom does have a meaning in CCS.
rom as a construct, is an alternative to const, _which allows pointers to be constructed_.
Look in the readme.txt with the compiler.
ptr=&table[i]. _can_ be constructed with a rom array.
However several key things apply:
The target has to 'know' the target is in ROM.
The format string in printf, _cannot be passed_. The format is parsed at compile time, so this won't work with either ROM or RAM arrays.
%s, expects a RAM char array, so again won't work.
You can produce the same effect, by accessing the characters yourself, just don't use printf. Avoids the need for a RAM buffer.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
DireSpume
Joined: 07 Jan 2013 Posts: 31
|
|
Posted: Thu Feb 07, 2013 2:23 pm |
|
|
Thanks Ttelmah, I actually learned that the rom qualifier exists from reading one of your responses to another thread. I'm using #device CONST=READ_ONLY because it seems silly to have two keywords that do the exact same thing (more or less), and changing the meaning of an established C keyword is very confusing and generally stupid IMO. Interestingly, I can find no mention of the rom qualifer anywhere in the manual (but it is in the readme.txt).
And I did discover the quirk about passing strings to printf() in the form of a variable doesn't work, and thanks for the explanation on that. I find it interesting that printf() is able to accept RAM pointers, ROM pointers, and string literals with no problem, but if you make your own function that accepts a char* you have to specify rom or ram (not-rom) and can then only accept one or the other. I really wish this stuff was explained in the manual.
Okay, onto the unresolved issue at hand, which is that the code in the OP works for uint32, but not for char. In other words, str2[4] and ptr[1] both work properly, but str[4] does not (returns zero instead of 'h', which I'm assuming is because it's reading the wrong memory space). I've tried it with #device PASS_STRINGS=IN_RAM and without, but no difference. |
|
![](templates/subSilver/images/spacer.gif) |
DireSpume
Joined: 07 Jan 2013 Posts: 31
|
|
Posted: Fri Feb 08, 2013 11:53 am |
|
|
Okay, I figured it out. There is a bug in printf() when using %c with romstr[] when romstr is a rom pointer. The printf in the following code works fine for every single argument except for the first one, where it prints a NUL character instead of 'k'. Using %u or assigning to a char variable first both work correctly, as do ram pointers with %c.
The result of the following code is "[NUL], k, 107, k, 20, d/r/n".
Code: |
typedef unsigned int16 uint16;
rom uint16 data[] = { 10, 20, 30 };
char str1[] = "Spiders";
rom char str2[] = "Snakes";
void PrintStuff(rom char* romstr, char* ramstr, rom uint16* ptr)
{
char Chr = romstr[3];
printf("%c, %c, %u, %c, %lu, %c\r\n", romstr[3], Chr, romstr[3], str2[3], ptr[1], ramstr[3]);
}
void main()
{
while(1)
{
delay_ms(1000);
PrintStuff(str2, str1, data);
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Fri Feb 08, 2013 12:12 pm |
|
|
I have a 'sneaky suspicion' you will find it works OK with a slightly older compiler. I've had quite a few problems with 4.140 having oddities. 4.137, has proved much more reliable in general for me....
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|