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 support@ccsinfo.com

String in ROM to RAM ?

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



Joined: 15 Dec 2003
Posts: 51
Location: Italy

View user's profile Send private message

String in ROM to RAM ?
PostPosted: Sun Jan 25, 2015 1:46 pm     Reply with quote

Hello,
in the forum there are many posts but, reading the previous posts, I have not found an answer.
Compiler 5.037 and PIC24EP512GU810

place a simple code to explain:
Code:

#include      <24ep512gu810.h>         
#FUSES NOWDT                    
#FUSES NOBROWNOUT           
#FUSES NOJTAG               
#FUSES DEBUG
#FUSES HS
#FUSES PR
#FUSES WPRES32
#DEVICE ADC=10

#device ICD=TRUE
#device ICSP=1
#device const=rom
#device PASS_STRINGS=IN_RAM
#use delay(clock=40000000,crystal=8000000) 

//uart 2
#pin_select U2TX=PIN_E4
#pin_select U2RX=PIN_E6
#use rs232(UART2, baud=9600, stream=UART2)


void main (void)
{
 rom char *version[] ={"AAA","BBB","CCC"};
 rom  char *ptr;
 char string[5];
 ptr = version[1];
 //strcpy(string,ptr)              // Not work
 fprintf(UART2,"%s",ptr);       // Ok
// fprintf(UART2,"%s",string); // Not work
 while(1){
  restart_wdt();
 }
}


the above code works and the fprintf see the content of the char ROM version.
But I need to use the string contained in the version without the 'use of fprintf.
(I have to pass it as a pointer to a function that will display it on a LCD graphic)
if I put ptr does not work, I should probably be able to copy it to a temporary variable on RAM.
how can you do? Strcpy does not work
example
Code:
strcpy(string,ptr)
not work.
the structure of the function is as follows where s is the pointer to the string passed
Code:
ft_void_t Ft_Gpu_CoCmd_Text(Ft_Gpu_Hal_Context_t *phost,ft_int16_t x, ft_int16_t y, ft_int16_t font, ft_uint16_t options, ft_char8_t * s)


Thank You
guy



Joined: 21 Oct 2005
Posts: 291

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

PostPosted: Sun Jan 25, 2015 2:08 pm     Reply with quote

You can use sprintf() instead of printf() and 'print' to a string (very useful when using printf formatting features), or you can read from the ROM-array char by char into the RAM variable until zero is reached.
There may be more elegant ways though.

Also you might be able to optimize your code and send a ROM pointer to the function (if applicable).
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Sun Jan 25, 2015 2:28 pm     Reply with quote

You can pass it as a pointer to your function, but the function declaration needs to have it as a ROM pointer.
The key is that ROM pointers are distinct from RAM pointers. Some of the CCS functions are internally overloaded to handle them, some aren't.
If you want to do an equivalent to strcpy, then you can use:
Code:

#include      <24EP256GU810.h>         
#FUSES NOWDT                   
#FUSES NOBROWNOUT           
#FUSES NOJTAG               
#FUSES DEBUG
#FUSES HS
#FUSES PR
#FUSES WPRES32
#DEVICE ADC=10

#use delay(clock=40000000,crystal=8000000)

//uart 2
#pin_select U1TX=PIN_E4
#pin_select U1RX=PIN_E6
#use rs232(UART2, baud=9600, stream=UART2)

void strromcpy(char *dest, rom char *source)
{
   while (*source != '\0')
       *(dest++) = *(source++);
   *dest='\0';
}

void main (void)
{
 rom char *version[] ={"AAA","BBB","CCC"};
 char string[5];
 strromcpy(string,version[1]);   
 fprintf(UART2,"%s",string);   
 while(TRUE)
 {
  restart_wdt();
 }
}


You are also making it very complex, by changing the settings several ways. const=rom, changes the default behaviour of const, then PASS_STRINGS also changes this. If you are using the rom directive get rid of both of these.

You are trying to mix three different ways of doing the same thing. Use one or the other.


Last edited by Ttelmah on Tue Jan 27, 2015 9:45 am; edited 1 time in total
Max



Joined: 15 Dec 2003
Posts: 51
Location: Italy

View user's profile Send private message

PostPosted: Mon Jan 26, 2015 2:10 am     Reply with quote

Hello Ttelmah,
I tried the code but to me it does not work.
I tried with ICD3 in debugger, during the 'execution of
Code:
strromcpy
resets, never comes to run the line
Code:
fprintf(UART2,"%s",string);

