CW08 V5.0 Problem with global variable over-writing a global structure

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CW08 V5.0 Problem with global variable over-writing a global structure

Jump to solution
3,144 Views
bigmac
Specialist III
Hello,
 
I have been attempting to use the ROM based routines ERARNGE (page erase) and PRGRNGE from within my code, to implement non-volatile storage of parameter data within a 908QYx device.  The use of these routines requires a data structure to reside at a specific location in RAM.
 
The following is an excerpt from the associated header file -
 
#define DATASIZE 2        /* Data bytes to be stored (up to 32) */
 
#define RAMStart 0x0080
 
typedef struct {
   byte CTRLBYT;
   byte CPUSPD;
   word LADDR;
   byte databuf[DATASIZE];
}  BlockStruct;
 
extern BlockStruct RAMBlock @ RAMStart+8;
 
It is useful to determine the number of bytes to be stored from within the header file, by defining the value of DATASIZE.  The code compiles correctly, and the RAMBlock structure commences at address 0x0088.
 
However, if I declare further global variables, as well as the structure, (within main.c) such as -
 
/* Globals */
BlockStruct RAMBlock;
byte var[16];
 
the situation occurs where the var array will commence at address 0x0080, and will consequently over-write RAMBlock.
 
Is there some way to solve this problem, perhaps using pragmas.  I do not necessarily want to create a new section specifically for RAMBlock, within the PRM file, for the following reasons -
  1. The size of a new section would need to match DATASIZE, that may differ for each application.  It would not generally be feasible to always allow for a worst case of 36 bytes, not with a total of 128 bytes of RAM available.
  2. It is likely that the 8 bytes of RAM starting at 0x0080 would never be assigned to anything.
Presumably, if I did not need to specify the exact location for RAMBlock, there would not be a problem.
 
Any suggestions would be welcomed.
 
Regards,
Mac
 


Message Edited by bigmac on 2007-07-12 10:17 PM
Labels (1)
Tags (1)
0 Kudos
Reply
1 Solution
1,607 Views
CompilerGuru
NXP Employee
NXP Employee
Variables are either places at a specific address (with the @) or they are placed in a section.
If there is a @, then the current section does not matter, so I guess crazycat's suggestion did include to remove the absolute declaration, well it did include it implicitely Smiley Wink.

As far as the linker is concerned, the linker does not place or move objects placed with a @ in anyway, they are actually handled identically to  assembly ORG sections. They are also not considered during the placement of relocatable objects into the segments, so the existence of a absolute object does not cause a gap in the relocatable objects.
Hmm not sure it is documented that what the linker is not doing Smiley Wink. In general the idea is if the user is placing the objects at a certain address he knows what he is doing and therefore if they should not overlap then he would exclude the range from the segments in the prm file.
Surprisingly often I did see that the linker warning for overlapping objects (which does occur for such cases) is explictely disabled, so there are really use cases for overlapping of absolute objects with actual content.

Note that you can place the Z_RAM0 segment just after the Z_RAM one.
....
 _DATA_ZEROPAGE, MY_ZEROPAGE         INTO  Z_RAM,Z_RAM0;


Daniel

View solution in original post

0 Kudos
Reply
5 Replies
1,607 Views
CrasyCat
Specialist III
Hello
 
I am not sure I have enough information to really help here, so I will make some assumption.
I assume that:
    - The RAM (or Z_:RAM) memory area starts at 0x80 in your .prm file
 
In that case would do the following:
  - Define the variable  RAMBlock in a user specific data section
  - Place that section first in the RAM or ZRAM memory area. This way there will be no object
    overwriting the variable. And variable size will be just what you need.
 
