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

constant array problem !

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



Joined: 28 Aug 2007
Posts: 45

View user's profile Send private message

constant array problem !
PostPosted: Mon Jul 26, 2010 9:31 am     Reply with quote

Hi all.
I want to print constant array but not directly and in main(). ! In this code I used pointer and I think print_data() work while I define F8_18 in RAM.
my question is here : why I can't get result correctly ?
(I think i must use read_program_memory() . am i right?)

Code:
#include "main.h"

#org 5000,5210
int const F8_12[210]={
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x0C, 0xC0, 0x03, 0x38, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0xF8, 0x03, 0xFC, 0x07, 0x06, 0x0C, 0x02, 0x08, 0x06, 0x0C, 0xFC, 0x07, 0xF8, 0x03, 0x00, 0x00, 
0x00, 0x00, 0x04, 0x08, 0x04, 0x08, 0xFE, 0x0F, 0xFE, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 
0x08, 0x08, 0x0C, 0x0C, 0x06, 0x0E, 0x86, 0x0D, 0xFE, 0x0C, 0x3C, 0x0C, 0x00, 0x06, 0x00, 0x00, 
0x08, 0x02, 0x04, 0x04, 0x46, 0x0C, 0x66, 0x0C, 0xFE, 0x0C, 0xDC, 0x07, 0x80, 0x03, 0x00, 0x00, 
0x80, 0x03, 0x40, 0x03, 0x20, 0x03, 0x18, 0x03, 0xFC, 0x0F, 0xFE, 0x0F, 0x00, 0x03, 0x00, 0x00, 
0x20, 0x02, 0x3C, 0x04, 0x36, 0x0C, 0x36, 0x0C, 0x66, 0x0C, 0xE6, 0x07, 0xC2, 0x03, 0x00, 0x00, 
0xE0, 0x03, 0xF8, 0x07, 0x3C, 0x0C, 0x26, 0x08, 0x66, 0x0C, 0xC2, 0x07, 0x82, 0x03, 0x00, 0x00, 
0x0C, 0x00, 0x06, 0x00, 0x06, 0x0C, 0x86, 0x0F, 0xF6, 0x03, 0x7E, 0x00, 0x0E, 0x00, 0x00, 0x00, 
0x1C, 0x03, 0xBE, 0x07, 0x73, 0x0C, 0x63, 0x0C, 0xE3, 0x0C, 0xFE, 0x07, 0x9C, 0x03, 0x00, 0x00, 
0x38, 0x00, 0x7C, 0x08, 0xC6, 0x0C, 0x82, 0x06, 0x86, 0x07, 0xFC, 0x03, 0xF8, 0x00, 0x00, 0x00, 
};

void print_data(int *I,int16 size)
{
   int16 S;
   for(s=0;s<size;s++)
      printf("D[%ld]=%x\r\n",s,I[s]);
}


void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
////////////////////////////////////////////////////////////////////////////////

   print_data(*F8_12,210);
}
collink



Joined: 08 Jan 2010
Posts: 137
Location: Michigan

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

PostPosted: Mon Jul 26, 2010 10:11 am     Reply with quote

Yeah, you should use read_program_memory. The below should work for you:

Code:

#include "main.h"

#org 5000,5210
int const F8_12[210]={
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0xC0, 0x03, 0x38, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF8, 0x03, 0xFC, 0x07, 0x06, 0x0C, 0x02, 0x08, 0x06, 0x0C, 0xFC, 0x07, 0xF8, 0x03, 0x00, 0x00,
0x00, 0x00, 0x04, 0x08, 0x04, 0x08, 0xFE, 0x0F, 0xFE, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
0x08, 0x08, 0x0C, 0x0C, 0x06, 0x0E, 0x86, 0x0D, 0xFE, 0x0C, 0x3C, 0x0C, 0x00, 0x06, 0x00, 0x00,
0x08, 0x02, 0x04, 0x04, 0x46, 0x0C, 0x66, 0x0C, 0xFE, 0x0C, 0xDC, 0x07, 0x80, 0x03, 0x00, 0x00,
0x80, 0x03, 0x40, 0x03, 0x20, 0x03, 0x18, 0x03, 0xFC, 0x0F, 0xFE, 0x0F, 0x00, 0x03, 0x00, 0x00,
0x20, 0x02, 0x3C, 0x04, 0x36, 0x0C, 0x36, 0x0C, 0x66, 0x0C, 0xE6, 0x07, 0xC2, 0x03, 0x00, 0x00,
0xE0, 0x03, 0xF8, 0x07, 0x3C, 0x0C, 0x26, 0x08, 0x66, 0x0C, 0xC2, 0x07, 0x82, 0x03, 0x00, 0x00,
0x0C, 0x00, 0x06, 0x00, 0x06, 0x0C, 0x86, 0x0F, 0xF6, 0x03, 0x7E, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x1C, 0x03, 0xBE, 0x07, 0x73, 0x0C, 0x63, 0x0C, 0xE3, 0x0C, 0xFE, 0x07, 0x9C, 0x03, 0x00, 0x00,
0x38, 0x00, 0x7C, 0x08, 0xC6, 0x0C, 0x82, 0x06, 0x86, 0x07, 0xFC, 0x03, 0xF8, 0x00, 0x00, 0x00,
};

void print_data(const int *I,int16 size)
{
   int16 s;
   int8 temp;
   for(s=0;s<size;s++) {
      temp = read_program_memory(I + s);
      printf("D[%ld]=%x\r\n",s,temp);
   }
}


