COGNEW is not returning
Lawson
Posts: 870
Ok, I'm building servo controller intended to replace solenoids and limit switches. It uses a modified version of the ServoTracker circuit and code as found here http://forums.parallax.com/showthread.php?p=582447
I've got the core aspects of my code working. Now I'm trying to speed it up by taking advantage of the Propeller's eight cores. My current system has an extra serial port for application communications, in addition to the default programming port. It's built on a Proto board. It's currently setup to share the serial port and servos amongst several "controllers" that each grab serial packets, move the commanded servo, and spit back status code packets.
The problem I'm having is that when I try to start multiple instances of my "controller" code, the COGNEW that started the first "controller" never returns! I didn't detect this earlier because otherwise the code works perfectly, and I hadn't been ready for parallel "controllers" yet.
P.S. this particular protoboard did get washed in tap water. (yea, not too smart) It didn't work for a day, but worked just fine once it fully dried out. Also, the full Blinker tutorial code ran fine on it after the dunking.
P.P.S. the .zip archive attached is a simpler version of my code that reproduces the same error.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Lunch cures all problems! have you had lunch?
Post Edited (Lawson) : 7/20/2007 8:33:49 PM GMT
I've got the core aspects of my code working. Now I'm trying to speed it up by taking advantage of the Propeller's eight cores. My current system has an extra serial port for application communications, in addition to the default programming port. It's built on a Proto board. It's currently setup to share the serial port and servos amongst several "controllers" that each grab serial packets, move the commanded servo, and spit back status code packets.
The problem I'm having is that when I try to start multiple instances of my "controller" code, the COGNEW that started the first "controller" never returns! I didn't detect this earlier because otherwise the code works perfectly, and I hadn't been ready for parallel "controllers" yet.
P.S. this particular protoboard did get washed in tap water. (yea, not too smart) It didn't work for a day, but worked just fine once it fully dried out. Also, the full Blinker tutorial code ran fine on it after the dunking.
P.P.S. the .zip archive attached is a simpler version of my code that reproduces the same error.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Lunch cures all problems! have you had lunch?
Post Edited (Lawson) : 7/20/2007 8:33:49 PM GMT
Comments
You either need to redo Servo_Diagnostics to share an instance of FullDuplexSerial or you need to call Servo[noparse][[/noparse] 1 ].Init.
Also, the "servo_diagnostics_starter.spin" uses a modified FullDuplexSerial.spin that has had all it's variables moved into the beginning of the DAT block. Hence, I only need to initialise it once. (i've also added lock statements to expose a shared lock to prevent contention)
I've attached my modified serial driver "DatDuplexSerial.spin". Once I clean it up a bit I plan to submit it to the object exchange.
by the way, is there a "better" way to share a serial driver? One way I've just thought of is to move the "controller" code and serial driver down to the startup object and manually start several versions of just the "controller" code in separate cogs. (still need to use locks for serial port access though)
Marty
also, funny things happen if COGNEW is used to start a method in the current object twice in two different cogs.
this *should* work, but the two cogs appear to be stepping on each other's toes. COGNEW does return as expected in this case though.
None, of this solves my core problem though. I'd like to have a single cog running a serial port driver, which is then shared among three or more command processing cogs. The execution of commands from the serial port can take several seconds so it is desirable to have several commands executing at once.
Thank you for your time, this one is really stumping me,
Marty
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Lunch cures all problems! have you had lunch?
The first parameter to a COGNEW (or COGINIT), must be a method in the same object as the COGNEW. You can't pass a call to a method in another object. The best way to handle this is to move the COGNEW to the object itself along with the stack (which is replicated for each instance as well). You'd have:
and:
Mike, why is that so and where is it documented? This is against all my previous understanding of how things work. I see hardly any reason for it, and - also- it is syntactically accepted.
Where is it documented? ... I don't know ... some forum message somewhere.
It is a compiler bug that it's accepted, but not implemented properly. Theoretically, the compiler could produce a short stub that consists of a parameterless unnamed local private method that just does the cross-object call and then do the COGNEW/COGINIT on that, but the compiler doesn't do that and that's a complicated fix that won't likely be done any time soon.
I did add a comment about this to the Propeller Tricks & Traps sticky thread.
Post Edited (Mike Green) : 7/21/2007 2:56:26 PM GMT
Currently i'm using a single instance of FullDuplexSerial with the controller code in the parent object. I'm then loading this controller code into multiple cogs using COGNEW. This works great with two controller cogs, but gets corrupted when I try for three cogs. I'll track down this bug today. If this doesn't work I'll switch back to using SerialMirror, or DatDuplexSerial.
Edit: my second bug cleared up when I boosted my stack space. I'd previously been allocating 30 longs for stack. Now with 100 longs for stack it works fine. I'll have to try the stack size measuring code to see just how big the stack gets with this code.
Marty
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Lunch cures all problems! have you had lunch?
Post Edited (Lawson) : 7/23/2007 5:32:04 PM GMT