CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

What is the proper use of extern char rom in header file?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kda406



Joined: 17 Sep 2003
Posts: 97
Location: Atlanta, GA, USA

View user's profile Send private message

What is the proper use of extern char rom in header file?
PostPosted: Mon Sep 12, 2016 1:46 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Sep 12, 2016 4:40 pm     Reply with quote

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: 19552

View user's profile Send private message

PostPosted: Tue Sep 13, 2016 12:55 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Sep 13, 2016 7:36 am     Reply with quote

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: 19552

View user's profile Send private message

PostPosted: Tue Sep 13, 2016 8:48 am     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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