Beginners questions about structure of programs.
godzich
Posts: 74
Hi,
As a prop newbie I decided first to learn PASM, to know the CPU and its possibilities - in and out. Now I do. I have been running just one simple spin file with embedded dat part with the PASM program, where the only spin code is just there to start the PASM in another COG. This actually requires 2 COGS, or does it? Is it possible to start the PASM in the same COG that initialized first as a spin compiler, and then continue with the PASM in the same COG???
In my final application 7 out of 8 COGs will run PASM (due to very tight timing tasks), and only one COG will run SPIN, controlling some data flow.
I want to write my PASM for each COG in a separate file, and also test them separately.
My big question is as follows:
How do I start (from my spin executing COG) these other 7 COGS (running PASM), when the source code are in 7 separate xxx.spin files? I hope you understand why I try to explain...
I should probably ready some other manual than the propeller manual. It leaves too many basic questions unanswered. Could someone recommend some freely down-loadable documents that would clarify such things as this?
Grateful for any feedback,
Cheers
Christian
As a prop newbie I decided first to learn PASM, to know the CPU and its possibilities - in and out. Now I do. I have been running just one simple spin file with embedded dat part with the PASM program, where the only spin code is just there to start the PASM in another COG. This actually requires 2 COGS, or does it? Is it possible to start the PASM in the same COG that initialized first as a spin compiler, and then continue with the PASM in the same COG???
In my final application 7 out of 8 COGs will run PASM (due to very tight timing tasks), and only one COG will run SPIN, controlling some data flow.
I want to write my PASM for each COG in a separate file, and also test them separately.
My big question is as follows:
How do I start (from my spin executing COG) these other 7 COGS (running PASM), when the source code are in 7 separate xxx.spin files? I hope you understand why I try to explain...
I should probably ready some other manual than the propeller manual. It leaves too many basic questions unanswered. Could someone recommend some freely down-loadable documents that would clarify such things as this?
Grateful for any feedback,
Cheers
Christian
Comments
From what you've described, it's possible to start with a top level file which will be the one cog you have running spin code. This file will include the other asm files/objects. You can do this one at a time to test them then include them all when you are finished. One way to think about this is to have 8 files. 7 are asm "files" in that they will be included and called by the one spin "file" (this your top level file). Your top level file will launch each of the included objects (into their own cogs in your case) then continue on to run the spin code it needs to.
OBJ
ASM_1 : "First_file_containng_ASM"
ASM_2 : "Second_file_containing_ASM"
PUB Main
ASM_1.Start(PINS and parameters here)
ASM_2.Start(Pins and parameters here)
You can include these or not by commenting them out in your top level cog. Once they are all working you can uncomment them.
My explanation may not be as clear as it could, so have a look at chapter 3 in the manual.
Yes it is. Just use COGINIT.
COGINIT takes a parameter indicating the ID of which cog to start. If that ID happens to be the ID of the cog currently running the Spin that is making the COGINIT call the the Spin will be replaced by the PASM in the COG. You can get the ID of the currently executing cog with COGID
Like so:
However I suspect this is not what you want to do as you say:
Let's arrange that your 7 other files of PASM include at least just one method "start" that launches the PASM using COGNEW. I guess you know how to do that as you have the first one running already.
So now that "master" cog that ends up running Spin as you main program, "managing data flow" as you say, only has to call the start method of the seven other objects to get the PASM running before it gets on with it's main work.
Thank you pgbpsu -your explanation is exactly what I was looking for, and I got your point. The structure is clear;
ASM_1 : "First_file_containing_ASM"
...
...
PUB Main
ASM_1.Start(PINS and parameters here - optionally)
...
Should then my "First_file_containing_ASM" start directly with the DAT statement and just the following PASM code? Nothing before that? The calling spin master sets the system clock and the pll multiplier, common for all COGS?
And are those "First_file_containing_ASM" actually in the format; "filename_ASM.spin"???
I'm slowly getting it... Thanks to you all that replied - this is great forum, and I feel that I dare ask even more stupid questions!
Cheers,
Christian
No. You need to write the "start" method in Spin. In that "start" method you will have a COGNEW statement to start the PASM part.
Correct.
Heater is also right that the top-level settings, like clock frequency, are inherited by all other objects (even if they have these declarations, I believe they are ignored).
Be sure to look over chapter 3. I refer to it often and still learn (or relearn) things every time.
p
Thanks to both of you. Now this is quite clear for me. Those PASM objects (files) have a normal header with the usual initialisation of the clock, a minimal spin program with a PUB (for example named "start") that starts the cog, when called from the main spin. In this way I can run the separate PASM module also stand alone for test purposes (I have the pin usage embedded inside the PASM, so there's no need to transfer any data when calling these.
Now I just need to make sure that the called spin module loads the PASM into itself, without starting another COG. You mentioned how that is done and that's my next subject for investigation!
I will read chapter 3 and try to understand everything in it. I was just so eager to get thins up and running. With your kind help I got now the big picture
This parallel processing and the philosophy behind the Prop is just something very different from anything else - but in a very nice way. Programming is suddenly fun again...
Christian
Just another stupid question. If one COG running spin writes to memory long[$7000]:=123456, is this memory location the same when reading it it PASM in another COG with rdlong[$7000]?
Can or should data be transferred this way, assuming that this memory location is free?
No you don't.
Here is what happens:
1) Your main Spin program runs. It runs in COG 0.
2) Your main program calls the "start" method of some other object. Something like "someobject.start"
3) That "start" method is still being run by the interpreter in COG 0 that is running your main module. It's just a method call after all.
4) The called "start" method loads and starts the PASM code in that objects file. Using COGNEW.
5) At that moment you have a) COG 0 running the "start" method and COG 1 running the newly loaded PASM program.
6) That "start" method returns back to the main programs Spin code.
7) Now you have the main program running in COG 0 and the desired PASM running in COG 1.
So the point here is not to confuse "objects" with COGS. Just calling a method in another object does not start a new COG to run that method. COGs don't get started unless you use COGNEW or COGINIT.
So there is no need to arrange for the method to replace itself with PASM in the COG that is executing it.
Having said that, on some special occasions you may want the new code run by COGINIT to replace the code that is actually calling the COGINIT. In which case use COGINIT and COGID as I pointed out earlier. But normally this is not done. Could be useful if you actually wanted your main code to be in PASM as well.
Yes.
You can of course make the decision that your main module communicates with a running PASM object through a fixed address, say $7000. It may even need a range of addresses for commands, data, buffers etc.
Then another object will need to communicate through some other address, say $7010. And so on.
In this case it is up to you to make sure both the "main" and "slave" objects are using the same addresses and that no other code is trampling over that space.
An improvement to this is for the main object to declare some variables to use as the memory to share with the slave and then pass the address of those variables to the slave via a parameter to "start" which is used as the PAR parameter to COGNEW. The "slave" PASM can then find the shared memory to use no matter where it happens to be and you don't have to worry about it.
This is the so called "mailbox" approach to communication between COGs. A good and simple example of mailbox can be found in Bill Henning's VMCOG object.
Having said all that in some case perhaps you do