Debug stack start off with an ISR at bottom

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

Debug stack start off with an ISR at bottom

3,088件の閲覧回数
cab
Contributor III

CW10.2(1.0.0) MC9S08LG32 Win7x64.

 

How does this happen--and how can I stop it?  Note that main() is called from Viic_isr.  Of course I cannot get any IIC interrupts.

 

MISTER_MC9S08LG32_PnE U-MultiLink [CodeWarrior Download]  HCS08, MISTER.abs (Suspended)   Thread [ID: 0x0] (Suspended: Signal 'Halt' received. Description: User halted thread.)    4 main() main.c:139 0x8915    3 vprintf() printf.c:548 0x8c96    2 Viic_isr() i2c.c:317 0x87f6    1 0x7F32 (0x7F32)()  0x7f32  C:\Users\John\workspace500\MISTER\MC9S08LG32\MISTER.abs (6/6/12 11:01 PM)

 I don't do a CLI inside of that isr--in fact, this is my beginning Debug stack--before sny code has been executed.  It appearts to make a difference where I put the EnableInterrupts.  This is how this one starts off

void main(void) {  int temp;  int k;  char ch;   chipinit();  startRTC();/*Real-time clock*/  EnableInterrupts  ...

No CLI in chipinit().  Not even any IICC_IICIE--that happens later on.  If I comment out //EnableInterrupts, then the stack is OK.

ラベル(1)
タグ(1)
0 件の賞賛
返信
9 返答(返信)

2,459件の閲覧回数
BlackNight
NXP Employee
NXP Employee

Hello,

are you using printf()/sprintf()/vprintf() in your code? If so, they use a *lot* of stack. So what you see could be a corrupted/overflowed stack. Anything weired could happen then.

In any case, if you have some RAM left: give all what you have for the stack (in the linker .prm file).

 

Additionally, I'm not sure you say that everything is ok if you are *not* enabling interrupts, or if things are ok if you enable interrupts?

By default on reset the I bit is masked/set (no interrupts). Maybe step through your main() code with the debugger and inspect the CCR register (registers view) if the I bit is set (interrupts disabled) or cleared (interrupts enabled).

 

Hope this helps,

BK

0 件の賞賛
返信

2,459件の閲覧回数
cab
Contributor III

Thanks for your response, BK.

 

Yes, I am using sprintf().  This is a text-based application.  That may explain the vprintf() at the bottom, sometimes.  However, did I make it clear that this is the initial debug startup?  I'm guessing start08() has been called and suspended at main()?  How can the stack overflow already?

  • EnableInterrupts
    - If I comment out this macro, I don't get the Viic_isr at the bottom (below main) in my initial setup.  Or if I change the precise placement of EnableInterrupts, sometime I get the "bad" setup, sometimes not.  I'm assuming I need to do whatever it takes to get the Viic_isr out of the initial calling stack.

-Cab-

0 件の賞賛
返信

2,459件の閲覧回数
rocco
Senior Contributor II

Hi Cab,


cab wrote:

. . . I'm guessing start08() has been called and suspended at main()? . . .

. . .  I'm assuming I need to do whatever it takes to get the Viic_isr out of the initial calling stack.


I don't think you are reading the stack dump the same way I am. But I'm not sure I'm reading it right. I'm reading it as if the oldest entry is on top (4, main), and the most recent entry is on the bottom (1, location 0x7f32).

 

What it looks like to me is that you successfully started main(), and main() called vprintf() at some point. While vprintf() was executing, the IIC interrupt occurred, and you vectored into Viic_isr(). The problem appears to take place while inside the isr after a call to location 0x7F32, which is prior to the address of the isr.

 

Maybe an errant return or a bad branch? I don't think it is a stack overflow, as there appears to be only three calls and one interrupt on the stack.

0 件の賞賛
返信

2,459件の閲覧回数
cab
Contributor III

Thanks for sticking with me BK-

 

From Debug (configurations), which pauses at main(), I see the following initial Debug stack:

 

MISTER_MC9S08LG32_PnE U-MultiLink [CodeWarrior Download]  HCS08, MISTER.abs (Suspended)   Thread [ID: 0x0] (Suspended: Signal 'Halt' received. Description: User halted thread.)    3 main() main.c:145 0x8a5b    2 vprintf() printf.c:671 0x9004    1 0x9F95 (0x9F95)()  0x9f95  C:\Users\John\workspace500\MISTER\MC9S08LG32\MISTER.abs (6/10/12 9:24 PM)

I should be at the first statement in main because I did not hit Resume, Step or Run. Please see the attached image.

 

If I step ahead into chipinit() I see the following stack:

MISTER_MC9S08LG32_PnE U-MultiLink [CodeWarrior Download]  HCS08, MISTER.abs (Suspended)   Thread [ID: 0x0] (Suspended)    4 chipinit() hardwarecode.c:27 0x846b    3 main() main.c:150 0x8a60    2 vprintf() printf.c:671 0x9004    1 0x9F95 (0x9F95)()  0x9f95  C:\Users\John\workspace500\MISTER\MC9S08LG32\MISTER.abs (6/10/12 9:09 PM)

So it looks like main() is called from vprintf() [please disconfuse me, BK].  I do not know why vprintf() is even in the picture, it is not always there, but as long as it is not Viic_isr() shown in my original post, I am not going to fret.

 

In the original post it was

MISTER_MC9S08LG32_PnE U-MultiLink [CodeWarrior Download]  HCS08, MISTER.abs (Suspended)   Thread [ID: 0x0] (Suspended: Signal 'Halt' received. Description: User halted thread.)    4 main() main.c:139 0x8915    3 vprintf() printf.c:548 0x8c96    2 Viic_isr() i2c.c:317 0x87f6    1 0x7F32 (0x7F32)()  0x7f32  C:\Users\John\workspace500\MISTER\MC9S08LG32\MISTER.abs (6/6/12 11:01 PM)

I have some print-statements in my Viic_isr() so Viic_Isr() calling vprintf() makes sense.  But main.c:139 is the beginning of the definition of main{ ...}.  printf.c:548 is..

#if LIBDEF_PRINTF_PTR            if ((sizeof(void*) != sizeof(unsigned int)) && ((flags & _PRINTF_PTR) != 0U)) { /*lint !e506 !e774 !e845 , MISRA 13.7 REQ & MISRA 14.1 REQ, target-dependent Boolean expressions */              /* support for %p for targets with non int pointer sizes */              /*lint -e{506} , MISRA 13.7 REQ & MISRA 14.1 REQ, default data type formats can be changed with the -T option */              /*lint -e{923} , MISRA 11.3 ADV, the cast is necessary, see comment above */              val = (unsigned _PRINTF_INTEG)va_arg(args, void*);            } else {              /*lint -e{506} , MISRA 13.7 REQ & MISRA 14.1 REQ, default data type formats can be changed with the -T option */              uint_tmp = va_arg(args, unsigned int);  <<<<<<<<<<<<<<<<<<<<<line 548              val = (unsigned _PRINTF_INTEG)uint_tmp;            }#else

So, though I do not understand the startup code, it does look like it intends main() to be called from vprintf().  But why Viic_isr() -- I don't undertand enough to  continue here.  Thanks for your ear.

 

-Cab-

0 件の賞賛
返信

2,459件の閲覧回数
bigmac
Specialist III

Hello,

 

I do not know what your "debug stack" display is meant to represent,  It appears that it is probably not a representation of "the stack" resident within RAM.  I have never seen this display within CW 6.3.

 

Unless there have been major changes within CW 10.x, I might expect that the _Startup function within start08.c would be called by means of the reset vector.  I would then expect this function to exit by directly jumping to the main() function, without leaving a return address on the stack (because main shall never exit).

 

I might then reasonably expect that space would be created on the stack for your three local variables defined within main().  This stack space would normally never be released.

 

The chipinit() funcion would then temporarily leave its return address on the stack, successively followed by the return address for the startRTC() function.  Up until this point interrupts should be globally disabled, so nothing associated with any interrupt should be present on the stack.

 

Why did you think that the startup code might be calling vprintf()?  Since the printf() functions, including sprintf() and vprintf() are complex and time consuming functions, they should definitely not be called from within any ISR function.  Additionally, they consume kilobytes of code space, and are stack hungry.

 

Regards,

Mac

 

0 件の賞賛
返信

2,459件の閲覧回数
CompilerGuru
NXP Employee
NXP Employee

It actually does represent the stack as it is in RAM :-)/

