Shop OBEX P1 Docs P2 Docs Learn Events
Calculate Stack Space? — Parallax Forums

Calculate Stack Space?

James LongJames Long Posts: 1,181
edited 2006-09-16 22:51 in Propeller 1
Ok....so I seached the forums.....what is the proper way to calculate the stack for a new cog?

I may have not seached right....so if there is a previous thread....just point me to the right thread.

I'm learning....I promise.

James L

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2006-09-15 23:22
    There really isn't a good discussion of this. There is a small utility program that watches memory and reports how much stack space was really used by a cog, but there's little information about how to estimate the need ahead of time. Here's a guide:

    Any call on a method (function or procedure) requires a long for the return address information. This may include the pointer to the previous stack frame or that may take a second long. Chip will have to chime in here on that. A long for the return value is always allocated. If the called method declares local variables, each one will take an additional long. If the called method has any parameters, a long for each will be allocated in the caller's stack frame. Expressions use the stack for evaluation, so they may cause the use of additional levels of the stack.

    Without public documentation on the SPIN interpretive byte code, it's difficult to determine exactly how much stack is needed for any given program. Start with figuring out how deep the deepest call will go and add up the space needed for parameters, local variables, and return address information for that call chain. Add 8-16 levels for expression evaluation and you should have a pretty good lower bound. At least there are no interrupts to non-deterministically require more.
  • James LongJames Long Posts: 1,181
    edited 2006-09-16 02:35
    Mike.....you are becoming my heroyeah.gif



    Since you answered that question so well.....I have another for you to instruct me on.



    Take a look at max_1270.spin and inform me about the following routine.



    pub get_count(control_bit, average_sample, ADC_count_address) | temp, adresult_temp



    I get the control_bit (the information to start conversion) and the average_sample (the number of samples to average)

    The ADC_count_address has me stumped.



    Maybe it been too long since I did any programming with the stamps....wow I'm really rusty.



    James L
  • Mike GreenMike Green Posts: 23,101
    edited 2006-09-16 03:12
    James,
    That's an easy one. The get_count routine is intended to run continuously in its own cog. Such routines cannot return a value directly, so they have to communicate through common memory locations. Rather than have a specific variable built into the source of the MAX1270 object, the author provided for the user to pass the address of a variable instead. Say you have a variable declared "long FOOBAH". You would write "start(???, ???, @FOOBAH)" with the appropriate "XXX." in front and the "???" replaced by whatever you need. The new cog would be started and you would shortly find the ADC averaged value in FOOBAH and it would be continuously updated as new average values were acquired.
    Mike

    Some languages allow you to pass a variable to a subroutine as a variable, "by reference", or "by value". The first is almost like a macro. Where the parameter name appears, the variable in all its complexity of subscripts, pointers, etc. functionally appears. This form isn't used much any more so you can forget it. "by reference" means that the address of a variable is passed. This location can then be referenced or modified by the subroutine. "by value" means that the actual current value of the variable is passed. There's no way to change the source of the value (the variable) in this type. SPIN uses "by value" always. It allows you to pass the address of a variable "by value" which allows you to effectively have "by reference" parameters so you can change things in the caller's variables.

    Post Edited (Mike Green) : 9/16/2006 3:20:46 AM GMT
  • James LongJames Long Posts: 1,181
    edited 2006-09-16 03:18
    Ah.....I see.....so that is not a requirement for the call.....but rather a variable that the "value" is stored in.

    It confused me...I was expecting the @ symbol.



    is the @ symbol required?· By this example it is not.



    James



    BTW you are going to teach me alot. Thanks Mike.
  • Mike GreenMike Green Posts: 23,101
    edited 2006-09-16 03:25
    To get the address of a variable, you need to use the "@". You don't have to have it in the call. You could do something like:
    VAR
      long tempAddress, myData
    
    PRI example
      tempAddress := @myData
      MAX1270.start(%10001000,8,tempAddress)
    
    


    This would start up a cog with get_count with a 0-10V range, internal reference, no power down, averaging 8 readings each cycle. The result would appear periodically in myData and there's no "@" in the call to MAX1270.start
  • James LongJames Long Posts: 1,181
    edited 2006-09-16 12:50
    Mike said...
    To get the address of a variable, you need to use the "@". You don't have to have it in the call. You could do something like:
    VAR
      long tempAddress, myData
    
    PRI example
      tempAddress := @myData
      MAX1270.start(%10001000,8,tempAddress)
    
    


    This would start up a cog with get_count with a 0-10V range, internal reference, no power down, averaging 8 readings each cycle. The result would appear periodically in myData and there's no "@" in the call to MAX1270.start
    Mike...I'm sorry....I'm a little confused this morning.

    So the @ is only for getting the address of the variable. Is it required?

    Better yet....when is the @ required?

    I tried something last night.....just put something together for a max 1202....I have included it here.....for you guys to tell me what I'm doing wrong.

    Hey be easy.....it was late....and I'm somewhat confused at this point.

    James
  • Mike GreenMike Green Posts: 23,101
    edited 2006-09-16 13:02
    The "@" is an operator like any other (like "+" or "-") and it produces the address of the variable whose name is to the right of the "@". At this point, you have a 32 bit number like any other. You can add another number to it. So "@FOOBAH + 1" is the address of the byte following FOOBAH. The BYTE/WORD/LONG pseudo-variables produce the value at some address, so "BYTE[noparse][[/noparse]@FOOBAH]" is the same as "FOOBAH" (assuming you declared FOOBAH as a byte). Similarly "BYTE[noparse][[/noparse]@FOOBAH+x]" is the same as "FOOBAH[noparse][[/noparse]x]" which is also the same as "BYTE[noparse][[/noparse]@FOOBAH][noparse][[/noparse]x]". If FOOBAH were declared as a LONG, then "LONG[noparse][[/noparse]@FOOBAH+4*x]" is the same as "FOOBAH[noparse][[/noparse]x]" which is the same as "LONG[noparse][[/noparse]@FOOBAH][noparse][[/noparse]x]". Notice that the compiler accounts for the fact that LONGs are 4 bytes (except in the first case).
  • James LongJames Long Posts: 1,181
    edited 2006-09-16 13:33
    Mike said...
    The "@" is an operator like any other (like "+" or "-") and it produces the address of the variable whose name is to the right of the "@". At this point, you have a 32 bit number like any other. You can add another number to it. So "@FOOBAH + 1" is the address of the byte following FOOBAH. The BYTE/WORD/LONG pseudo-variables produce the value at some address, so "BYTE[noparse][[/noparse]@FOOBAH]" is the same as "FOOBAH" (assuming you declared FOOBAH as a byte). Similarly "BYTE[noparse][[/noparse]@FOOBAH+x]" is the same as "FOOBAH[noparse][[/noparse]x]" which is also the same as "BYTE[noparse][[/noparse]@FOOBAH][noparse][[/noparse]x]". If FOOBAH were declared as a LONG, then "LONG[noparse][[/noparse]@FOOBAH+4*x]" is the same as "FOOBAH[noparse][[/noparse]x]" which is the same as "LONG[noparse][[/noparse]@FOOBAH][noparse][[/noparse]x]". Notice that the compiler accounts for the fact that LONGs are 4 bytes (except in the first case).
    OK... so the"@" is used to delcare an addressed·variable in mid routine, rather than in the VAR section.

    Is there any instance that (other than maybe Stack) that the "@" MUST be used?

    I hope I got that right.....

    James L
  • Mike GreenMike Green Posts: 23,101
    edited 2006-09-16 22:51
    Please don't think of "@" as a kind of declaration. It really is an operator that takes a variable and produces the address of the variable. It can be used in the DAT section as a compile-time operator to produce the address of a variable, but works differently. There's a discussion of this in the Propeller Manual under the "@@" operator.
Sign In or Register to comment.