EmbeddedRelated.com
Forums

Solved Rabbit Hole Problem

Started by "mra...@hofferflow.com [msp430]" June 3, 2014
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

Beginning Microcontrollers with the MSP430

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