HCS08- Stack Control

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 
3,400件の閲覧回数
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,912件の閲覧回数
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,912件の閲覧回数
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,913件の閲覧回数
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,912件の閲覧回数
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,912件の閲覧回数
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,912件の閲覧回数
klasen
Contributor I

Thanks! Exactly what I was looking for!

0 件の賞賛
返信
1,912件の閲覧回数
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,912件の閲覧回数
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 件の賞賛
返信