|
|
View previous topic :: View next topic |
Author |
Message |
quantum_mechanic_nli Guest
|
compilation of const struct with #org |
Posted: Tue Oct 14, 2008 5:51 am |
|
|
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 |
Posted: Tue Oct 14, 2008 5:57 am |
|
|
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
|
|
Posted: Tue Oct 14, 2008 11:49 am |
|
|
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
|
|
Posted: Wed Oct 15, 2008 3:19 am |
|
|
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
|
|
Posted: Wed Oct 15, 2008 4:11 am |
|
|
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? |
|
|
|
|
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
|