Example of PRM File
Code:
SEGMENTS     ROM                      =  READ_ONLY    0xF800 TO 0xFDFF;    Z_RAM                    =  READ_WRITE   0x0080 TO 0x00FF;    ROM1                     =  READ_ONLY    0xFFB0 TO 0xFFBD;    ROM2                     =  READ_ONLY    0xFFC2 TO 0xFFCF;ENDPLACEMENT    DEFAULT_ROM, ROM_VAR, STRINGS       INTO  ROM;     MyRAMBlock, DEFAULT_RAM,    _DATA_ZEROPAGE, MY_ZEROPAGE         INTO  Z_RAM;END

 
Does that help?
 
CrasyCat
0 Kudos
Reply
1,607 Views
bigmac
Specialist III
Hello CrasyCat,
 
Thanks for your response.
 
I tried your suggestion, but this did not fix the over-write problem.  However, after a bit more experimentation, I did find the apparent cause.
 
It would seem that, when an absolute address is specified for a variable, such as -
extern BlockStruct RAMBlock @RAMStart+8;
 
the linker suffers amnesia concerning that variable, and ignores its existence (apart from including it in the map file).  However, if I declare the same variable without an absolue address, there is now no overlap of variables (as expected), but RAMBlock is in the wrong place, starting at 0x0080.
 
To fix this problem, I needed to alter the Z_RAM segment in the PRM file to -
Z_RAM = READ_WRITE  0x0088 TO 0x00FF;
 
The result of this was OK provided that RAMBlock was defined or declared before any other global variable.  If I now implement your suggestion, on top of these changes, and the order of variable definition became non-critical.
 
To make accessible the 8 bytes of RAM, starting at 0x0080, I would need to define a further segment -
Z_RAM0 = READ_WRITE  0x0080 TO 0x0087;
 
Is this behaviour of the linker, with respect to variables having an absolute address, documented anywhere?
 
Regards,
Mac
 


Message Edited by bigmac on 2007-07-14 12:55 AM
0 Kudos
Reply
1,608 Views
CompilerGuru
NXP Employee
NXP Employee
Variables are either places at a specific address (with the @) or they are placed in a section.
If there is a @, then the current section does not matter, so I guess crazycat's suggestion did include to remove the absolute declaration, well it did include it implicitely Smiley Wink.

As far as the linker is concerned, the linker does not place or move objects placed with a @ in anyway, they are actually handled identically to  assembly ORG sections. They are also not considered during the placement of relocatable objects into the segments, so the existence of a absolute object does not cause a gap in the relocatable objects.
Hmm not sure it is documented that what the linker is not doing Smiley Wink. In general the idea is if the user is placing the objects at a certain address he knows what he is doing and therefore if they should not overlap then he would exclude the range from the segments in the prm file.
Surprisingly often I did see that the linker warning for overlapping objects (which does occur for such cases) is explictely disabled, so there are really use cases for overlapping of absolute objects with actual content.

Note that you can place the Z_RAM0 segment just after the Z_RAM one.
....
 _DATA_ZEROPAGE, MY_ZEROPAGE         INTO  Z_RAM,Z_RAM0;


Daniel
0 Kudos
Reply
1,607 Views
bigmac
Specialist III
Hello Daniel,
 
Thank you for clarifying the situation.  With default settings for the project, I did not actually get any linker warnings.
 
Regards,
Mac
 
0 Kudos
Reply
1,607 Views
CompilerGuru
NXP Employee
NXP Employee
I created a project for the HC08 QY8, and then in the linker panel the wizard adds the options
"-WmsgSd1100 -WmsgSd1912 " which basically shuts up the linker.
When removing those options, the linker complains:
L1912: Object _COPCTL overlaps with another (last addr: 0x10000, object addr: 0xFFFF)

Which is not wrong either, _COPCTL:

extern volatile COPCTLSTR _COPCTL @0x0000FFFF;

shares the address with the second byte of the reset vector.
So the code works fine, but in the end the outcome of this setup is that the linker does not complain for overlappings anymore ;-(.

One solution would be to define _COPCTL as macro, but that's not done in the current headers.
Anyway, that's why the linker does not issue a warning.

Daniel

0 Kudos
Reply