This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Andy Neil said:Should there?
First of all: thanks.
if i'm not mistaken the default CCSv5 settings assign 80 bytes of heap to the executable, obviously i checked the 80 bytes quantity but i cannot say if there's some checkbox somewhere that disable those setting.
that aside, since the code is supposedly configured with 80 bytes of heap, and since there's only a single call to "new" and none to "malloc", before that call, all the heap should be unused. Am i wrong?
Have you actually checked?
i checked the linker setting of the project but i cannot say if that's all i have to check.
Are you sure that your project is correctly configured for C++ ?
I don't know each and every quirk of CCS so, no, i cannot say I am sure. If I remember correctly, the CCSv5 should be able to manage the C++ code on its own, from the moment you let it know that you are writing C++ code. I didn't see any particular caveat on the compiler guide either, aside to avoid the many advanced features of C++.
In mi case i left all the CCSv5 configuration at default, and i simply used the ".cpp" filename extension in place of the ".c" one in every code file, aside the _pre_init.c file.
The "standard" header file i included are "new.h" and msp430f2274.h all the rest is code i wrote on my own, that's why i supposed there's no use of heap.
What should i check? is there a guide somewhere?
By the way, i didn't checked the box related to the c++ exception but even using the instruction
ptr = new (std::nothrow) char[2];
i got the same behaviour
UPDATE:
I created a new project based on the "blink the led" example and new seems to work gracefully...
After that i went back to the original project and i checked some of the parts i added.
The problem disappeared when i removed the pre_init.c file.
pre_init.c contains the following code, which is supposed to reset the ram:
#define RAMSTARTADDR 0x0200
#define RAMSIZE 0x0400
#define RAMINITEND (RAMSIZE - 6)
int _system_pre_init(void)
{
WDTCTL = WDTPW+WDTHOLD;
int i ;
char *ptr = (char *)RAMSTARTADDR;
for (i=0; i<RAMINITEND; i++)
{
*ptr = 0x00;
*ptr++;
}
return 1;
}
Looking at the compiler manual V4 (p.125) this function is called before the initialization, shouldn't be safe to use it?
Can someone explain what's really happening ? even a link is fine obviously.
Thank again.
I have repeated the failure (on a MSP430FR5739), in that using your _system_pre_init then causes new to "crash".
When _system_pre_init is called there are two function pointers lock and unlock in the first eight bytes of RAM which have already been initialised. Since the _system_pre_init zeros from the start of RAM it zeros these function pointers which is what seems to cause new to crash. The RTS source code is available in C:\ti\ccsv5\tools\compiler\msp430\lib\rtssrc.zip which shows that the memory allocation functions in memory.c uses the intrinsics _lock() and unlock() which I think call the lock and unlock function pointers.
When _system_pre_init was modified to not zero the first eight bytes of RAM then new no longer caused a crash.
What is the purpose of clearing the RAM using the RAMSTARTADDR / RAMSIZE definitions?
Chester Gillon said:I have repeated the failure (on a MSP430FR5739), in that using your _system_pre_init then causes new to "crash".
When _system_pre_init is called there are two function pointers lock and unlock in the first eight bytes of RAM which have already been initialised. Since the _system_pre_init zeros from the start of RAM it zeros these function pointers which is what seems to cause new to crash. The RTS source code is available in C:\ti\ccsv5\tools\compiler\msp430\lib\rtssrc.zip which shows that the memory allocation functions in memory.c uses the intrinsics _lock() and unlock() which I think call the lock and unlock function pointers.
When _system_pre_init was modified to not zero the first eight bytes of RAM then new no longer caused a crash.
Thanks for the suggestion. I'll look into that.
What is the purpose of clearing the RAM using the RAMSTARTADDR / RAMSIZE definitions?
As you can see here
http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/t/18872.aspx?PageIndex=8
the code is not mine, since i don't have all the elements to do such a thing on my own. If i'm not mistaken it is a general code which would fit on many devices, and thus the autor suggested the RAMSTARTADDR / RAMSIZE definitions to easily adapt the code to the device. In my case, since i used the MSP430F2274 i didin't need such adjustement ( or so i thought )
Even if it wasn't the case, i suppose hardcoding the addresses and the size would be worse in case of adjustment, debugging or even reading the code, is it not?
The fact that i didn't correct those defines accordingly it's a different matter though...
If the aim is to zero the .bss segment, rather than use #defines for the RAM size to clear it would be more reliable to use the linker symbols for the start and end of the bss segmment. See C:\ti\grace_1_10_00_17\packages\ti\targets\msp430\rts430\pre_init.c for how to do that. Using the linker symbols means only the bss segment get cleared and no #defines to change.
If i understand you correctly you are telling me that in case of a reset, to remove all the garbage due to the previous run there's no need to wipe the whole ram but just the .bss section? Is that so?
Without knowing how your program allocates variables (global, static, on the heap, on the stack), I can't provide a specific answer.
The System Initialization section of the MSP430 Optimizing C/C++ Compiler User's Guide contains the following note about a deviation from the ANSI/ISO standard:
By adding a custom _system_pre_init which only clears the bss segment global and static variables that are not explicitly initialized get set to zero as per the ANSI/ISO standard.Note
Initializing Variables
In ANSI/ISO C, global and static variables that are not explicitly initialized must be set to 0 before program execution. The COFF ABI C/C++ compiler does not perform any preinitialization of uninitialized variables. Explicitly initialize any variable that must have an initial value of 0.
My program is written in C++.
I made used some static objects ( class instances ) as hardware interfaces.
The ISR are static member function of those object, and their data members if any, are allocated on the stack.
The constructor of each is responsible to initialize the data members.
I also have an (one) additional object which is not static and hosts the pointers to the heap.
I didn't made use of global variable nor static ones aside the object i mentioned.
In the heap i have two linked lists created at run time.
**Attention** This is a public forum