Shop OBEX P1 Docs P2 Docs Learn Events
Beginner's Q - What is the preferred way to pass multiple parameters between co — Parallax Forums

Beginner's Q - What is the preferred way to pass multiple parameters between co

ManAtWorkManAtWork Posts: 2,178
edited 2009-10-12 19:12 in Propeller 1
Hello all,

I just·started learning prop assembly and·have my first test program running, blinking some LEDs, generating waveforms with counters in DUTY mode and so on. Now I'd like to write my first "real" application. I plan to write the main program in spin which does all the initialisation and the user interface and run the time critical tasks in seperate cogs and assembler.

I saw that I can pass an argument to the cognew function which is placed in the par register. Now, what should I do if I want to pass multiple parameters? I haven't found a way to group variables together like STRUCT in C. Relying on the order of variables (eg. passing the address of the first variable and assuming that the next variables have known adresses) is a matter of luck. I read somewhere that the compiler sorts the variables to make more efficient use of memory space.·So AFAIK, only arrays of longs are possible to preserve the order of arguments.

I also experienced that it is not possible to use the (hub) address of a variable in assembler code except the one passed via PAR. It seems that the compiler doesn't like something like this:
VAR
  long hubVar
...
DAT
...
   rdlong local,@hubVar ' meant to be address of variable in hub memory

Why not? The compiler should know the address of the variable at compile time. And that would be an easy way to access global variables from assembler code. Or is there a better method?

If direct acess is not possible,·are there·any safe·assumptions about adresses of variables? Or is there a safe way to (statically, at compile time) allocate/reserve hub memory (as RES does for cog memory)?

Thanks for your help

Comments

  • Erik FriesenErik Friesen Posts: 1,071
    edited 2009-10-12 12:11
    In spin, the order of variables is not luck. Each memory type is ordered as you place them. You cannot do as a struct though, because it will place all the longs in a row, then words, then bytes.

    There are few ways to pass an address to assembly. One is to pass the first address of an array or similar, another is to create a few address constants, and not use PAR at all.

    Direct access is possible.

    rdlong tovariable,fromaddress
  • KyeKye Posts: 2,200
    edited 2009-10-12 12:18
    You can't do this:

    rdlong local,@hubVar ' meant to be address of variable in hub memory

    because the source section in the command is only 9 bits long. Apparently the compilier can't figure out the run time address of the code so you have to initialize the address of everything in spin before running the code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-10-12 13:17
    @MenAtWork:
    You are right, the compiler knows the adress of the VAR at compile-time, as SPIN has no dynamic generation of objects.

    But to be more precise, it knows the adresses from each of the instanciates you created with this object. But which one to use in the PASM code in this case?
    Your expectation is only a special case where you only have instanciated the object once. And only in this special case the problem could be solved by the compiler itself. But SPIN and PASM are supposed to be general purpose. The PASM code should be able to work on each of those objects.

    To pass multiple parameters is easiest when the parameters are in a row and have the same size (preferrably long). Then you only need the adress of the first variable.
    For mixed type variables you add 2 pointers to the long variables which point to the beginning of the word and the byte section.
  • ManAtWorkManAtWork Posts: 2,178
    edited 2009-10-12 16:11
    MagIO2 said...
    But to be more precise, it knows the adresses from each of the instanciates you created with this object
    Ah, thanks, now I got it. idea.gif

    @Kye: Err, I actually meant "rdlong local,#@hubVar", but what you said is still true. In general, the hub memory address is longer than 9 bits, of course.
    Erik said...
    another is to create a few address constants, and not use PAR at all
    Erik, how can I tell which address is free? I know, the end of hub RAM is used for the spin stack, but how much is used?

    BTW. is the propeller big or little endian? E.g. would
    DAT
      mov result,first
    ...
    result long 0
    first  word $DEAD
    second word $BEEF
    

    give result=$DEADBEEF or result=$BEEFDEAD? I know, I could try out but I'm curious if this is documented anywheresmilewinkgrin.gif

    Thanks, again
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-10-12 19:04
    Hello MaW,

    here is a thread which has an example how to transfer data from cog2hub.spin for the other direction hub to cog you use the same mechanism

    best regards

    Stefan
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-10-12 19:12
    The first SPIN-interpreter will use ALL the free memory if required by the program. And even more if you do recursive calls, as there is no boundary check for the stack.
    And as far as I know the stack in SPIN is growing from bottom to top and not from top to bottom as it is in other CPUs. So, for your constant memory locations for variable you should rather use the end of HUB-RAM.
Sign In or Register to comment.