Problem declaration Table in flash

cancel
Showing results for 
Search instead for 
Did you mean: 

Problem declaration Table in flash

Jump to solution
504 Views
DEMO9S12XEP100
Contributor II

Hi,

i have a developpement kit DEM09S12XEP100. and i want to declare an array in flash with 180Kbyte.

this table is constant.

i write this code.

 

const int tab [300][300];

after compilation, i have a error "out of allocation space in segment ROM_C000 at adress 0xC051"

 

Can you help me please?

Labels (1)
0 Kudos
1 Solution
72 Views
kef
Specialist I

To allocate such big chunk of data, first of all you need that big contiguous data segment. For 180kB you need at least 180/16  --- 11 flash pages. So you may edit prm file to comment out PAGE_C0 to PAGE_CA segments and all references to them. Then you define new big segment specifing segment top and bottom using global addresses like this:

 

      PAGES_C0_CA   = READ_ONLY         0x700000'G/*0xCA8000*/ TO 0x72BFFF'G/*0xCABFFF*/;

 

Then you define placement into this segment:

 

      BIGDATA  INTO PAGES_C0_CA;

 

Then you come back to your source and put tab into BIGDATA like this

 

#pragma DATA_SEG __GPAGE_SEG BIGDATA

const int tab [300][300];

#pragma DATA_SEG DEFAULT

 

Unfortunately you can't use >64k array directly. You can initialize your 180k data in the code, but can't reference array elements like tab[i][j]. Instead, for >64k arrays you need to use __far24 pointers.

 

#define dimx 300ul
#define dimy 300

 

#pragma DATA_SEG __GPAGE_SEG BIGDATA

const int tab [dimx][dimy];

#pragma DATA_SEG DEFAULT

 

const int * __far24 tabptr = &tab[0][0];

 

unsigned int i,j;

int x;

 

void main(void) {
  
  // accessing array elements

   i = 0; j=0; 
   x = tabptr[i*dimx + j]; // data @ 0x700000'g

 

   i = 0; j=dimy-1;
   x = tabptr[i*dimx + j]; // data @ 0x700256'g

 

   i = dimx-1; j=0;
   x = tabptr[i*dimx + j]; // data @ 0x72BCC8'g

 

   i = dimx-1; j=dimy-1;
   x = tabptr[i*dimx + j]; // data @ 0x72BF1E'g

}

 

Please note that:

1)array index should be long integer. I made dimx long, so that all expressions in [] are long.

2) this is still tricky. Array elements must be word aligned, else you will certainly read wrong data if you try to read word from address % 0x10000 = 0xFFFF. For array of integers it is easy to satisfy this requirement and never read "dangerous" address, just align whole array. For array of structs it may be harder.

 

View solution in original post

0 Kudos
9 Replies
73 Views
kef
Specialist I

To allocate such big chunk of data, first of all you need that big contiguous data segment. For 180kB you need at least 180/16  --- 11 flash pages. So you may edit prm file to comment out PAGE_C0 to PAGE_CA segments and all references to them. Then you define new big segment specifing segment top and bottom using global addresses like this:

 

      PAGES_C0_CA   = READ_ONLY         0x700000'G/*0xCA8000*/ TO 0x72BFFF'G/*0xCABFFF*/;

 

Then you define placement into this segment:

 

      BIGDATA  INTO PAGES_C0_CA;

 

Then you come back to your source and put tab into BIGDATA like this

 

#pragma DATA_SEG __GPAGE_SEG BIGDATA

const int tab [300][300];

#pragma DATA_SEG DEFAULT

 

Unfortunately you can't use >64k array directly. You can initialize your 180k data in the code, but can't reference array elements like tab[i][j]. Instead, for >64k arrays you need to use __far24 pointers.

 

#define dimx 300ul
#define dimy 300

 

#pragma DATA_SEG __GPAGE_SEG BIGDATA

const int tab [dimx][dimy];

#pragma DATA_SEG DEFAULT

 

const int * __far24 tabptr = &tab[0][0];

 

unsigned int i,j;

int x;

 

