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.

how to access __STACK_TOP?

Other Parts Discussed in Thread: MSP430F5419A

Hi,

I am getting an unresolved symbol error when trying to access __STACK_TOP in CCS developing for an MSP430f5419a chip.  I am able to get the __STACK_SIZE by doing the following, but it does not work for __STACK_TOP for some reason:

extern char __STACK_SIZE; 

void main(void){

       unsigned stack_size = _symval(&__STACK_SIZE);

       printf("stack size = %u\n", stack_size);

}

  • This is the wrong forum.  This forum is for the Stellaris family of microcontrollers.

    You should post in the MSP430 forums or in the CCS forums.

    Edit:  I replied to the post in the Stellaris forums, but now it seems the thread has been moved.

  • Are you sure __STACK_TOP does exist?

    __STACK_SIZE is ratehr a hint for the linekr, so it can throw an error if the variables grow so much that there is no more room for a __STACK_SIZE stack. I thas no effect on the code itself in any case.

    Teh placement of the top of stack, however, is something the linker handles internally, based on the processor description and the linker script for this processor. It is usually the top of ram and requires manualy change of the linker script file if you want to have it differently.

  • I guess it was only for Stellaris.  So there is no way to access the value of the address for the top of the stack during run time?  The reason is because I want to write an arbitrary value right at the top of the stack and do a  check to make sure the stack never overflowed.

  • I do not use CCS. But is there an intrinsic __get_SP_register ? Dose it return the current content of SP (pointing to the top of stack)?

  • To write something to top of stack, just use the push instruction at beginning of main (in case you don't have local variables on main - which wouldn't be smart anyway, as local variables on main are presistent (main never exits) but don't count when the linker checks for memory usage. Make them global or static instead.

    And it would be a stack underflow test. The stack usually starts at top of ram, which is also top of stack. Anything is added below. So unless you changed the linker scripts, the initial top of stack is the top of ram.

    To test for a stack overflow, you need to place a guard value somewhere below on ram - at the wanted guarding theshold position. The stack grows top-down. The stack overflows when it grows down below the top of your heap or the global variables area.
    No setting can prevent this. Any stack-size setting you can do in project preferences is just a hint for the linker and debugger and does not make it into the code itself.

  • yes, sorry my terminologies were incorrect.  I understand that I need to place the guard in RAM, but I would like to somehow detect the stack limit to place the guard.  

    For example, if I set the stack limit to 10 bytes in CCS, I would like to detect the address of where that limit is and put a guard there.  Basically I need to be able to extract that 10 bytes stack limit in code some how dynamically from CCS.

  • Harvey Ku said:
    I would like to somehow detect the stack limit to place the guard.  

    Sicne the MSP has no memory management unit that would allow programmable access restrictions (as required for any stack size limiting), there is no such thing as a stack limit from teh processor view. The 'stack size' settign you may configure doesn't make it into the code at all.
    For the linker, it jsut defines the size of a 'stack segment' tha tis placed on top of ram and 'blocks# part of the available ram for placing variables. There is no symbol that would give you an address or even just a size value. And the debugger uses it also directly form the project settings.
    If you compile the same code with different 'stack size' settings, the binaries will be 100% identical.

  • Hi Harvey,

    In IAR I use this in the __low_level_init( ) function which is automatically called early during cstartup:

    #pragma segment = "DATA16_N" __data16  // declare segment DATA16_N
    uint16* fencePtr = (uint16*) (((int) __segment_end("DATA16_N") + 1) & 0xFFFE);
    *fencePtr = 0xCAFE;
    

    The reason I use DATA16_N is because that's the last segment I put just before the stack.  In my case, I don't really care how much stack space I told IAR I needed, I only care if the stack grows into my DATA16_N area.  Using __segment_begin("CSTACK") would do what you asked about, instead of all the stuff I do with manipulating the pointer to the end of the DATA16_N area.

    Hope that helps, even though it probably doesn't apply directly to CCS.  (I use IAR.)  You compiler manual might describe the directives you need.

    Jeff

**Attention** This is a public forum