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

String constants as arguments to in-built functions

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



Joined: 13 Dec 2010
Posts: 4

View user's profile Send private message

String constants as arguments to in-built functions
PostPosted: Fri Sep 30, 2011 4:23 pm     Reply with quote

Hi,
I've tried a number of times to use string-constants as arguments to in-built string functions which don't modify the string.
Whenever I try doing this I get the following error (or similar):
Code:
*** Error 51 "PATH" Line 98(51,58): A numeric expression must appear here


The code used that gave the above error is:
Code:
void usb_debug_log(unsigned int8 area, unsigned int8 severity, char const message[])
{
   sprintf(out_data, "99%3u%3u%48s", area, severity, message);
   usb_write();
}


Does anyone know why this is? Are there any workarounds for this issue to allow passing string constants to such functions?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 30, 2011 4:55 pm     Reply with quote

If I make your code into a test program, and add the two #device
statements shown below, I get this output in MPLAB simulator:
Quote:

99 5 648PATH


Test program:
Code:

#include<16F877.h>
#device PASS_STRINGS=IN_RAM
#device CONST=READ_ONLY
#fuses HS,NOWDT,BROWNOUT,PUT,NOLVP
#use delay(clock=20M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

char out_data[20];

void usb_debug_log(unsigned int8 area, unsigned int8 severity, char const message[])
{
sprintf(out_data, "99%3u%3u48%s", area, severity, message);

printf("%s", out_data);
}


//======================================
void main()
{
usb_debug_log(5, 6, "PATH");

while(1);
}


For information on the #device statements, see the CCS manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf

This was tested with compiler vs. 4.124.
rconan



Joined: 13 Dec 2010
Posts: 4

View user's profile Send private message

PostPosted: Fri Sep 30, 2011 5:14 pm     Reply with quote

Thanks for the prompt reply.
That seems to fix the problem I was having but raises an incompatibility with the USB HID driver included with CCS.
Seems the usb_hid_desc.h header populates a constant array using values from another constant array (line 241) which, using that #device statement, are stored in RAM which it cannot read from at compile time.

Seems like these two behaviours are mutually exclusive? Is there a way to get around that other than rewriting usb_desc_hid.h to not depend on that behaviour?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 30, 2011 5:25 pm     Reply with quote

Quote:

void usb_debug_log(unsigned int8 area, unsigned int8 severity, char const message[])

The simple way would be to re-write your function to conform to CCS
standards. Get rid of the 'const' and the brackets for the last parameter,
and just make it be char *message. Then add the #device
PASS_STRINGS=IN_RAM but not the other #device statement.
rconan



Joined: 13 Dec 2010
Posts: 4

View user's profile Send private message

PostPosted: Fri Sep 30, 2011 5:30 pm     Reply with quote

That works. Kind of a shame this involves an extra step to copy the string into RAM rather than simply passing a pointer to the data in program memory. I guess this is because program memory and RAM aren't in the same address space so it can't do that?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Sep 30, 2011 5:32 pm     Reply with quote

That's right.
rconan



Joined: 13 Dec 2010
Posts: 4

View user's profile Send private message

PostPosted: Fri Sep 30, 2011 5:37 pm     Reply with quote

Thanks for all your help.
Ttelmah



Joined: 11 Mar 2010
Posts: 19480

View user's profile Send private message

PostPosted: Sat Oct 01, 2011 2:14 am     Reply with quote

Or, use ROM, rather than CONST.

This is down to history, and the layout of the PIC memory spaces, and CCS 'predating' later standards.
On the earliest PIC's, there is no direct way of accessing data stored in program memory. So for constant data, CCS built a program, that used RETLW instructions, to return the value from the index requested. This format was used for 'const' data.
When they moved to trying to support ANSI style const, several things had to change. First, the PIC's themselves had evolved, and most now offered instructions to read program memory. Const in ANSI, is designed for processors in general where data is in RAM, so the ANSI const construct, just attempts to protect this RAM data from being written. This is the form emulated by the 'PASS_STRINGS_IN_RAM' form.
However the presence of the ability to directly read ROM, does make it potentially possible to have a 'pointer to ROM', but would mean having an extra bit to say that this is to ROM, rather than RAM, or some other way of 'distinguishing' the address space. This is the form generated by the ROM constant.
CCS has the ability to change what the ROM, and CONST keywords actually 'do'. Look at the 'readme.txt' with your compiler. However as you have found, changing the operation of these can easily bring problems.

Best Wishes
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