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

compilation of const struct with #org

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







compilation of const struct with #org
PostPosted: Tue Oct 14, 2008 5:51 am     Reply with quote

Hi,

(PIC18F4580 CCS 4.071 MPLAB 8.00 ICD2)

I am trying to store persistent settings in a const struct which I will periodically update using write_program_memory, and also a temporary RAM copy which I will use for scratch editing e.g.

Code:
#include <18F4580.h>

#FUSES NOWDT, WDT128, INTRC, NOPROTECT, BROWNOUT, BORV21, NOPUT
#FUSES NOCPD, STVREN, NODEBUG, LVP, NOWRT, NOWRTD, IESO, FCMEN
#FUSES NOWRTC, NOEBTR, LPT1OSC, MCLR, NOXINST               

#use delay(clock=8000000)

typedef struct
{
   unsigned int8 channel_type[8];
   unsigned int8 log_interval;
   unsigned int8 base_channel;
} s_settings;

// ROM data
#org 0x5000, 0x5200
const s_settings rom_settings =
{
   {1,2,3,4,1,2,3,4}, 1, 9
};

// RAM data
s_settings temp_settings;


void main()
{
   // Auto-generated
   setup_adc_ports(NO_ANALOGS|VSS_VDD);    setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   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);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);    setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   // Load ROM data into RAM
   read_program_memory(0x5000, &temp_settings, 200);
   // Update RAM data
   temp_settings.channel_type[0] = 5;
   // Save back to ROM
   write_program_memory(0x5000, &temp_settings, 200);

}


I have found that the call to read_program_memory does not copy the correct values into my RAM instance temp_settings, and write_program_memory does not save back the contents of temp_settings

When I examine the hexfile, I see:
    :10500000F76A100FF66E500EF7220900F5501200E5
    :0C50100001020304010203040109000C6A


Which would suggest that the actual data (bold) of this struct begins at 0x5010.

Bearing in mind that there is nothing else competing for this space (my hex has the program data in the range 0-0x0120), can anyone tell me...

What is occupying the 16 bytes 0x5000-0x500F before the data, and the 2 bytes 0x501B-0x501C after? From the helpfile entry for #org, there is a cryptic statement: "note some extra code will proceed the ...", very useful info but how much and what? I assume that this is "magic code" and I note that sometimes if I overwrite it I can kill the firmware quite nicely.

What governs the position of where the data is stored (relative to where I #rom it to be stored) - I have noticed comparing my actual problem program to this example code that the offset is different.

And generally, is there any simple way I can achieve this with const structs. In the past I have had success with storing the data in raw word format, e.g.
Code:
#rom 0x5000, 0x500A {0x0102, 0x0304, 0x0102, 0x0304, 0x0109}

(or whatever - drawn from memory) and then reading this raw data onto a struct in the RAM. But this seems to defeat the object of being able to declare #org variables.

Clues much appreciated.
quantum_nli
Guest







Re: compilation of const struct with #org
PostPosted: Tue Oct 14, 2008 5:57 am     Reply with quote

Correction:

quantum_mechanic_nli wrote:

What governs the position of where the data is stored (relative to where I #rom it to be stored) - I have noticed comparing my actual problem program to this example code that the offset is different.


...Or even #org it to be stored
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 14, 2008 11:49 am     Reply with quote

Compile the program and look at the Program Memory window in MPLAB.
This will show you what's happening. You'll see that the compiler inserts
"access code" at 0x5000 loads the TBLPTR register with address 0x5010.
The compiler calls this access code to read the structure data.

Insert this test code at the start of main(), to display your const structure.
Code:
for(i = 0; i < 8; i++)
    printf("%X ", rom_settings.channel_type[i]);
   
    printf("\n\r");
    printf("%X \n\r", rom_settings.log_interval);
    printf("%X \n\r", rom_settings.base_channel);


Run it in MPSIM, with UART1 enabled (in the Debugger menu).
Also add a #use rs232() statement to your program.
This is the output displayed in the MPLAB Output Window.
Quote:
01 02 03 04 01 02 03 04

01

09

The access code is working. Your rom data is accessible.
Ttelmah
Guest







PostPosted: Wed Oct 15, 2008 3:19 am     Reply with quote

The manual does tell you about the extra code, if you look at the #ORG examples.

There is no really 'elegant' way round this at present. The 'label_address' function, will return the real location of the data.

If you can accept not using a structure, but using a simple array, then you can switch to using ROM constants, instead of the 'const' form. The ROM form, does not put the access code in front of the data, instead using a general access code, which is a little larger. Unfortunately, while, if it worked 'right', it'd be the total answer, at present it has problems handling data structures, so you would have to use something like:

#ORG 0x5000,0x5100 DEFAULT
ROM int8 rom_settings[10]= {1,2,3,4,1,2,3,4,1,9};
#ORG DEFAULT

Which will put the int8 array 'rom_settings', at the required address, without extra code.

Best Wishes
quantum_mechanic



Joined: 14 Nov 2007
Posts: 4

View user's profile Send private message

PostPosted: Wed Oct 15, 2008 4:11 am     Reply with quote

Thanks both for clearing that up. It's been bugging me for a while. I wondered why I could read access the members as though they were RAM. To put clarity over code size, I think I will go for the label_address route.

Just for future refs, is there any way that I can calculate the space requirement for the access code if I want to pack the data efficiently e.g. something along the lines of:

Code:

#define AREA1_SIZE xxx
#define AREA2_SIZE xxx
#define AREA3_SIZE xxx
...
#define AREA1_BASE getenv("PROGRAM_MEMORY") - AREA1_SIZE
#define AREA2_BASE AREA1_BASE - AREA2_SIZE
#define AREA3_BASE AREA2_BASE - AREA3_SIZE
...
#org AREA1_BASE (AREA1_BASE+AREA1_SIZE)
#org AREA2_BASE (AREA2_BASE+AREA2_SIZE)
etc.


Presumably this is not a calculation that can be automated using label_address as the #org statement comes before the label.

Is there a worst-case value that can be used which permits reasonably tight packing?
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