Jump to content

How to print out the stack pointer through inline assembler?


Gertius
 Share

Recommended Posts

Hi, fellow MIDIboxers!

We are building a relatively complex MIDIbox as a university project, programming it in C, and the due date is nearing very quickly (next monday). I have posted about the project two or three times already, and we will have a detailed wiki explaining everything very soon.

Now that our code size has grown and grown (we already migrated to PIC18F4620) we encountered another strange problem yesterday, that we hope to find some help for here.

The problem is that function parameters (data type "long" and others) are not transfered correctly into the functions since some days, which leads to very strange behaviour. It means that for example an address for a memory access function is correct before that function is called, but is corrupt inside the function, directly after the call (no calculations done yet in the function). We found out by reading out the values over MIDI before and after the function call.  Now we assume that our stack might get an overflow by using too many local variables. Is that probable? How big is the stack exactly? We read about 31 items in the PIC18F4620 datasheet, could that be? How could we read out the stack pointer variable (STKPTR) through inline assembler code to determine if there was an overflow? We would really appreciate some lines of assembler code and how they could be inserted into our C code, as we have no idea of programming assembler.

Thanks in advance,

Christian

Link to comment
Share on other sites

Hi Christian,

I don't know about the stack, but you can insert assembler code into C by using the following scheme:

/////////////////////////////////////////////////////////////////////////////
// This is an assembly optimized function which scales a 7bit value between
// a minimum and maximum value
/////////////////////////////////////////////////////////////////////////////
unsigned char Scale_7bit(unsigned char value, unsigned char min, unsigned char max)
{
  // scaled value is (<8-bit random> * ) >> 8
  PRODL = value << 1; // 8bit value
  PRODH = max-min+1;  // range
__asm
    movf _PRODL, W
    mulwf _PRODH, 0
__endasm;

  return min + PRODH;
}

This example was taken from the scaling pot values C-example found at http://www.ucapps.de/mios_c_send_range.html.

Best regards, ilmenator

Link to comment
Share on other sites

I am quoting the PIC 18F4620 data sheet found at http://ww1.microchip.com/downloads/en/DeviceDoc/39626b.pdf, page 54:

5.1.2.1 Top-of-Stack Access

Only the top of the return address stack (TOS) is

readable and writable. A set of three registers,

TOSU:TOSH:TOSL, hold the contents of the stack

location pointed to by the STKPTR register (Figure 5-2).

[glow=red,2,300]This allows users to implement a software stack if

necessary.[/glow] After a CALL, RCALL or interrupt, the

software can read the pushed value by reading the

TOSU:TOSH:TOSL registers. These values can be

placed on a user defined software stack. At return time,

the software can return these values to

TOSU:TOSH:TOSL and do a return.

The user must disable the global interrupt enable bits

while accessing the stack to prevent inadvertent stack

corruption.

This does not solve your immediate problem, because you only want to find out if the stack is actually overflowing, but at least you can be sure there is a solution in case that is causing your trouble. I would think there must be some application example from Microchip on how to implement a software stack, but I'm afraid I am not of great help with that.

TK to the rescue...  :(

Best regards, ilmenator

Link to comment
Share on other sites

You might wanna take a look at the indispensable sdccman.pdf as well... I've got a vague memory that some of the C stuff uses the stack and might be overwriting your locations.

As said above, you could try storing the stack pointers in your own variables at the beginning of the offending function, but I'd also be looking at this sentence closely:

The user must disable the global interrupt enable bits

while accessing the stack to prevent inadvertent stack

corruption.

Have you tried disabling interrupts?

Link to comment
Share on other sites

The stack boundaries are defined in the file header of mios_wrapper/mios_wrapper.asm:


; the upper boundary of the stacks are defined here
; customize the values for your needs
#ifndef STACK_HEAD
#define STACK_HEAD 0x37f
#endif

#ifndef STACK_IRQ_HEAD
#define STACK_IRQ_HEAD 0x33f
#endif
[/code]

The default setup is 64 bytes for main tasks, 64 bytes for interrupt tasks. (stack pointer is counted down, there is no collision control to save runtime)

Since a PIC18F4620 has enough memory, you could use two 256 bytes stacks located at the upper RAM pages:

#define STACK_HEAD 0xeff

#define STACK_IRQ_HEAD 0xdff

this should relax the situation.

Note that the appr. memory area (0xd00-0xeff) should be reserved in the projekt.lkr file

Best Regards, Thorsten.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...