void main(void) {
  
  // accessing array elements

   i = 0; j=0; 
   x = tabptr[i*dimx + j]; // data @ 0x700000'g

 

   i = 0; j=dimy-1;
   x = tabptr[i*dimx + j]; // data @ 0x700256'g

 

   i = dimx-1; j=0;
   x = tabptr[i*dimx + j]; // data @ 0x72BCC8'g

 

   i = dimx-1; j=dimy-1;
   x = tabptr[i*dimx + j]; // data @ 0x72BF1E'g

}

 

Please note that:

1)array index should be long integer. I made dimx long, so that all expressions in [] are long.

2) this is still tricky. Array elements must be word aligned, else you will certainly read wrong data if you try to read word from address % 0x10000 = 0xFFFF. For array of integers it is easy to satisfy this requirement and never read "dangerous" address, just align whole array. For array of structs it may be harder.

 

View solution in original post

0 Kudos
72 Views
DEMO9S12XEP100
Contributor II

Hi

 

Thank your for your reponse Kef

it s very clear  and it work good. (after compilation t find my table at the 0x700000 global

Now, i can declared my table in flach using Ppage in .prm

  PAGES_C0_CA   = READ_ONLY         0x700000'G/*0xCA8000*/ TO 0x72BFFF'G/*0xCABFFF*/;

the error for comment    0x700000'G/*0xC08000*/ TO 0x72BFFF'G/*0xCABFFF*/;

 

for my appliaction i want to declared a table canst  in flash and searching in my table for a value corrsponding a value  and send this value with CAN comunication.

example:


#pragma DATA_SEG __GPAGE_SEG BIGDATA
const float tab [600][38]={ {.....................},{.............................}};
#pragma DATA_SEG DEFAULT

 

for (i=0;i<600;i++) {
      for(j=0;j<38;j++){
       
        if(tab[i][j] == v)
          send frame();

 

Kef, for you i can not check all value for my table in my if loop?

 

thank you

 

0 Kudos
72 Views
kef
Specialist I
  • the error for comment    0x700000'G/*0xC08000*/ TO 0x72BFFF'G/*0xCABFFF*/;

Why error? Banked C0_8000 is exactly global 700000'G.

 

 

Array of 600*38 floats still is bigger than 64k and you have to use __far24 pointer. Accessing far array elements like tab[x][y] won't work for all x' and y, since in current Codewarrior versions array offset can't be >=64k. For bigger arrays you need to:

 

const float * __far24 tabptr = &tab[0][0];

 

x = tabptr[(long)i*dimx + (long)j];

 

Of course you can loop through all array elements, it's just not as comfortable and readable as tab[i][j].

0 Kudos
72 Views
freescale_satya
Contributor III

Iam sorry iam at a mistake.

 

 

0 Kudos
72 Views
freescale_satya
Contributor III

Hi,

 

I think you have declared a constant array of very huge size of 180Kb. If you reduce the size of the constant array then the error should go. I think you need to identify the following things

1. How much code size does your compiler support?

2. What is your code size ?

 

Based on the above factors you have to figure out how much constant array size you can allocate.

 

Thanks

Satya

 

0 Kudos
72 Views
DEMO9S12XEP100
Contributor II

Hi,

thank you for your reponse.

my table is not have a size of 180Kb but just 100Kb. i use 180Kb for example.

for the flowing thnigs :

1. How much code size does your compiler support?

i use a codeWarrior version 5.9 that i installed with my developpemnt kit and i think that supported 64KB?

 

2. What is your code size ?

my code is not tirminated so i dont know my code size. but how can i to check my code size ?

Thanks

0 Kudos
72 Views
Lundin
Senior Contributor IV

This is data, not code. So any CW restrictions on code size don't apply, because CW checks code size only, and not data size.

 

0 Kudos
72 Views
freescale_satya
Contributor III

Hi,

 

The array was declared with "const" qualifier so i think the code size would increase rather than the data size. I checked the same thing in the CW compiler and it is increasing the code size if the "const" is used for an array equal to the size of the array and increases the data if "const" is removed before the array. Please correct me if iam wrong in my understanding.

 

Thanks

Satya  

0 Kudos
72 Views
CompilerGuru
NXP Employee
NXP Employee

Constants do end up in flash by default, sure.

But as far as I know, the build tools consider only code for the license limitation checks.

 

Daniel

0 Kudos