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

How to pass const array to function

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



Joined: 12 Jun 2007
Posts: 68
Location: Poland, podlaskie district

View user's profile Send private message

How to pass const array to function
PostPosted: Thu Oct 04, 2018 10:28 am     Reply with quote

Hello,

For some reason I have quite big char array that is not changing so I want them to be const array. But I have problem with passing it to function.

Normally if this array is variable it is possible to pass it to function as pointer.

Code:
v
//it compiles
oid function_with_const_array(int array_to_pass[])
{
   int c;
   c=array_to_pass[0]+1;
}

void main()
{
   int array[2]={1,2};
   function_with_const_array(array);
}


but If I change it to const like below the compiler gives errors
Code:

void function_with_const_array(const int array_to_pass[])
{
   int c;
   c=array_to_pass[0]+1;
}


void main()
{
   const int array[2]={1,2};
   function_with_const_array(array);
}


It is obvious because there is no such thing like pointer to const but I wonder how to fix this issue. I mean to pass const array to function.

I know that I can declare const array in function body, but I will pass to this function 2 or more const arrays. Also I don't want to make variable because from my point of view it is waste both ram and rom space (as I said those are const's). I have considered to write const to variable (in function block) and pass it as variable to function but malloc, free and so on functions also take a huge amount of rom. So I am searching for simplest solution to pass array(s) to function.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Oct 05, 2018 12:13 am     Reply with quote

Possibly
#device PASS_STRING=IN_RAM

The problem is because of the nature of the PIC processor. The PIC uses Harvard architecture, rather than the more normal Von Neumann architecture.
The Von Neumann architecture has a single adress space, and your ROM and RAM all appear in this single space. So address 0x1000 might be in ROM, and address 0x4000 in RAM. A single 'address' number can talk to anywhere in the memory. In the Harvard architecture, the ROM and RAM are in completely separate data spaces. There is an address 0x1000 in the ROM, and another address 0x1000 in the RAM. A RAM 'pointer' can't be constructed to talk to the ROM.
Now the compiler offers various ways of 'working round' this. Some depend on the processor involved. So:

First method.
char arrays, can be automatically 'virtualised'. The PASS_STRINGS option shown above, will automatically create a 'psuedo' pointer value, which then copies part of the const array into RAM, and allows it to be accessed as if it was in RAM. Uses a small RAM buffer to do this. Only works for text arrays.

Second ROM.
Declaring a constant using the rom keyword, instead of const, allows a rom pointer to be constructed:
Code:

void function_with_const_array(rom int array_to_pass[])
{
   int c;
   c=array_to_pass[0]+1;
}


void main()
{
   rom int array[2]={1,2};
   function_with_const_array(array);
}

Using the rom keyword, the compiler adds code to generate pointers.

Third (DsPIC's only) PSV.
The DsPIC's have a feature that allows part of their ROM to be mapped into the RAM address space. Program Space Visibility. On these chips enabling the feature by adding #device PSV=16, will allow RAM pointers to access const/rom data directly through this feature.

Fourth sequential access.
The compiler has a feature that dates from the earliest PIC's where ROM could not actually be read. On these to generate a const array, a program had to be created that returned an addressed byte when called. Means you can access the array in a slightly different way:
Code:

void function_with_const_array(int val)
{
   int c;
   c=val+1;
}


void main()
{
   const int array[2]={1,2};
   function_with_const_array(array);
}

Will actually result in 'function_with_const_array', being called twice, the first time with array[0], and the second with array[1]. What is done is the program to access the const is called with each possible index in turn, and the value returned is passed to the function. Allows a lot of code to be written without actually accessing the 'array' as such.

Probably for what you describe, the rom keyword is most likely to do what you want.
silelis



Joined: 12 Jun 2007
Posts: 68
Location: Poland, podlaskie district

View user's profile Send private message

PostPosted: Sat Oct 06, 2018 4:27 am     Reply with quote

I have decided to use second way. "rom char".

It did not work directly. To access rom data it is required to use read_program_eeprom.
The program looks like:


Code:
void function_with_const_array(int array_to_pass[])
{
   char data = read_program_eeprom (array_to_pass);
   fprintf(Dbg, "Value: %d \r\n", data);
   data = read_program_eeprom (array_to_pass+1);
   fprintf(Dbg, "Value: %d \r\n", data);
   //fprintf(Dbg, "Value: %d \r\n", array_to_pass[0]);
   
}

void main()
{
   rom int array[]={12,22};
   //int *p;
   //p=&array;
   function_with_const_array(array);
}



But it is working now and BIG THX for Your help. Smile
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sat Oct 06, 2018 12:24 pm     Reply with quote

It should work directly with the address declared as rom *.
The only thing I did not try was passing this as an array declaration rather than a pointer declaration. The normal way to declare the function would be:

void function_with_const_array(rom int * array_to_pass)

Now in C an array declaration and a pointer are equivalent, so I expected the array declaration to work, however if it doesn't, it suggests CCS may not respect the equivalence in this specific case.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Oct 07, 2018 2:10 am     Reply with quote

Yes. Just built a basic test program, and the compiler accepts rom *, but not building as an array. A bit naughty...
Code:

#include <18F4520.h>
#device ADC=10

#FUSES NOWDT                    //No Watch Dog Timer

#use delay(crystal=20000000)
#use rs232(UART1, baud=9600, ERRORS)

int8 func_using_ptr(rom int8 * array)
{
   //test array
   int8 sum;
   sum=array[0];
   sum+=array[1];
   return sum;
}


void main()
{

   rom int8 test[]={1,2};
   int8 sum;
   while(TRUE)
   {
      sum = func_using_ptr(test);
      printf("sum is %d\n", sum);
      delay_ms(1000);     
   }
}


as you can see it makes no functional difference (you can still reference it as an array).
silelis



Joined: 12 Jun 2007
Posts: 68
Location: Poland, podlaskie district

View user's profile Send private message

PostPosted: Sun Oct 07, 2018 10:53 am     Reply with quote

I see. So I made something wrong. Once again thank You for Your time and for help. :-)
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Sun Oct 07, 2018 2:09 pm     Reply with quote

No, you didn't make a mistake.

In C a parameter passed to a function as [] is an equivalent alternative to passing as a pointer. The language should accept either. In the case of a rom pointer type, the language is not accepting this equivalence...
silelis



Joined: 12 Jun 2007
Posts: 68
Location: Poland, podlaskie district

View user's profile Send private message

PostPosted: Tue Oct 09, 2018 10:00 am     Reply with quote

I have also question about "#device PASS_STRING=IN_RAM".

This pseudo pointer and virtual constant "is" during function execution only or during all program execution?

I mean if it use RAM temporary or permanently?
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Oct 09, 2018 10:38 am     Reply with quote

The amount it uses is tiny. I think it is typically perhaps 4 bytes!. It is global, so 'all the time'.
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