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.
I have been unable to specify an entry point using CCSv5 and MSP430 linker version 4.2.1. I have specified my entry point in Properties->MSP430 Linker->Advanced Options (--entry_point). I have specified the the object file containing my entry point as the first to be linked (Properties->MSP430 Linker->File Search Path). The linker always seems to link _c_int00, as I get the following error with each attempt:
"../lnk_msp430f5438a.cmd", line 221: error #10099-D: program will not fit into
available memory. placement with alignment fails for section ".reset" size
0x4 . Available memory ranges:
RESET size: 0x2 unused: 0x2 max hole: 0x2
Is there any way to stop the linker from linking in _c_int00? I have even tried changing my entry point to _c_int00, but then the linker complains of a duplicate symbol.
Hi Steve,
Interesting question. I was wondering why you are trying to change the entry point? Is there a reason for making your own c-startup code for _c_int00 instead of using the one from the run-time support library? I'm just wondering, because there may be an easier option here (like using __system_pre_init() for example to be able to set some things before main). Or maybe you are implementing a custom main-memory bootloader like in MSP-BOOT (www.ti.com/.../slaa600 )?
From what I can find in the linker information in www.ti.com/.../slau131 section 8.4.11 Define an Entry Point, it says: "The _c_int00 symbol must be the entry point if you are linking code produced by the C compiler." Which would mean you'd have to override _c_int00 with your own version. Looking at the code that goes with MSP-BOOT software-dl.ti.com/.../index_FDS.html it does include an example of overriding _c_int00 (look in the file boot.c), so you may want to use this as a reference if there's no other way to achieve your goal.
Regards,
Katie
Hi Steve,
Maybe something in your project setting would be needed as well. Your comment reminded me of something from earlier this year: RE: Creating a custom BSL for firmware update - MSP low-power microcontroller forum - MSP low-power microcontrollers...
I took a look at boot.c in the run time support library. I'm using a newer compiler version, but hopefully this hasn't changed much. I can find the rts library source code in my ccsv6 installation at C:\ti\ccsv6\tools\compiler\msp430_4.2.6\lib\src. Looking in boot.c, I see this:
/*****************************************************************************/ /* C_INT00() - C ENVIRONMENT ENTRY POINT */ /*****************************************************************************/ #pragma CLINK(_c_int00) CSTART_DECL _c_int00() { STACK_INIT(); /*------------------------------------------------------------------------*/ /* Allow for any application-specific low level initialization prior to */ /* initializing the C/C++ environment (global variable initialization, */ /* constructers). If _system_pre_init() returns 0, then bypass C/C++ */ /* initialization. NOTE: BYPASSING THE CALL TO THE C/C++ INITIALIZATION */ /* ROUTINE MAY RESULT IN PROGRAM FAILURE. */ /*------------------------------------------------------------------------*/ if(_system_pre_init() != 0) _auto_init(); /*------------------------------------------------------------------------*/ /* Handle any argc/argv arguments if supported by an MSP430 loader. */ /*------------------------------------------------------------------------*/ _args_main(); exit(1); }
Then looking in boot.h, I see STACK_INIT() is really just defined as:
/*---------------------------------------------------------------------------*/ /* Macro to initialize stack pointer. Stack grows towards lower memory. */ /*---------------------------------------------------------------------------*/ #if defined(__LARGE_DATA_MODEL__) #define STACK_INIT() __asm("\t MOVX.A\t #__STACK_END,SP") #else #define STACK_INIT() __asm("\t MOV.W\t #__STACK_END,SP") #endif
So I think really the only thing that STACK_INIT() actually changes is the value of the SP register. You could simply change it back to wherever else you want (wherever maybe you know you have space in RAM to have stack while you are doing your copy to NVM?) in _system_pre_init, and I don't think that should really have changed anything in RAM.
As a note, this is actually what our new Compute Through Power Loss (CTPL) library does (it is part of our new MSP-FRAM-UTILITIES for FRAM devices). That library is using _system_pre_init to bypass our normal c-startup code variable initialization etc, because in that case we are wanting to copy the variables and peripheral states that we saved to FRAM as we were losing power back into the peripheral registers and RAM, rather than using initial startup values - this includes the stack being initialized to the same state it was in as we were losing power. So that library simply lets the STACK_INIT() call in _c_int00 occur, but then in _system_pre_init simply reinitializes the SP (and stack values in RAM) to whatever we'd saved.
Regards,
Katie
Katie,
Again, thank you for the quick response.
I do understand that STACK_INIT() only modifies the stack pointer, but the SP is the most important bit of state information that we are trying to preserve, as the purpose of saving RAM is for crash analysis. We absolutely must be able to specify our own entry point for this reason.
- Steve
**Attention** This is a public forum