But one important note was provided by bigmac, the default startup code does not store the any return address main would return too on the stack. Therefore the debugger code reconstructing the call chain by reading the memory content cannot deduce who called main the usual way. Instead it either has to somehow (magically) know that the call chain should end at main, or if such a magic is not builtin or available (my guess in CW 10.x), it will read further up in the RAM outside of the actual stack and will reconstruct bogus entries as "callers" of main. I would guess that is what here is happening here.

If the code is not behaving as you expect it, I would recommend to look in the other direction, the functions main is calling.

If the code is using sprintf and similar functions, make sure the stack is big enough. If not certain, increment the size in the prm file. You can also tweak in start08.c the "JMP main" code to a "JSR main" in the HLI code calling main. This will waste 2 bytes of RAM, but it will keep on showing that _Startup did call main in the debugger.

Another approach to address the issue of a bogus main caller entry would be to allocate the stack at the end of the RAM, then that could be used by the debugger to detect that there is no known caller of main.

 

Daniel

0 件の賞賛
返信

2,459件の閲覧回数
cab
Contributor III

I have been away, but I am very interested in your replies--BK, BigMac, Daniel.  I hope it is clear to everyone that this is the -initial-display none of my code has been executed--I am very confused how the size of my stack could possibly cause it--but what do I know?  The startoff is not a constant--usually just main() -- sometimes as many as three viic_isr's or two! main()'s.

  • Daniel- You are suggesting that this is just an artifact.  When I saw viic_isr() below main() I supposed that the I-bit would be on--but not so, the program seemed to function normally.
  • Is this another of those features that only dogs me and nobody else?
    .
  • I'lll likely implement the good stack suggestions anyway, because I have been bit by stack overflow before.  I don't know why stack at the top of ram is not the default--that's always better isn't it?