void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
////////////////////////////////////////////////////////////////////////////////

   print_data(F8_12,210);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19329

View user's profile Send private message

PostPosted: Mon Jul 26, 2010 10:49 am     Reply with quote

No.....

Problem is that when you store a constant array in memory, it _does not_ start at the beginning of the area declared to hold it. The compiler places the program to retrieve the values here, followed by the values themselves.

There are a number of answers acccording to what you really need.

First, the function 'label_address', will return the actual address in memory where the array is stored. You can then use 'read_program_memory' starting at this location to access the data.
In fact the array won't fit in the area declared, because of this extra code....

Second though, if you store the array using #ROM, rather than 'const', the array will be placed directly in the program memory, without the access code.

Third thing though is that on the latter compilers, you can use pointers to an array declared like this....

So the original code, won't compile, since the array + access code, won't fit in the area defined (remember you need #org default after the array to switch the memory useage back to normal....).
The 'answer' won't work, because you can't hand the address of the array like this, and the read_program_memory function, does not return a value, instead requiring an _address_ to put it's result into.

Simplest answer, use rom, instead of const, get rid of the ORG statement, and let the compiler handle things for you.
Other answer, enlarge the space enough for the extra code, use 'label_address' to get the memory address involved, and hand this as a simple int16/32 (depending on the processor memory size), to the function.

Best Wishes
collink



Joined: 08 Jan 2010
Posts: 137
Location: Michigan

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

PostPosted: Mon Jul 26, 2010 11:38 am     Reply with quote

Whoops... I guess I should have mentioned that. I do use #DEVICE CONST=ROM in my code. Also, I was mixing up read_program_memory and read_program_eeprom. read_program_eeprom works the way I showed.
Ttelmah



Joined: 11 Mar 2010
Posts: 19329

View user's profile Send private message

PostPosted: Mon Jul 26, 2010 2:50 pm     Reply with quote

I actually don't like using 'CONST=ROM'. I think it is better to use the ROM keyword, and keep 'const' with it's normal meaning. Having multiple meanings to one keyword, is asking for problems latter with working out what is going on...

However, using this (either const=ROM, or int8 rom as the data declaration), then you can use:
Code:

void print_data(int16 addr,int16 size)
{
   int16 s;
   int8 temp;
   for(s=0;s<size;s++) {
      temp=*(rom *)(addr+s);
      printf("D[%ld]=%x\r\n",s,temp);
   }
}

//and for the call in main:
   print_data(F8_12,210);

There is however a 'problem'. If you do this, the array still won't be put at the #ORG location. Don't know why, but CCS ignores an ORG on a rom array...

However I'd suggest this is probably 'reliable':
Code:

#define F8_12 (5000)
#org F8_12,F8_12+210

#rom int8 F8_12={
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0C, 0xC0, 0x03, 0x38, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF8, 0x03, 0xFC, 0x07, 0x06, 0x0C, 0x02, 0x08, 0x06, 0x0C, 0xFC, 0x07, 0xF8, 0x03, 0x00, 0x00,
0x00, 0x00, 0x04, 0x08, 0x04, 0x08, 0xFE, 0x0F, 0xFE, 0x0F, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
0x08, 0x08, 0x0C, 0x0C, 0x06, 0x0E, 0x86, 0x0D, 0xFE, 0x0C, 0x3C, 0x0C, 0x00, 0x06, 0x00, 0x00,
0x08, 0x02, 0x04, 0x04, 0x46, 0x0C, 0x66, 0x0C, 0xFE, 0x0C, 0xDC, 0x07, 0x80, 0x03, 0x00, 0x00,
0x80, 0x03, 0x40, 0x03, 0x20, 0x03, 0x18, 0x03, 0xFC, 0x0F, 0xFE, 0x0F, 0x00, 0x03, 0x00, 0x00,
0x20, 0x02, 0x3C, 0x04, 0x36, 0x0C, 0x36, 0x0C, 0x66, 0x0C, 0xE6, 0x07, 0xC2, 0x03, 0x00, 0x00,
0xE0, 0x03, 0xF8, 0x07, 0x3C, 0x0C, 0x26, 0x08, 0x66, 0x0C, 0xC2, 0x07, 0x82, 0x03, 0x00, 0x00,
0x0C, 0x00, 0x06, 0x00, 0x06, 0x0C, 0x86, 0x0F, 0xF6, 0x03, 0x7E, 0x00, 0x0E, 0x00, 0x00, 0x00,
0x1C, 0x03, 0xBE, 0x07, 0x73, 0x0C, 0x63, 0x0C, 0xE3, 0x0C, 0xFE, 0x07, 0x9C, 0x03, 0x00, 0x00,
0x38, 0x00, 0x7C, 0x08, 0xC6, 0x0C, 0x82, 0x06, 0x86, 0x07, 0xFC, 0x03, 0xF8, 0x00, 0x00, 0x00
}
#org default

void print_data(int16 addr,int16 size)
{
   int16 s;
   int8 temp;
   for(s=0;s<size;s++) {
      read_program_memory(addr,&temp,1);
      printf("D[%ld]=%x\r\n",s,temp);
   }
}

//addr needs to be an int32, if using a part with more than 64K ROM
//Then call from main with:

print_data(F8_12,210);

Using #ROM, simply declares a data 'table' at the specified address, rather than an 'array'.

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