Beginner's Q - What is the preferred way to pass multiple parameters between co
ManAtWork
Posts: 2,178
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:
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
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
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
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,
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.
@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, 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
give result=$DEADBEEF or result=$BEEFDEAD? I know, I could try out but I'm curious if this is documented anywhere
Thanks, again
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
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.