HCS08- Stack Control

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

HCS08- Stack Control

Jump to solution
2,673 Views
rdazcal
Contributor III

Hi all,

 

How do I read the stack pointer address in a C language code? I am using the MC9S08LC60 MCU.

 

I wanted to have some control of my stack pointer where-abouts. I'm afraid it will overflow when I least expect it, specially since I have only estimated it, but am not sure at all how close to overflowing I actually am.

 

I have a timer interrupt, and I believe that's the most critical point, since it may be triggered when the main thread is in it's most nested condition (where stack is at it's lowest), so if I can detect the lowest stack value in that condition, I'll have a good estimate if my stack is well dimentioned.

 

If you have other stack control ideas, I'll be happy to hear them.

 

Thank you

Labels (1)
0 Kudos
Reply
1 Solution
1,185 Views
Lundin
Senior Contributor IV

The easiest and cleanest way is to use inline assembler: then you can read the SP right away. In pure C language you would have to use some sort of dirty hack like this:

 

interrupt void isr (void)

{

  volatile uint32 debug_sp = 0;  /* volatile so that it wont be optimized away, uint32 so that it is guaranteed to end up on the stack and not in an accumulator. */

 

  if( (uint16)&debug_sp - STACK_START > some_size)

  {

    do_something();

  }

}

 

 

Another trick is to download the program with the BDM, then in the debugger set the whole stack area to some unlikely value like 0xAA. Let the program run for a while, halt it and check the stack, to see at which address 0xAA still exists without having been overwritten. If there is no 0xAA anywhere, the stack has overflowed.

 

View solution in original post

0 Kudos
Reply
7 Replies
1,185 Views
kef
Specialist I
  •  have a timer interrupt, and I believe that's the most critical point, since it may be triggered when the main thread is in it's most nested condition (where stack is at it's lowest), so if I can detect the lowest stack value in that condition, I'll have a good estimate if my stack is well dimentioned.

 

Not at all. Timer interrupt is often synchronized with main routine. If for example main thread is not executing most nested routines until timer interrupt signals something, then your most critical point can be synchronized and happen always somewhere between two adjacent timer interrupt events.

 

You could clear stack space or initialize it with some constant before enabling interrupts and jumping to main(). Then you could periodically scan stack space upwards from the bottom to find first occurence of modified byte. Or, better, to make checks faster, just check if safe minimum of N bytes was not modified.

0 Kudos
Reply
1,186 Views
Lundin
Senior Contributor IV

The easiest and cleanest way is to use inline assembler: then you can read the SP right away. In pure C language you would have to use some sort of dirty hack like this:

 

interrupt void isr (void)

{

  volatile uint32 debug_sp = 0;  /* volatile so that it wont be optimized away, uint32 so that it is guaranteed to end up on the stack and not in an accumulator. */

 

  if( (uint16)&debug_sp - STACK_START > some_size)

  {

    do_something();

  }

}

 

 

Another trick is to download the program with the BDM, then in the debugger set the whole stack area to some unlikely value like 0xAA. Let the program run for a while, halt it and check the stack, to see at which address 0xAA still exists without having been overwritten. If there is no 0xAA anywhere, the stack has overflowed.

 

0 Kudos
Reply
1,185 Views
klasen
Contributor I

Hi, it's been a year since this thread was active, but maybe you are still "around"...

 

Inline assembler for reading the SP to a c-variable; what would this look like. Totally inexperienced in assembler coding...

0 Kudos
Reply
1,185 Views
bigmac
Specialist III

Hello, and welcome to the forum.

 

Maybe the following for HCS08 -

 

unsigned int readSP( void){   unsigned int temp;   __asm  tsx;      // Transfer stack pointer+1 to H:X   __asm  aix  #-1;   __asm  sthx temp;   return temp;}

Regards,

Mac

0 Kudos
Reply
1,185 Views
klasen
Contributor I

Thanks! Exactly what I was looking for!

0 Kudos
Reply
1,185 Views
bigmac
Specialist III

Hello,

 

Perhaps I should clarify one aspect, which I had previously over-looked.

 

Since the previous code snippet described a separate function, in which a 16-bit local variable was also defined, the stack pointer address returned by the function will be that within the function.  However, if you require the stack pointer address present just prior to the function call, the adjustment should be  __asm  aix  #3, rather than __asm aix #-1, to allow for both the local variable and the return address.

 

Regards,

Mac

 

0 Kudos
Reply
1,185 Views
rdazcal
Contributor III

Lundin, Kef

 

Filling the RAM with 0xAA in BDM worked beautifully! I can now see clearly how deep the stack goes!

 

Thank you both for your answers!

0 Kudos
Reply