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

Workaround for pointer to const or rom *?

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



Joined: 17 Jun 2019
Posts: 537
Location: Des Moines, Iowa, USA

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

Workaround for pointer to const or rom *?
PostPosted: Mon Apr 06, 2020 11:16 am     Reply with quote

There has been an outstanding issue with CCS dealing with rom * for awhile, and I wondered if anyone has figured out a workaround.

In my case, I have tables of data:

Code:
uint8_t data[100] =
{
   0,0,0,0,0 ... 0,0,0
};


And I have structures that contain pointers to that data:

Code:
typedef struct
{
     // stuff
     uint32_t *dataPtr;
};


To make this work currently, all our structures are in RAM. But I am now at 90% and need to get things moved.

I have one large structure as a "const" which I access directly with no problems, but the other elements are part of an LCD user interface so the structure has attributes for how that data gets displayed.

Anyone have a good workaround for how I can have a structure point to data in flash and make that work?
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Apr 06, 2020 11:25 am     Reply with quote

Generally, you are using PIC24/33's?.
If so, then:

#device PSV=16

You can then have pointers to all types of consts.

If you are on the PIC16/18, then declare your consts, as 'rom', instead
of const. Then declare your pointers as 'rom *'.
allenhuffman



Joined: 17 Jun 2019
Posts: 537
Location: Des Moines, Iowa, USA

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

PostPosted: Mon Apr 06, 2020 11:56 am     Reply with quote

Thanks, but unfortunately that doesn't seem to help. I don't know the details of the compiler bug, just that it may take a few months for them to have a fix.

Simple things like this:

Code:
typedef struct
{
   int x,y;
   const uint8_t *ptr;
} MyStruct;


...compile and work fine if the program is small. At some point, they won't even compile -- complains about "const" not being recognized -- even when this declaration is in main.c.

I expect this is related to the compiler bug, am I am hopeful someone has figured out a workaround.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
jeremiah



Joined: 20 Jul 2010
Posts: 1314

View user's profile Send private message

PostPosted: Mon Apr 06, 2020 4:59 pm     Reply with quote

Have you tried switching to function pointers to access constant tables? Something like create a constant table:

Code:


const unsigned int table[100] = /*stuff*/;

int get_at(unsigned int index){
   if(index > 99){
      index = 99;
   }
   return table[index];
}

typedef int(*indexer)(unsigned int);

typedef struct
{
   int x,y;
   indexer ptr;
} MyStruct;


MyStruct v = {0,1,get_at};

int value = v.indexer(some_index);



I don't have the compiler handy here, so that is off the cuff pseudo code that hasn't been compiled. But basically you replace the pointer to the table with a pointer to a function that reads the table for you.

It's mostly just a workaround type solution, not optimal obviously. It's more scaffolding than you would normally want to do, but it may get around your issue.

Another option is to use an enum paired with switch statement to select your table:
Code:

const unsigned int ctable1[4] = {1,2,3,4};
const unsigned int ctable2[4] = {1,2,3,4};
const unsigned int ctable3[4] = {1,2,3,4};
const unsigned int ctable4[4] = {1,2,3,4};

typedef enum {
   TABLE1,
   TABLE2,
   TABLE3,
   TABLE4
} table_selector_t;


unsigned int get_at(table_selector_t table, unsigned int index){
   switch(table){
      case TABLE1: return ctable1[index]; break;
      case TABLE2: return ctable2[index]; break;
      case TABLE3: return ctable3[index]; break;
      default:     return ctable4[index];
   }
}

typedef struct
{
   int x,y;
   table_selector_t selector;
} MyStruct;


MyStruct v = {0,1,TABLE1};

int value = get_at(v.selector, some_index);



then you just keep the selector enum value with each struct.

Side note: Make sure you not to take the address of an individual element of a const table pointer or dereference it. I.E. I don't believe CCS fully supports the following:

*table =
address = &table[6];
some_const_struct_pointer->some field

It may or may not work, but the CCS docs usually only allow for bracketed element access for constant tables. That may have changed more recently, but I haven't seen any updates indicating so.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Apr 07, 2020 12:06 am     Reply with quote

If you use PSV, the pointers are just normal pointer. Get rid of the
const keyword in the pointer declaration.
If you declare the pointers as 'const', they have to be resolved at compile
time, not run time.
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Tue Apr 07, 2020 3:06 am     Reply with quote

As a separate 'workround', which was a way that I have used in the past,
look at Addressmod.
This is a function designed to allow you to map external memory areas
into the memory supported for variables. However you can use it with the
internal flash memory.
I suspect you are having problems with PSV, possibly because yous chip
has 64K of RAM?. The total addressable RAM 'window' for the PIC24/33
chips is 64K. PSV uses a 16K window into this space. If your chip has more
RAM than 48K, it can get confused. Also it sounds as if your total ROM
needed may be large (again larger than the PSV window).
Now there are going to be 'issues' however you do this.
Remember the program memory space only implements 24bits in
every 32. When PSV is used, it stores values only into the low 16bits
of each 32, making translation relatively easy, but wasting space.
You are going to have to write the read function you call with AddressMod
to automatically handle multiplication by 4/3 of the address, and allow
indexing in bytes into this area (see below).
You can pack the data into the ROM using #IMPORT. I do this with a
number of bitmaps with:

#IMPORT(FILE=.\Logo.bin, RAW, LOCATION=where_stored, BPI=3)

Which puts binary data into the ROM space, packed 3 bytes per word.
My read function, is then:
Code:

union access {
    unsigned int32 whole;
    unsigned int8 bytes[4];
}; //union to allow byte access into 32bit word

//routine to give access to ROM stored data - used for bitmap
BYTE getval(unsigned int32 locn, unsigned int32 index)
{
    unsigned int32 calc;
    union access rdg;
    unsigned int8 bval;
    //Now I need to calculate the actual cell I need to read, fetch this
    //then extract the byte
    calc=(index/3)*2;
    //This gives the actual cell offset from locn.
    read_program_memory(locn+calc, &rdg, 4);
    //Gives the 32bit value containing the byte required.
    bval=index % 3;
    //Now gives the byte number required
    return rdg.bytes[bval];
    //return the physical byte
}


'locn' here is the variable 'where_stored' from the import, which
is where the data has been put in memory. 'index' is the byte number
I want to retrieve from the data.
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