Obviously if the call to
Code:
strromcpy
the does not reset.
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Mon Jan 26, 2015 2:15 am     Reply with quote

You may have a compiler problem. I tried with 5.028, which I'm currently using as seeming to be more reliable than the latest releases, and it works as posted. Note I'm using the 256 processor (didn't have the 512).
Max



Joined: 15 Dec 2003
Posts: 51
Location: Italy

View user's profile Send private message

PostPosted: Mon Jan 26, 2015 3:26 am     Reply with quote

I added a forced to exit the while loop:
Code:
void strromcpy(char *dest, rom *source)
{
   unsigned int8 t=0;
   while ((*source) != '\0'){
       *(dest++) = *(source++);
       if(t==3)
        break;
       t++;
   }
   *dest='\0';
}

I changed the content in the rom to better understand
Code:
rom char *version[] ={"123","456","789"};


and I get the following results printed:

Code:
 if t==0 -> 4
if t==1 -> 46
if t==2 -> 467
if t==3 -> 4679
if t==4 -> reset
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Mon Jan 26, 2015 4:02 am     Reply with quote

The retrieval code is not working. It's jumping forward two characters for every one being retrieved. Force the size to a char in the declaration, it's assuming an int16. It should have the char there (mistype), but on the older compiler, it worked without it....
Max



Joined: 15 Dec 2003
Posts: 51
Location: Italy

View user's profile Send private message

PostPosted: Mon Jan 26, 2015 7:05 am     Reply with quote

I haven't understand to what definition are you referring to? Can you explain it with an example, please?
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Mon Jan 26, 2015 8:00 am     Reply with quote

Code:

void strromcpy(char *dest, rom char *source)
Max



Joined: 15 Dec 2003
Posts: 51
Location: Italy

View user's profile Send private message

PostPosted: Tue Jan 27, 2015 7:21 am     Reply with quote

Ttelmah wrote:
Code:

void strromcpy(char *dest, rom char *source)

Thanks, now works !
only problem that I do not understand is that in 'example above no matter insert
Code:
#device PASS_STRINGS = IN_RAM
and gives no error.

While in my application if I do not put
Code:
#device PASS_STRINGS = IN_RAM

the compiler generates me the 'error:
Code:
Attempt to create a pointer to a constant
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Tue Jan 27, 2015 8:45 am     Reply with quote

Are you declaring the constants as 'rom', or 'const'?.
It matters.

rom, constructs a constant, for which pointers can be constructed. const creates one for which it can't. PASS_STRINGS=IN_RAM, tells the compiler to _automatically_ 'virtualise' pointer accesses to const strings to the RAM address space, so a pointer can be constructed.
Max



Joined: 15 Dec 2003
Posts: 51
Location: Italy

View user's profile Send private message

PostPosted: Tue Jan 27, 2015 12:07 pm     Reply with quote

I have declared all constants "rom"
I replaced all
Code:
const
with
Code:
rom
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Tue Jan 27, 2015 3:52 pm     Reply with quote

So does it work?.

What happens with the example as posted (I have amended the rom declaration in it)?. This runs perfectly for me.
Max



Joined: 15 Dec 2003
Posts: 51
Location: Italy

View user's profile Send private message

PostPosted: Wed Jan 28, 2015 1:06 am     Reply with quote

Ttelmah wrote:
So does it work?.

What happens with the example as posted (I have amended the rom declaration in it)?. This runs perfectly for me.

l 'example is fine.
But in my full code generates some 'error
Code:
 Attempt to create a pointer to a constant


I checked there are no more "const" all replaced with "rom".
L 'error only eliminated leaving in the define
Code:
#device PASS_STRINGS = IN_RAM



From the support CCS me confirm a problem with this family of processors using the strcpy to copy from ROM to RAM, which should solve short.
They recommend using:

Code:
read_rom_memory (version [1], string, sizeof (string));


Tried it and it works ... but it works well

Code:
void strromcpy (char * dest, rom char * source)

that thou hast recommended
Thank You
Ttelmah



Joined: 11 Mar 2010
Posts: 19372

View user's profile Send private message

PostPosted: Wed Jan 28, 2015 9:05 am     Reply with quote

That implies somewhere you are using a simple 'char *', not a 'rom char *' to access the data.
PASS_STRINGS will allow this to be done, but at a cost of making all constant accesses slightly bulkier and slower.
You 'pays your money and takes your choice'.

I prefer to retain full control, and explicitly know how things are accessed.
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