How to prevent the linker error "Call Stack Overflow&qu

General discussion on mikroPascal.
Post Reply
Author
Message
PC Pete
Posts: 68
Joined: 10 Nov 2005 09:19
Location: Melbourne, Australia
Contact:

How to prevent the linker error "Call Stack Overflow&qu

#1 Post by PC Pete » 07 Mar 2009 11:06

I'm using some very simple procedures to help me figure out why some word-to-float-to-byte conversions are going hopelessly wrong, but as soon as I add a procedure call to an existing simple non-nested procedure, I get the "Call Stack Overflow" when I try to build the project.

My ROM usage is less than 60%, my RAM usage is less than 40%, but as soon as I put the call in, I can no longer compile!

The procedure I'm calling is :

Code: Select all

procedure WriteWordValue(var TextString : string[20]; Dval : word);
var
 DWS : String[5];
begin
  Write(TextString);
  WordToStr(DVal, DWS);
  WriteLn(DWS);
end;
The procedure I'm calling it from is as follows :

Code: Select all

function ReadADCChannel(Channel : byte) : word;
begin
  // Configure the ADC again.
  if (Channel = 0) then ADCON0 := $81
  else ADCON0 := $81 or (Channel shl 3);      // enable the ADC, with slowest ADC clock prescaler possible (Fosc/64).
  ADCON1 := $C2;                         // Right justified, Fosc/64, A0..A4 analogue, A5..A7 digital
  // Unconfigure the interrupt
  INTCON.PEIE := 0;
  INTCON.GIE := 0;
  PIR1.ADIF := 0;
  // wait a while (Tad minimum is 12 uS)  - in our case that's 5 milliseconds. It's not that critical, but has to be done.
  Delay_ms(ADC_DELAY);
  // start conversion
  ADCON0.GO := 1;
  repeat until ((ADCON0.GO) <> 0);
  // clear ADIF
  PIR1.ADIF := 0;
  // read the register pair
  Result := (ADRESH shl 8) + ADRESL;
///WriteWordValue('RADCC: Result is',Result);
end;
Now, this procedure is called only once in the entire program, but it's called by a procedure that's in the main code loop (while true do... etc).
It compiles fine until I uncomment the last line, then no matter what I do, I can't get the linker to work.

Can anyone suggest a workaround or should I log this as a formal linker bug?

I guess it's not easy to be really clever with a compiler/linker in such a crippled architecture, but I thought I was doing the right thing, and I'm completely snookered.

My workaround is to call the routine from an inline ASM block in the ReadADCChannel() procedure, but this is not helpful if I have to manually insert inline assembler every time I want to debug legal and valid pascal code. So I must be misinterpreting something really obvious, but I can't see what it is!
Data is not Information. Information is not Knowledge. Knowledge is not Wisdom.

jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

#2 Post by jpc » 07 Mar 2009 12:00

i did not see this post before answering the other , start to get the picture now. I suppose you are using a P16 device which has a stack-depth of only 8. I think you are using more calling-levels than that you are aware of. Best information can be obtained by looking in the procedure details tab of the statistics view , the little example i have shown in the other post already results in a max stack-depth of 5. In reality you must add to this the number of levels used by interrupts which i suspect to be present as you take the effort ( not sure this is required btw ) of replacing the Adc_Read by your own which messes around with interrupts. Then you mention the writewordvalue() procedure which seems to call a writeln() which calls ????

If there is no way to reduce the number of call levels you might consider a P18 chip instead.

PC Pete
Posts: 68
Joined: 10 Nov 2005 09:19
Location: Melbourne, Australia
Contact:

#3 Post by PC Pete » 08 Mar 2009 01:21

jpc, thanks so much for explaining about the stack depth.

You're absolutely right, I'm using a 16 (midrange) device (16F877A) for all these code snippets (the local Microchip FAE is coming over this week with my 18F4620s, so "upgrading" to the 18 series PICs will probably help eliminate a few of these issues I'm having).

I don't actually use interrupts in this project, since it's really simple and not time-dependent (well, not time-dependent over tens of seconds upwards). So maybe that is helping this time.

This is not the first time I've had problems with routines being passed parameters (by value and/or by reference) some of which may then be passed to another routine. I thought it must be due to my limited understanding of the MP stack mechanism, but I didn't know why... (I hate not knowing why! :?)

I'll get rid of the parameters and use a couple of globals.

Thanks again for your time.
-PCP

jpc
Posts: 1986
Joined: 22 Apr 2005 17:40
Location: France 87

#4 Post by jpc » 08 Mar 2009 08:48

the call stack depth is not related to the parameters , as such you do not need to go for global variables . In the next compiler release we will get better scope and visibility rules which , if well understood , allow you to have better controll . I can only advise you to start learning with interrupts , once you understand them they are very powerfull and you will never want to do without them any more.

PC Pete
Posts: 68
Joined: 10 Nov 2005 09:19
Location: Melbourne, Australia
Contact:

#5 Post by PC Pete » 08 Mar 2009 09:43

I do understand and use interrupts in nearly all my projects, I just don't need or want interrupts in this simple application.

But better/clearer scope rules would be a great help for me in this situation too.

I'll keep watching and waiting for the next release.

I'd like to understand the stack issue, since this is stopping me from properly debugging the live hardware. Adding a single procedure call to a procedure that doesn't use the stack explicitly is just downright confusing. It implies that the calling code is simply a bunch of inline statements, which I guess it is if I take off my real Pascal hat. But adding a call to a procedure shouldn't have anything to do with the stack - certainly not when compiling!

I'll keep plugging along doing the best I can.

Thanks again for your time and help!

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

#6 Post by janni » 08 Mar 2009 11:59

PC Pete wrote:I'd like to understand the stack issue, since this is stopping me from properly debugging the live hardware. Adding a single procedure call to a procedure that doesn't use the stack explicitly is just downright confusing. It implies that the calling code is simply a bunch of inline statements, which I guess it is if I take off my real Pascal hat. But adding a call to a procedure shouldn't have anything to do with the stack - certainly not when compiling!
You're confusing data stack (which is absent in mP for PIC16/18s) with a hardware stack (ROM addresses stack). Procedures & functions' parameters aren't placed on any RAM stack, but every call to them uses one level of hardware stack to remember the return address. With just 8-levels deep hardware stack the PIC16s aren't really suitable for higher level languages.

Post Reply

Return to “mikroPascal General”