0 件の賞賛
返信

2,459件の閲覧回数
bigmac
Specialist III

Daniel,

 

If the debug stack does represent a comprehensive picture of the stack RAM, how can the missing allocations for the local variables declared within main() be explained?  Is it possible that the compiler would automatically treat these as non-stack based in this specific instance?

 

Cab,

 

Your present observations are not to do with the stack size.

 

By default, with STACKSIZE specified within the PRM file, the stack will commence immediately above the RAM allocated to global and static variables by the linker.  I presume it was done this way so that any remaining RAM above the stack would be available as a heap for dynamic memory allocation.  However, for embedded code within an 8-bit MCU, dynamic memory allocation would be rarely, if ever used.  It requires significant overhead resources.

 

To locate the stack at the top of RAM, you would need to specify STACKTOP within the PRM file, in lieu of STACKSIZE.  Additionally, you should also set up a stack segment above the modified RAM segment range.  The range of this segment will dictate the maximum stack size usage, and will provide linker warnings should the allocation of global and static variables infringe on the stack segment.

 

Regards,

Mac

 

0 件の賞賛
返信

2,459件の閲覧回数
BlackNight
NXP Employee
NXP Employee

Hi cab,

I still think you have a corrupted stack.

Could you check your stack size in the linker .prm file?

I would set it to

STACKSIZE 0x0500

if this helps.

 

As for the startup code: __startup() calls main(), then calls all the rest. So what you see on the stack that vprintf() calls main() indicates me that something on the stack is wrong.

Additionally, I see from your screenshot that you are on the first line of main(). Is the picture the same if you do a single step into main()? Maybe the stack frame has not been set up yet by the code.

 

Hope this helps,

BK

0 件の賞賛
返信