Hello,
Got a reply from TI. They suggested this as another way to solve my
problem:
Custom linker configurations are an option as well.
If you modify this line from your XCL file to exclude the first segment that
aligns to address 0x30000 (0x30000-0x301FF);
-P(CODE)CODE\00-FF7F,10000-45BFF
to
-P(CODE)CODE\00-FF7F,10000-2FFFF,30200-45BFF
The linker is now unaware of this space for linking CODE.
This sounds reasonable, but I think I'll stick with my simple,
straightforward method.
Live long and prosper,
Mike Raines
________________________________
From: m... [mailto:m...]
Sent: Tuesday, June 03, 2014 12:33 PM
To: m...
Subject: [SPAM] [msp430] Solved Rabbit Hole Problem
Importance: Low
Hi folks,
Some of you may remember awhile back I posted about a weird problem where
adding more code or functions to the project caused functional code in other
parts to fail while executing seemingly simple intrinsic functions like atof(),
sprintf(), or even __delay_cycles(). I now see that I left the segment from
0x30000 + sizeof(sysConfigurationType) to end of segment unprotected and by
adding more code, eventually the compiler/linker stored functions there that
then got erased. I want to tell all emphatically that I would probably still be
in the rabbit hole if it wasn't for the good help from Michael Stevens at
TI and his team. I was, of course aware of this condition and had devised an
algorithm to prevent the compiler/linker from placing any code in the unused
portions of 512 byte segments that might be erased by my code. This has worked
well in other projects for us. The algorithm is two parts: First, placing an
array of chars at the end of the used portion of the segment. The array is
sized to take up the entire rest of the segment. The array is designed to be a
placeholder and is never really used.
__no_init __data20 sysConfigurationType sysConfigurationNv@0x30000; // Old Trip
log beginning
const int unusedConfigNv = (0x200 - sizeof(sysConfigurationType));
__no_init __data20 unsigned char configPlaceHolder[unusedConfigNv] @ (0x30000
+ sizeof(sysConfigurationType));
This brings us to the second part to the algorithm: I discovered that if I did
not "use" the array, the compiler/linker would ignore the fact that I had
declared that portion of memory and would write anything it wanted there. In
the rabbit hole case, it apparently placed intrinsic functions like atof() and
__delay_cycles() there. They were erased when I erased the configuration
parameters, and later when they were called, instant rabbit hole. The second
part is to "pretend" to use the placeholder array. In function
WriteSysConfigNv1() I set all of the elements of the placeHolder array to 0X00.
This "fools" the compiler/linker and it does not place anything in the
placeholder memory that might get erased.
In this software, I followed both steps of my algorithm for the segment where I
stored the kfactor tables, but I overlooked step 2 when implementing the storage
of the sysConfiguration. In the old project I copied from, sysConfiguration is
stored in INFO A memory. Since the compiler/linker will not place anything in
INFO memory unless I instruct it to do so, part 2 was not needed. When I copied
the old code to new project, I did not notice that I needed part 2. Eventually,
as I added more code, the compiler/linker had to start using upper memory to
store things and some of these things were erased.
In the future, I will pay closer attention to this problem, and if I see bizarre
behavior where adding code causes failures in other parts of the program, I will
suspect that the points of failure are probably where needed code has been
erased or overwritten.
To fix the current problem, I just added step 2 to the function
WriteSysConfigNv1() by writing zero to each byte of the placeholder array.
#if 1 // needed because optimizer does not reserve memory
unless variables actually used
for (int i=0; i
{
configPlaceHolder[i] = 0x00;
} // end for each to end of segment
#endif // // needed because optimizer does not reserve memory
unless variables actually used
This "fools" the compiler/linker" and it will not reuse this memory space for
anything else.
I know I could move the sysConfiguration parameters to INFO memory and just
leave out step 2, if they will fit into 128 byte segment.
The question remains, is there a better way to handle this?
Thanks for your time,
Mike Raines
size=1 width="100%" noshade color="#a0a0a0" alignter>
No virus found in this message.
Checked by AVG - www.avg.com
Version: 2014.0.4592 / Virus Database: 3955/7611 - Release Date: 06/02/14