Help with Compiler error

Thread Starter

Vulcan27

Joined Apr 9, 2014
5
Hi. I'm using MPLAB X IDE and XC8. This code was originally written for MPLAB 8 and C18. Fairly new to PICs so I wanted to learn the latest software but I keep encountering problems with legacy coding not being compatible. In this caes it is for a PIC18F452 to a LCD.

The header file (part) gives this error when I clean and build project:

/* prototypes */
void delay_ms(unsigned char);
void lcd_busy(void);
void lcd_i_write(unsigned char);
void lcd_d_write(unsigned char);
void lcd_init(void);
void putrs_lcd(const rom char *);
../lcd.h:28: error: (372) "," expected
void puts_lcd(char *);
char ntox(unsigned char);
char *btox(unsigned char, char *);
char *itox(unsigned int, char *);
char *ltox(unsigned long, char *);


and the .c file (part) gives this error:

void putrs_lcd(const rom char *buffer) ../lcd.c:222: error: (372) "," expected
{
while (*buffer) {
lcd_d_write(*buffer);
buffer++;
}
}

Any suggestions as to where I'm going wrong?

Steve
 

ErnieM

Joined Apr 24, 2011
8,377
I'm still dedicated to C18 and have only done a few experiments with XC8.

Looks like XC8 does not like the rom keyword we so love in C18. Keyword "rom" was necessary to let the compiler know to use a different method to retrive a variable from program memory or data registers.

My guess is the compiler authors recognized a "const" variable should always be places in program memory and thus dropped the "rom" keyword.

MPLAB® XC8 C Compiler User’s Guide said:
3.4.3.3 HOW DO I PLACE VARIABLES IN PROGRAM MEMORY?
The const qualifier implies that the qualified variable is read-only. As a consequence
of this, any variables (except for auto variables or function parameters) that are
qualified const are placed in program memory, thus freeing valuable data RAM. See
Section 5.5.3 “Variables in Program Space”, for more information. Variables that are
qualified const can also be made absolute, so that they can be positioned at an
address you nominate; see Section 5.5.4.2 “Absolute Objects in Program
Memory”.
Again my guess is just drop the "rom" in these statements. Note you would still need two forms of functions when supplying either data or program ("const") variables.
 

MrChips

Joined Oct 2, 2009
30,806
Just drop the const rom altogether:

Code:
void putrs_lcd(char *buffer)
{
   while (*buffer)
      lcd_d_write(*buffer++);
}
 

Thread Starter

Vulcan27

Joined Apr 9, 2014
5
Thanks that does solve this error. Unfortunately other errors now come up when compiling. I will try going back to MPLAB 8 and C18 as it does seem too time consuming to try and rewrite code, especially with my limited knowledge.
 

spinnaker

Joined Oct 29, 2009
7,830
Thanks that does solve this error. Unfortunately other errors now come up when compiling. I will try going back to MPLAB 8 and C18 as it does seem too time consuming to try and rewrite code, especially with my limited knowledge.
It really is not that difficult. What is the new error?
 

ErnieM

Joined Apr 24, 2011
8,377
Thanks that does solve this error. Unfortunately other errors now come up when compiling. I will try going back to MPLAB 8 and C18 as it does seem too time consuming to try and rewrite code, especially with my limited knowledge.
The C18 is a fine compiler, and it will now be eternally stable; such is the blessing of obsolescence. I have bad memories of one major upgrade that broke some difficult code I had involving a boot loader: code and the link script needed rewrites.

I’m keeping several projects written for C18 in C18. No need to modify good code just because there is a new bright and shiny toy to play with.
 

JohnInTX

Joined Jun 26, 2012
4,787
..it will now be eternally stable; such is the blessing of obsolescence.
That should be engraved on a plaque somewhere important.

Again my guess is just drop the "rom" in these statements. Note you would still need two forms of functions when supplying either data or program ("const") variables.
Its correct that you don't need 'rom' to specify program memory like HiTechC (progenitor of XC8) wanted. Any non-auto 'consts' will go into ROM.

I don't think you need separate functions to deal with const in ROM vs. variables of the same type or defined type. In HiTechC (PICC18 at least), if the compiler detects variables in ROM and RAM will be used by a function, it generates code that executes at run-time to examine the address of the variable to determine whether its in RAM or ROM then jumps to a direct read from RAM or table reads from ROM as required. I've ported some routines from HiTech to XC8 that accept pointers to struct in either ROM or RAM and they work OK - though I haven't looked at the assembler output to see exactly what's going on...

My .02
 
Last edited:

ErnieM

Joined Apr 24, 2011
8,377
I don't think you need separate functions to deal with const in ROM vs. variables of the same type or defined type. In HiTechC (PICC18 at least), if the compiler detects variables in ROM and RAM will be used by a function, it generates code that executes at run-time to examine the address of the variable to determine whether its in RAM or ROM then jumps to a direct read from RAM or table reads from ROM as required. I've ported some routines from HiTech to XC8 that accept pointers to struct in either ROM or RAM and they work OK - though I haven't looked at the assembler output to see exactly what's going on...
That is very good to know. Discovering pointers were different depending on where the variable was located was a stumbling block getting C18 to dance for me.

Some lessons are easier learned then unlearned. Good to know there may actually be a reason to use XC8.
 

JohnInTX

Joined Jun 26, 2012
4,787
That is very good to know. Discovering pointers were different depending on where the variable was located was a stumbling block getting C18 to dance for me.
Some lessons are easier learned then unlearned. Good to know there may actually be a reason to use XC8.
Maybe. The way HiTech did it was to use unused bits in the pointer variable to specify ROM or RAM. Unfortunately, we found that the pointer calculation did not work correctly for some big pointers >64K. HiTech sent a patch that solved our problem. Unfortunately again, later we found that there were other types of big pointers that weren't fixed. By that time, they had updated to OCG which didn't compile the RTOS at all so that was that. When XC8 arrived, I queried uCHIP to see if the big pointer issues were fully resolved and got ??? in return.

If I were to start a real project with XC8 (or any other compiler, I guess now) I'd throw some complex/big stuff at it and see what it did in the dusty corners of C that I always seem to find. Or just stick with 'eternally stable' as you suggest.
 

djsfantasi

Joined Apr 11, 2010
9,163
Just a question?

You have defined your input as const char or const uint_t8. This is a value between 0-255. Is this sufficient for a pointer?

Then you increment a const. How does this work?

If you want to change the passed parameter in the calling code, wouldn't you use the & operator instead?

New to C myself, so I often have to write test code to learn how the constructs work. I have always used the & operator in my function prototypes when the code needs to pass values from the function to the calling routine.
 
Last edited:

ErnieM

Joined Apr 24, 2011
8,377
First you get two demerits for both hijacking a thread and not being crystal clear what your own question is.

the putrs_lcd (char * buffer) function above accepts the char * buffer as the input is is NOT taking in a character (constant or not) but a pointer to the string. The buffer variable (pointer) will be sized as appropriate to your hardware automatically by the compiler.

A pointer to a constant string may be freely changed, poked, prodded, incremented, decremented, stamped, folded, indexed, briefed, debriefed, or numbered.

The underlying string of course may not be changed if it is a constant, though your compiler may not be smart enough to throw you an error since you are indirectly referencing the string. To protect against that you define the function as a pointer to a constant, so your function would fail compilation if you try to write anything. Reads are of course OK.
 
Top