|
|
View previous topic :: View next topic |
Author |
Message |
peaps
Joined: 15 Sep 2008 Posts: 11 Location: Hemel Hempstead, Hertfordshire, UK
|
lcd_putc() functionality |
Posted: Fri Oct 03, 2008 7:07 am |
|
|
I am bemused as to how this function is able to print strings. The definition of the function clearly accepts a char, not a char pointer and there is no looping within the function to parse an array of chars. How then does it manage to print a literal string to the lcd?
Code: | void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
} |
E.g This will compile, and work:
Code: | void main void() {
lcd_putc("test string");
} |
Andy |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Fri Oct 03, 2008 7:41 am |
|
|
It's a general built-in feature of CCS C functions with character parameter.
But it only works with ROM constants, that are copied per character. The general valid syntax is printf(putc,string). |
|
|
peaps
Joined: 15 Sep 2008 Posts: 11 Location: Hemel Hempstead, Hertfordshire, UK
|
|
Posted: Sat Oct 04, 2008 3:34 am |
|
|
Quote: | The general valid syntax is printf(putc,string). |
I don't understand this. How does that work? How are you meant to be able to write code when there is some compiler magic going on in the background?
Assuming that a char can be passed as an argument to a function, that function will simply process the code within it, using the char.
Now when you send a char pointer, what happens to the flow of code? Does the same function execute multiple times or something?
In the case of lcd_putc, there is a switch that compares the char c with various char codes. I don't understand how you can effectively 'overload' a function that you haven't written a definition for. If this is some magic, then I am off to use another compiler.
Andy |
|
|
Ttelmah Guest
|
|
Posted: Sat Oct 04, 2008 5:14 am |
|
|
Key thing to understand, is that you can't have pointers to constants (though see latter). The PIC, has an architecture, where the ROM, and RAM, are in different memory spaces. Also most of the older PICs, cannot read/write their own ROM. Hence a 'constant' array, is actually a program, to return a value, based on the number it is called with. This works fine for things wanting to access a value in an array like 'array[4]', but makes it impossible to handle pointer based operations like strings passed to functions.
Now CCS, added a shortcut, to help the limitations in this, where if you pass a constant array, to a function that accepts a single char, value, the function will automatically be called repeatedly for each value in the array. This is documented in the manual. No 'magic' involved. Look at the section 'Function definition' in the manual.
On the more recent flash PICs, the ability to access the ROMs has appeared in the hardware, and on these, with the latter compilers, you can use the 'ROM' declaration, instead of the 'const' declaration, to access a constant array with pointer operations supported. You can also change the default operation, so that const arrays can be used this way, with a #device statement.
The printf, is also documented, and is also a syntax used on several other compilers. printf("string",vals), functions as normal, and sends it's output, to putc. printf(function_name,"string",vals), instead sends it's output to 'function_name'. Printf in the manual.
Best Wishes |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat Oct 04, 2008 6:44 am |
|
|
As said in the CCS C readme.txt, the new storage classe qualifier ROM should allow usage of pointerswith rom constants.
Quote: | These three storage modes may be set directly using one of the following qualifiers:
ROMI Traditional CCS method to store in ROM optimized for access from indexed arrays
ROM New method to save data in ROM optimized for when the user needs pointers to the data
_READONLY Marks the data item as read only, defaults to RAM (like ANSI wants)
By default the CONST keyword is the same as ROMI. |
But wasn't yet able to see ROM work. I saw, that e. g. PCH generated out of bounds accesses for char rom xx[] constants. I basically didn't understand, what kind of flash rom access is intended with this storage class.
With PCD, the PSV (program space visibility) feature could be used to allow more effective constant access. But I don't think that it's used by CCS C up to now.
Regards,
Frank |
|
|
peaps
Joined: 15 Sep 2008 Posts: 11 Location: Hemel Hempstead, Hertfordshire, UK
|
|
Posted: Sat Oct 04, 2008 9:13 am |
|
|
I see. Thanks both for the input.
Not sure if this is a good thing or not really. Doesn't make porting to a different compiler/architecture any easier.
Andy |
|
|
Ttelmah Guest
|
|
Posted: Sat Oct 04, 2008 9:23 am |
|
|
Yes, you have to restructure the program slightly. ROM pointers do work, but use more program space than the const format, and the pointers themselves have to be declared as ROM pointers, requiring overloading the function, if you want it to handle RAM pointers as well. The 'shortcut', is quick and efficient, but much more limited in what it can do.
Best Wishes |
|
|
|
|
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
|