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

How can I use large const struct arrays with CCS ???

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



Joined: 05 Aug 2006
Posts: 149
Location: Redditch, UK

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

How can I use large const struct arrays with CCS ???
PostPosted: Sun Jul 15, 2007 5:53 am     Reply with quote

PIC 16F876A
Compliler PCM 249

I am trying to use some large lookup tables in my program. Unfortunatly with CCS once the size of const array is bigger than 256 bytes then the indexes nolonger work correctly.

for example if you have something like this :

Code:
const int val[] = { 1, 2, 3, ........., 254,255,256 } ;

int16 i ;
i = 255 ;
printf("val[%ld] = %d", i, val[i]) ;

you will probably see val[255] = 1 on the screen and not val[255] = 256.

The way I have got round this in the past has been to split a large table in half and use a function to access it, like this :

Code:

const int table1 = {1,2,3 .......,126,127} ;
const int table2 = {128,129,130 .......,255,256} ;

int GetVal(int16 idx)
{
  if(idx >= 128) return table2[idx - 128] ;
  else return table1[idx] ;
}


This sort of works.

However !!

I now want to use a typdef struct in an array, something like this :

Code:
typedef struct _sFrame {
   uint16      time ;            uint8      output[MAX_UNITS] ;
} sFrame ;

const sFrame film1[] = {
//                      1111111    11122222     22222333
//   Time     12345678    90123456    78901234    56789012
//    -----     --------     --------     --------     --------
   {50,   0b00000000,   0b00000000,   0b00000000,   0b00000000   },
   {50,   0b10000000,   0b00000000,   0b00000000,   0b00000000   },
   {50,   0b00000001,   0b00000000,

                ..... etc ....................

   0b00000001,   0b00000000   },
}  ;

// Function to access one element of the struct array
sFrame *GetFrame(uint16 idx)
{
   sFrame *f ;
   f = &film1[idx] ;
   return f ;
}



The problem is I can't get the syntax correct to force GetFrame() to return a pointer to an element in the struct array. Once I can do this I can implement a large table fix as per normal const arrarys. Whats the correct syntax that keeps the CCS compiler happy ?
Ttelmah
Guest







PostPosted: Sun Jul 15, 2007 7:12 am     Reply with quote

What you are trying to do, won't work.
The array of structures, will still be a single memory element, and as such will have the original problem. Also, CCS, in v3 compilers (I guess your 'version', is 3.249, since you say '249'), does not support pointers to constants.
Your original solution is the only one that is going to work with normal array accesses. In the past, some functions have been published here to 'automate' the handling of multiple arrays like this, so that a int16 address is passed to the function, and then automatically select the sub-array, anthe required element in this.
The best solution though (only applicable on the 16 chips that support reading from program memory - the 676 is one that does), is to declare the large array, using the #ROM statement at a particular address, and then just access the elements using the 'read_program_memory' function (element number+start address of the array).
This isn't the default behaviour, because the ability only exists on a limited number of PICs.

Best Wishes
Pret



Joined: 18 Jul 2006
Posts: 92
Location: Iasi, Romania

View user's profile Send private message

PostPosted: Mon Jul 16, 2007 12:45 am     Reply with quote

Ttelmah wrote:
Also, CCS, in v3 compilers (I guess your 'version', is 3.249, since you say '249'), does not support pointers to constants.
But v4.x supports? As far as i know... it doesnt support either.
nurquhar



Joined: 05 Aug 2006
Posts: 149
Location: Redditch, UK

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

PostPosted: Mon Jul 16, 2007 2:53 am     Reply with quote

My soloution has been to do a copy into ram of the element of required from the const struct with a function. The function handles getting the index to one of several tables, to avoid using a table bigger than 256 bytes that CCS can't handle. I would have thought the overhead of using a function instead of "read_program_memory" would not be much in either code size or execution time. However the function is perhaps it bit more obvious when it comes to code maintenance.

Code:

typedef struct _sFrame {
   uint16      time ;               // Time for this output frame to endure, hunderths
   uint8      output[MAX_UNITS] ;      // The units output values
} sFrame ;

const sFrame film1[] = {
//                      1111111    11122222     22222333
//   Time     12345678    90123456    78901234    56789012
//    -----     --------     --------     --------     --------
   {150,   0b00000000,   0b00000000,   0b00000000,   0b00000000   },

   {150,   0b10000000,   0b00000000,   0b00000000,   0b00000000   },

.....................
   {750,   0b11111111,   0b11111111,   0b11111111,   0b00000000   },

}  ;
#if sizeof(film1) > 256
   #error film1 table is too big
#endif
const uint16 maxframes1 = sizeof(film1) / sizeof(sFrame) ;


const sFrame film2[] = {
//                      1111111    11122222     22222333
//   Time     12345678    90123456    78901234    56789012
//    -----     --------     --------     --------     --------
   {150,   0b11111111,   0b11111111,   0b11111110,   0b00000000   },
   {150,   0b11111111,   0b11111111,   0b11111100,   0b00000000   },
   {150,   0b11111111,   0b11111111,   0b11111000,   0b00000000   },
................
   {150,   0b10000000,   0b00000000,   0b00000000,   0b00000000   },

}  ;
#if sizeof(film2) > 256
   #error film2 table is too big
#endif
const uint16 maxframes2 = sizeof(film2) / sizeof(sFrame) ;

const sFrame film3[] = {
//                      1111111    11122222     22222333
//   Time     12345678    90123456    78901234    56789012
//    -----     --------     --------     --------     --------
}  ;
#if sizeof(film3) > 256
   #error film3 table is too big
#endif
const uint16 maxframes3 = sizeof(film3) / sizeof(sFrame) ;


const uint16 maxframes = maxframes1 + maxframes2 + maxframes3;

// Function to access the frames
void GetFrame(uint16 idx, sFrame *f)
{
   int i ;

   if(idx < maxframes1) {
      f->time = film1[idx].time ;
      for(i = 0 ; i < MAX_UNITS ; i++) {
         f->output[i] = film1[idx].output[i] ;
      }
      return ;
   }
   if(idx < (maxframes1 + maxframes2)) {
      idx -= maxframes1 ;
      f->time = film2[idx].time ;
      for(i = 0 ; i < MAX_UNITS ; i++) {
         f->output[i] = film2[idx].output[i] ;
      }
      return ;
   }
   if(idx < (maxframes1 + maxframes2 + maxframes3)) {
      idx -= (maxframes1 + maxframes2) ;
      f->time = film3[idx].time ;
      for(i = 0 ; i < MAX_UNITS ; i++) {
         f->output[i] = film3[idx].output[i] ;
      }
      return ;
   }
}

#endif
Ttelmah
Guest







PostPosted: Mon Jul 16, 2007 3:05 am     Reply with quote

Yes, V4 allows pointers to constants, in certain specific cases. They started to work in the mid 4.03x releases. However in some cases it generates a lot of code in use, and the syntaxes that work, bear little relationship to those in the manual!.
However the limit on block size in the 16 chips still exists, so the array as shown would still not work.

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