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

pointers

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



Joined: 23 Apr 2005
Posts: 4

View user's profile Send private message Send e-mail

pointers
PostPosted: Sat Apr 23, 2005 5:02 pm     Reply with quote

Hi all more experienced
I missed something... What is wrong by such construction ?

void lcd_writeline_rom(char lineno, char const * text) {
while (*text)

The compiler refuses *text in while statement because it's not a numeric expression... Strange behaving at least by me.

Regards

Igor
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Apr 23, 2005 6:25 pm     Reply with quote

Remove the "const" declarator, shown in bold below:

void lcd_writeline_rom(char lineno, char const * text)
igorp



Joined: 23 Apr 2005
Posts: 4

View user's profile Send private message Send e-mail

pointers
PostPosted: Sun Apr 24, 2005 3:02 pm     Reply with quote

I see... C Compiler Reference Manual page 232 Sad
I don't see any way how to send address of a string stored in the program memory to a procedure as a parameter. Am I right?

Igor
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 24, 2005 3:05 pm     Reply with quote

Yes. You can't pass a pointer to a constant string, in CCS.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

Re: pointers
PostPosted: Sun Apr 24, 2005 9:11 pm     Reply with quote

igorp wrote:
I see... C Compiler Reference Manual page 232 Sad
I don't see any way how to send address of a string stored in the program memory to a procedure as a parameter. Am I right?

Igor

Copy it to RAM and then pass a pointer to that buffer.
gustnado



Joined: 23 Apr 2005
Posts: 21
Location: Phoenix,AZ

View user's profile Send private message Visit poster's website AIM Address

PostPosted: Mon Apr 25, 2005 10:12 am     Reply with quote

As a new PIC programmer, I understand that the Harvard architecture imposes limitations in this area.

If I wanted to do something like the following normal C code, what is the best way with PCH/PCM? A printf in each case?

Code:

    char *cp;
    switch (i) {
       case 0:
           cp = "zero";
           break;
       case 1:
           cp = "one";
           break;
       default:
           cp = "huh?";
   }
   printf("Got %s\r\n", cp);

_________________
The best weather is bad weather
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Mon Apr 25, 2005 10:16 am     Reply with quote

This should be more efficient than a bunch of printf's
Code:

    char cp[5];
    switch (i) {
       case 0:
           strcpy (cp, "zero");
           break;
       case 1:
           strcpy (cp, "one");
           break;
       default:
           strcpy (cp, "huh?");
   }
   printf("Got %s\r\n", cp);

treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Mon Apr 25, 2005 11:32 am     Reply with quote

I use a 2d array alot.
Code:

const char error_txt[8][16] =
{
  "USART overflow",  // -0-
  "TXBuffer ovrflw", // -1-
  "RXBuffer ovrflw", // -2-
  "Bad Checksum",    // -3-
  "",                // -4-
  "LCD X exceeded",  // -5-
  "LCD Y exceeded",  // -6-
  ""                 // -7-
};

//========================== err_chk ===============================
void ChkErr(void) //print out any errors that occured
{
  int8 chk=0;
  fprintf(STDERR,"ERROR(%U): %s.\r\n",chk,error_txt[chk]);
}


I think this puts the stings in rom. And you can print easy. But your not passing a pointer. You could also do as suggested and memcopy.
gustnado



Joined: 23 Apr 2005
Posts: 21
Location: Phoenix,AZ

View user's profile Send private message Visit poster's website AIM Address

PostPosted: Mon Apr 25, 2005 1:01 pm     Reply with quote

Oddly enough, in my tests, the series of printf's are shorter than the strcpy's. The following shows number of instruction words (in decimal):

Code:

                 printf        strcpy
14 bit           10              14
16 bit            9              16


It appears to be inlining strcpy and part of printf.

Is there a way to tell it to not inline strcpy in this case (I would guess not)? #separate only works in the function declaration, not in its usage, as far as I can tell.

It also appears that there is no strncpy, which I often use to avoid future buffer over-runs.

treitmey's solution with the two dimensional array uses a lot of program memory to hold the leftover space for each entry, and thus is inefficient (space wise). I tried all sorts of things to have a constant array of pointers to strings (rather than treitmey's array of the strings themselves), without success. Does anyone know how to do that?

I know there are serious restrictions on the use of pointers due to the Harvard architecture (separate program and data address spaces), although it is possible in at least some processors (I'm new to PIC - I think only some families have a register to access tables in the program memory.)
_________________
The best weather is bad weather
Ttelmah
Guest







PostPosted: Mon Apr 25, 2005 2:42 pm     Reply with quote

The solution I used in the past to efficient use of a constant string, was to code a massive block like:
Code:

const char E_general[] = {
"Manual~Data~Setup~Alarms~Cal ~Wash ~Sample ~IP span~Zero~Timings~Clock~Language~High~XHigh~for ~"
"every ~secs~hours~mins~continuously~Cal Hi~"
};

And then either store the address of the start of each string in a seperate constant array, or (with a very long table...), search for each '~' marker, and store the byte number where this occurs. The output routine simply transfers characters from the specified start, till it sees the next '~' marker.

Best Wishes
igorp



Joined: 23 Apr 2005
Posts: 4

View user's profile Send private message Send e-mail

pointers
PostPosted: Mon Apr 25, 2005 2:42 pm     Reply with quote

I suggest such solution:
Code:

char const tabstr[]={"this string is over twenty characters\000\
second string\000\
thirth string, please\000"};

void lcd_writeline_rom(char lineno, char nostring) {
unsigned char i = 0;
// address tabstr has to be known here
while (nostring) {  //seek for first character of the selected string
  if (!tabstr[i++]) nostring--;
  }
// we have the index of first characters of wanted string in i
........


}

void main()
{
.......


 lcd_init();
 lcd_writeline_rom(0, 0);
 lcd_writeline_rom(1, 2);
.....
}


Two disadvantages :
1 - The procedure has to know where strings are stored
2- I am not able to find out how to do the continuation line in the IDE editor.
3- to find the selected string in any huge array takes some time.

I use it for LCD display (with running text if the string is longer than 16 characters).

Regards

Igor
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