|
|
View previous topic :: View next topic |
Author |
Message |
kda406
Joined: 17 Sep 2003 Posts: 97 Location: Atlanta, GA, USA
|
What is the proper use of extern char rom in header file? |
Posted: Mon Sep 12, 2016 1:46 pm |
|
|
What is the proper use of "char rom" in a header file for the CCS compilers? I am currently using 5.046 with a PIC18F8722, but I don't think the version or chip matters to the question. I am writing a program that deals with a great amount of repetitive string data and need to store the information as efficiently as I can.
From CCS's manual: Quote: | A special method allows the use of pointers to ROM. This method does not contain extra code at the start of the structure as does constant. For example:
char rom commands[] = {“put|get|status|shutdown”}; |
Unfortunately, they do not show how to declare it correctly in a header file for the entire project to use this string.
Code: | // USB.c
#include "USB.h"
char rom c_nMessUnchanged[] = {"(unchanged)"};
char rom c_nMessInvalidInput[] = {"Invalid input"}; |
Code: | // USB.h
extern char rom c_nMessUnchanged[];
extern char rom c_nMessInvalidInput[]; |
Code: | // From Settings.c
#include "USB.h"
fprintf(USB,c_nMessInvalidInput); // Print that it was invalid input |
Results in the following enigmatic error:
Quote: | Error#44 Internal Error - Contact CCS Hidden forward reference 32 from 1620 |
However, if I remove the keyword "rom" from the code, which takes me back basically to the ANSI C, it compiles and works with no problem. I suspect I am using the "rom" keyword in the header file incorrectly. Suggestions?
Thanks,
Kyle |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 12, 2016 4:40 pm |
|
|
Just to be sure, what compilation method are you using ?
1. The "one big file" method, where all modules are added to the
main source file with #include statements. This is the most
common method for CCS users.
-or-
2. Multiple Compilation Units. This is less common.
https://www.ccsinfo.com/faq.php?page=multi_comp_units |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Tue Sep 13, 2016 12:55 am |
|
|
Some other things:
You seem to be changing CCS source files. USB.h, and USB.c are supplied files. Much better to put your new declarations into your own files. There is also something very odd about your declaration order. You have USB.c, including USB.h, but USB.h does not include USB.c (where the actual declarations are). If you are using multiple compilation units (PCM_programmer's question), then USB.c would need to be compiled first, and this would have to be linked into the main code at compilation time.
The syntax though is dangerous. Use:
fprintf(USB,"%s",c_nMessInvalidInput); // Print that it was invalid input
Printf (and the derivatives like fprintf), all expect a const 'format' string, followed by what is to be printed using that format. You are using the rom 'string' as the format string. Now this will work (a text string will be printed if this is the format string), but has a big 'caveat'. The compiler will parse this for escape sequences. So if (for example) your string contained '%', this would cause problems.....
Far better to 'KISS'.
A demo, using rom strings, just printing to RS232.
maintestromptr.c
Code: |
#include <maintestromptr.h>
#include "messages.h"
void main()
{
while(TRUE)
{
//now just print the ROM message
fprintf(DEMO,"%s",c_nMessUnchanged); //send the message out the RS232
delay_ms(1000);
}
}
|
maintestromptr.h
Code: |
#include <18F4620.h>
#device ADC=10
#use delay(crystal=20000000)
#use RS232(UART1, baud=9600, ERRORS, stream=DEMO)
|
messages.h
Code: |
char rom c_nMessUnchanged[] = {"(unchanged)"};
|
|
|
|
kda406
Joined: 17 Sep 2003 Posts: 97 Location: Atlanta, GA, USA
|
|
Posted: Tue Sep 13, 2016 7:36 am |
|
|
With your help, it seems to be working. I post the following in hopes of helping others.
I am using multiple compilation units. This project has 32 C files.
Ttelmah, I apologize for the odd declarations. I was attempting to make meaningful excerpts from real files which are extremely long.
You make an excellent point about using fprintf without a format string.
So far, it seems the solution is to put the rom variable into a header file.
Code: | //messages.h
#ifndef _USB_MENU_MESAGES_H
#define _USB_MENU_MESAGES_H
char rom c_nMessUnchanged[] = {"(unchanged)"};
#endif |
I shy away from placing variable declarations in header files. Normally, variables should be declared in the C files and linked among the compilation units using a header file with an extern keyword. But, as CCS's manual states, this is a special method. For the most efficient string message storage I will just have to do what works to get the job done.
THANKS for the help.
-Kyle |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Tue Sep 13, 2016 8:48 am |
|
|
My current project has 38 'C' files, and 42000 lines of code. I don't use MCU's, because the code is smaller, and runs better compiled as one item. It takes less than a 20 seconds to compile this.
CCS was designed as a non linking compiler, and still runs better treated this way. |
|
|
|
|
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
|