As this is a thread for asking stupid questions, I've just started trying to get to grips with cog's and want to get one thing straight in my mind, Am I right in thinking that every object that is mentioned in the main spin program's object section compiles and runs in it's own cog automatically? So the main program uses one cog and the more objects you use the more cogs get used or do you only open new cogs with the cognew command?
As this is a thread for asking stupid questions, I've just started trying to get to grips with cog's and want to get one thing straight in my mind, Am I right in thinking that every object that is mentioned in the main spin program's object section compiles and runs in it's own cog automatically? So the main program uses one cog and the more objects you use the more cogs get used or do you only open new cogs with the cognew command?
Objects are just a convenient way of breaking code into smaller sizes.
The only way a new cog starts is with the cognew statement. There are lots of objects that start a new cog but many that don't. You really need to check to see if there's a cognew statement in the object in order to tell if the object runs in its own cog.
There are two different ways to use another cog. One is to use assembly and the other is to use Spin. A cog launched with assembly copies a section of hub RAM into a cog. Hopefully the section of memory copied to the cog has useful PASM code written in it.
If you want to use an other cog to run Spin code, instead of a memory location, a Spin method is used as the first parameter in cognew. In order to run the Spin method, the Spin interpreter is loaded into the cog. So instead of copying a section of hub RAM to the cog, a section of ROM (the section with the Spin interpreter) gets copied to the cog.
Each cog has it own RAM from which it executes its program.
The Spin interpreter needs a section of hub RAM as a type of scratch pad. It's the job of the programmer to tell the interpreter were in RAM this scratch pad area should be. That's why we include a "@stack" as one of the parameters.
PASM code doesn't use any scratch pad area other than that defined by the programmer (within the PASM code). The second parameter of a PASM newcog call is a memory location (long aligned) that it can use as a reference point so it knows were to read and write data in the hub.
I know I read most of the above in the Prop Manual, but it took over a year of reading the forums to have it really sink in. Fortunately people like Mike Green, kuroneko, Phil, and others are very patient and have repeated the way this works many times. Hopefully one of them will correct anything I said that's wrong.
Edit: Heater's post below reminded be there is another way to start of cog besides cognew. Coginit also starts a cog. It's generally not a good idea to use coginit when cognew would do the job. I've never used coginit in any of my programs.
@skylight, In my current project I'm using four cogs. The main reason is that I have four repeat loops which don't exit. Infinite repeat loops need a separate cog. One of those loops evaluates combined conditions such as "If (A > and (C < D)". By letting it run in a separate cog it runs in parallel to the other processes saving a lot of time.
THERE IS NO RELATIONSHIP BETWEEN OBJECTS AND COGS.
Sorry for the uppercase but this is a question that comes up very often and shows that many people looking at Spin have issues with it. This should be in large bold print somewhere in the beginning of the Propeller manual.
As noted above objects are just a way of splitting up a program into smaller more easily manageable chunks. Chunks that can be easily reused and shared with others. Think OBEX. Objects enable you to hide variables in one part of code from variables in another and so on. A subroutine/function/procedure/method groups lines of code. An object groups related subroutines.
A cog will not be started unless some method in some object in your program starts one with cognew/coginit A single object could start many cogs or none. A single cog can end up using methods from many objects, ie, the method started in a cog calls methods in other objects.
@Duane Thanks for clearing that up for me, It looks like that to do what I want to achieve I will need to open a new cog, I am getting warnings of too many longs used when trying to link a couple of objects.
@lardom that's exactly the hurdle I have hit with a repeat loop in one object needing to scan for input on a touchscreen whilst another object continues doing a task.
@Heater Thanks for clarifying. You can read the manual and still not be aware of things like that, this is where the forum and it's patient subscribers come into it's own with helpful advice no matter how many times it may have been asked in the past.
Thanks guys, i'll keep hammering away to achieve what I am trying to do.
Touchscreens can be memory hogs. I generally use a one Prop as a graphics slave when using a touchscreen. The master Prop sends data telling what the slave Prop should display and where. The slave sends touch coordinates to the master and the master makes all the decisions and sends data for the next screen of buttons to be displayed.
What touchscreen are you using? If it's one of Rayman's earlier resistive touchscreens, I may have some code you could use for your slave Prop.
I would appreciate seeing your touchscreen code as I'm getting a little confused as to what parts of the paint program are relevant to just the touchscreen
Basically I'm trying to merge touchscreen code in the paint program which reads the buttons to the left of the screen in order to advance or previous the wav playing in the wav player code.
I have manged to adapt the wav player code to play multiple tracks and show current artist and track, if I can get the touchscreen to work at the same time I can use the buttons to select tracks and control volume.
I'v e also thought about incorporating some of Oldbit Collectors code from his games program to show a list of tracks available on the SD card and use the touchscreen to select a particular track.
Getting the touchscreen to work alongside other code will open up many options for projects I have in mind, so any help is greatly appreciated.
In PASM, I tend to name uninitialized working registers "r0, r1, etc.". This fails, however, as soon as I merge multiple assembly language sections into one DAT object. The Propeller Tool complains "Symbols are already defined". I am aware of how the DAT section is handled before the individual cogs get started. Nevertheless -- is there an easy workaround short of renaming my working regs?
Example demonstrating the issue (program otherwise not meanuingful):
PUB demo
cognew(@pasm0, 0)
cognew(@pasm1, 0)
DAT
org 0
pasm0 xor r0,r0
xor r1,r1
jmp pasm0
r0 res 1
r1 res 1
fit 496
org 0
pasm1 xor r0,r0
xor r1,r1
jmp pasm1
r0 res 1
r1 res 1
fit 496
In PASM, I tend to name uninitialized working registers "r0, r1, etc.". This fails, however, as soon as I merge multiple assembly language sections into one DAT object. The Propeller Tool complains "Symbols are already defined". I am aware of how the DAT section is handled before the individual cogs get started. Nevertheless -- is there an easy workaround short of renaming my working regs?
Example demonstrating the issue (program otherwise not meanuingful):
PUB demo
cognew(@pasm0, 0)
cognew(@pasm1, 0)
DAT
org 0
pasm0 xor r0,r0
xor r1,r1
jmp pasm0
r0 res 1
r1 res 1
fit 496
org 0
pasm1 xor r0,r0
xor r1,r1
jmp pasm1
r0 res 1
r1 res 1
fit 496
I don't think there's a way around this.
Phil has mentioned this annoyance in a couple of his posts.
Is there any difference in the assembled output when all internal method calls from a class are preceded with "this->"? I like to do this in my code for clarity since Eclipse doesn't do any special syntax highlighting for method calls.
Is there any difference in the assembled output when all internal method calls from a class are preceded with "this->"? I like to do this in my code for clarity since Eclipse doesn't do any special syntax highlighting for method calls.
What's the difference between the HUBTEXT and HUBDATA PropGCC keywords?
I have a feeling this question should be re-phrased as "what's the difference between text and data sections in hub RAM?" but I'm not sure what would even mean.
Questions on the waitxxx instructions. I'll use waitcnt as my example.
// Assuming system counter equals 0 during the first clock cycle
mov temp, cnt // Line 1: Begin execution of this command @ CNT = 0
mov temp, #14 // Line 2: Begin execution of this command @ CNT = 4
waitcnt temp, #0 // Line 3: Begin execution of this command @ CNT = 8
nop // Line 4: Begin execution... when?
What value is loaded into temp in line 1? Is it 0 or 4 or something else?
What is the first clock cycle of line 4? Are all instructions 4-clock-cycle aligned? If not, does it begin at clock cycle 14 or 15?
What if line 2 read "mov temp, #12"? Would that be valid or would we see a 53 second pause?
What if line 2 read "mov temp, #11"? Presumably that would result in a 53 second pause right?
I tried looking through the web propeller manual for these answers and couldn't find them - sorry if I just didn't read close enough.
// Assuming system counter equals 0 during the first clock cycle
mov temp, cnt // Line 1: Begin execution of this command @ CNT = 0
[COLOR="#FF0000"]mov[/COLOR] temp, #14 // Line 2: Begin execution of this command @ CNT = 4
waitcnt temp, #0 // Line 3: Begin execution of this command @ CNT = 8
nop // Line 4: Begin execution... when?
What value is loaded into temp in line 1? Is it 0 or 4 or something else?
What is the first clock cycle of line 4? Are all instructions 4-clock-cycle aligned? If not, does it begin at clock cycle 14 or 15?
What if line 2 read "mov temp, #12"? Would that be valid or would we see a 53 second pause?
What if line 2 read "mov temp, #11"? Presumably that would result in a 53 second pause right?
Are you sure you don't want add temp, #14? Otherwise, depending on where cnt is ATM you will have to wait for rollover, IOW until cnt reaches e.g. #14.
add temp, #14
something else, cnt is never reset and doesn't start at 0 after power-up
ref+19, provided you don't use hubops and/or waitxxx insns are 4n aligned (relative to cog start time that is, cnt can be anything though)
nop starts at ref+17 (no rollover delay)
nop starts at ref+16 (no rollover delay)
mov temp, #14
see above
absolute 14+41, waitpxx has a 3 cycle exit, i.e. the 4th after match is the first for nop
Comments
Objects are just a convenient way of breaking code into smaller sizes.
The only way a new cog starts is with the cognew statement. There are lots of objects that start a new cog but many that don't. You really need to check to see if there's a cognew statement in the object in order to tell if the object runs in its own cog.
There are two different ways to use another cog. One is to use assembly and the other is to use Spin. A cog launched with assembly copies a section of hub RAM into a cog. Hopefully the section of memory copied to the cog has useful PASM code written in it.
If you want to use an other cog to run Spin code, instead of a memory location, a Spin method is used as the first parameter in cognew. In order to run the Spin method, the Spin interpreter is loaded into the cog. So instead of copying a section of hub RAM to the cog, a section of ROM (the section with the Spin interpreter) gets copied to the cog.
Each cog has it own RAM from which it executes its program.
The Spin interpreter needs a section of hub RAM as a type of scratch pad. It's the job of the programmer to tell the interpreter were in RAM this scratch pad area should be. That's why we include a "@stack" as one of the parameters.
PASM code doesn't use any scratch pad area other than that defined by the programmer (within the PASM code). The second parameter of a PASM newcog call is a memory location (long aligned) that it can use as a reference point so it knows were to read and write data in the hub.
I know I read most of the above in the Prop Manual, but it took over a year of reading the forums to have it really sink in. Fortunately people like Mike Green, kuroneko, Phil, and others are very patient and have repeated the way this works many times. Hopefully one of them will correct anything I said that's wrong.
Edit: Heater's post below reminded be there is another way to start of cog besides cognew. Coginit also starts a cog. It's generally not a good idea to use coginit when cognew would do the job. I've never used coginit in any of my programs.
THERE IS NO RELATIONSHIP BETWEEN OBJECTS AND COGS.
Sorry for the uppercase but this is a question that comes up very often and shows that many people looking at Spin have issues with it. This should be in large bold print somewhere in the beginning of the Propeller manual.
As noted above objects are just a way of splitting up a program into smaller more easily manageable chunks. Chunks that can be easily reused and shared with others. Think OBEX. Objects enable you to hide variables in one part of code from variables in another and so on. A subroutine/function/procedure/method groups lines of code. An object groups related subroutines.
A cog will not be started unless some method in some object in your program starts one with cognew/coginit A single object could start many cogs or none. A single cog can end up using methods from many objects, ie, the method started in a cog calls methods in other objects.
@lardom that's exactly the hurdle I have hit with a repeat loop in one object needing to scan for input on a touchscreen whilst another object continues doing a task.
@Heater Thanks for clarifying. You can read the manual and still not be aware of things like that, this is where the forum and it's patient subscribers come into it's own with helpful advice no matter how many times it may have been asked in the past.
Thanks guys, i'll keep hammering away to achieve what I am trying to do.
What touchscreen are you using? If it's one of Rayman's earlier resistive touchscreens, I may have some code you could use for your slave Prop.
http://www.rayslogic.com/Propeller/Products/QMP/QMP.htm
I would appreciate seeing your touchscreen code as I'm getting a little confused as to what parts of the paint program are relevant to just the touchscreen
Basically I'm trying to merge touchscreen code in the paint program which reads the buttons to the left of the screen in order to advance or previous the wav playing in the wav player code.
I have manged to adapt the wav player code to play multiple tracks and show current artist and track, if I can get the touchscreen to work at the same time I can use the buttons to select tracks and control volume.
I'v e also thought about incorporating some of Oldbit Collectors code from his games program to show a list of tracks available on the SD card and use the touchscreen to select a particular track.
Getting the touchscreen to work alongside other code will open up many options for projects I have in mind, so any help is greatly appreciated.
Example demonstrating the issue (program otherwise not meanuingful):
I don't think there's a way around this.
Phil has mentioned this annoyance in a couple of his posts.
Fred
And my version of GCC is: Why is testn not recognized by the compiler?
It's a bug. We'll fix it soon, but in the meantime you can use "andn ...,nr" instead.
Thanks,
Eric
For example, I prefer this vs this
I have a feeling this question should be re-phrased as "what's the difference between text and data sections in hub RAM?" but I'm not sure what would even mean.
Questions on the waitxxx instructions. I'll use waitcnt as my example.
- What value is loaded into temp in line 1? Is it 0 or 4 or something else?
- What is the first clock cycle of line 4? Are all instructions 4-clock-cycle aligned? If not, does it begin at clock cycle 14 or 15?
- What if line 2 read "mov temp, #12"? Would that be valid or would we see a 53 second pause?
- What if line 2 read "mov temp, #11"? Presumably that would result in a 53 second pause right?
I tried looking through the web propeller manual for these answers and couldn't find them - sorry if I just didn't read close enough.add temp, #14
- something else, cnt is never reset and doesn't start at 0 after power-up
- ref+19, provided you don't use hubops and/or waitxxx insns are 4n aligned (relative to cog start time that is, cnt can be anything though)
- nop starts at ref+17 (no rollover delay)
- nop starts at ref+16 (no rollover delay)
mov temp, #14- see above
- absolute 14+41, waitpxx has a 3 cycle exit, i.e. the 4th after match is the first for nop
- absolute 12+41
- absolute 11+41
1 with potential rollover delayMinimal waitcnt advance(s):