HCS08- Stack Control

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

HCS08- Stack Control

跳至解决方案
3,388 次查看
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

标签 (1)
0 项奖励
回复
1 解答
1,900 次查看
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 项奖励
回复
7 回复数
1,900 次查看
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 项奖励
回复
1,901 次查看
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 项奖励
回复
1,900 次查看
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 项奖励
回复
1,900 次查看
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 项奖励
回复
1,900 次查看
klasen
Contributor I

Thanks! Exactly what I was looking for!

0 项奖励
回复
1,900 次查看
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 项奖励
回复
1,900 次查看
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 项奖励
回复