Error with FullDuplexSerial.Spin object
SamMishal
Posts: 468
HELP
I think I have found a problem with the FullDuplexSerial.Spin library object.
Look at this code:
If you run this code you will get 123 on the PST......HOWEVER.....if you uncomment the line Debug[noparse][[/noparse]1].Start(....)
the program stops working and may even spew out garbage some times.
The program is just to demo the problem. The real problem arises if multiple objects need to have access to
FullDuplexSerial and declare their own instances then the same problem occurs.....the multiple instances seem
to interfere with each other.......I am thinking that the various cogs are driving the TX and RX pins continously
and therefore are stopping the other cogs from doing their own transmissions.......I am not very up to par with
PASM and maybe someone with more knowledge than mine can help...e.g. Chip Gracey, Jeff Martin..... PLEASE.
But even if we manage to solve the problem......the sample programs below illustrate another problem.
The program does not work as given due to the problem mentioned above. BUT....Also please read on for ANOTHER problem....
The other problem is in the scenario of the top_object program, there would be two cogs (even if they did not interfer with each other) running
the serial I/O. This is wasteful.
So how would one provide Serial I/O to multiple objects without having multiple cogs (which actually does not work any way
as shown above)????????????
I hope someone whith DEEP knowledge of all this stuff can help
Samuel
Post Edited (SamMishal) : 7/9/2009 8:12:39 PM GMT
I think I have found a problem with the FullDuplexSerial.Spin library object.
Look at this code:
Con _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ Debug[noparse][[/noparse]2] : "FullDuplexSerial" PUB Main | x Debug[noparse][[/noparse]0].Start(31,30,0,115200) ' Start the Debug Terminal Cog 'Debug[noparse][[/noparse]1].Start(31,30,0,115200) ' Start the second Debug Terminal Cog waitcnt(clkfreq*3+cnt) repeat x from 1 to 3 Debug[noparse][[/noparse]0].Dec(x) waitcnt(clkfreq+cnt) repeat x from 4 to 8 Debug[noparse][[/noparse]1].Dec(x)
If you run this code you will get 123 on the PST......HOWEVER.....if you uncomment the line Debug[noparse][[/noparse]1].Start(....)
the program stops working and may even spew out garbage some times.
The program is just to demo the problem. The real problem arises if multiple objects need to have access to
FullDuplexSerial and declare their own instances then the same problem occurs.....the multiple instances seem
to interfere with each other.......I am thinking that the various cogs are driving the TX and RX pins continously
and therefore are stopping the other cogs from doing their own transmissions.......I am not very up to par with
PASM and maybe someone with more knowledge than mine can help...e.g. Chip Gracey, Jeff Martin..... PLEASE.
But even if we manage to solve the problem......the sample programs below illustrate another problem.
The program does not work as given due to the problem mentioned above. BUT....Also please read on for ANOTHER problem....
{ Top_Object.Spin } Con _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ Debug : "FullDuplexSerial" ObjB : "B_Object" PUB Main|NumSongs,i,x Debug.Start(31,30,0,115200) ' Start the Debug Terminal Cog ' if you comment this out then the ' ObjB.Print works ObjB.Init ' Start Object B waitcnt(clkfreq*2+cnt) Debug.Tx(Debug#Cls) ' Clear SerialTerminal screen Debug.Dec(12) Debug.Tx(13) ObjB.Print(34)
{ B_Object.Spin } OBJ Debug : "FullDuplexSerial" PUB Init Debug.Start(31,30,0,115200) ' Start the Debug Terminal Cog ' if you comment this line out then the ' Top object Debug works Pub Print(val) Debug.Dec(val) Debug.Tx(13)
The other problem is in the scenario of the top_object program, there would be two cogs (even if they did not interfer with each other) running
the serial I/O. This is wasteful.
So how would one provide Serial I/O to multiple objects without having multiple cogs (which actually does not work any way
as shown above)????????????
I hope someone whith DEEP knowledge of all this stuff can help
Samuel
Post Edited (SamMishal) : 7/9/2009 8:12:39 PM GMT
Comments
from distinct cogs, you also need to add locking.
This is a well-known and well-understood problem.
You will have to add your own locks to "Serial Mirror" if you plan to call it from several different cogs. It's not hard to do.
There's not very much call for the sort of serial driver you're asking for. Most of the time FullDuplexSerial or Simple_Serial will do the trick. That's why no one has bothered to contribute one (other than Mirror and that one doesn't have locking).
Post Edited (Mike Green) : 7/9/2009 8:19:36 PM GMT
locking and that also gets around the waste of having multiple cogs running it but still enabling multiple objects to have
access to serial I/O...??
I would like to see Chip Gracey's and·Jeff Martin's input on this.....PLEASE....
Sam
·
do you have a link for the SerialMirro object....I am trying to find it.....
Regards
Samuel
·
There is an object on obex.parallax.com that takes a step toward this functionality by using a DAT block for variables instead of a VAR block. It's called SerialMirror:
http://obex.parallax.com/objects/189/
Also on obex, you can find MultiCogSerialDebug, which extends the DAT block approach and applies locks.
http://obex.parallax.com/objects/232/
This example puts the onus on the parent object for using locks. An alternate approach might be to build the locks into the object's methods. I started experimenting with methods that shunt strings into holding pens so that the parent object doesn't have to worry about getting locked out of its own task list, but I haven't worked the kinks out yet.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
It should be possible to modify this object so that it matches with your needs. I don't know the object in detail, but I have the following ideas:
1. If the TX/RX buffer is in the var section, then shift it to the DAT section
2. Have a variable in the DAT section, which shows whether the PASM has already been started
3. Modify the start function to use the right buffers and only start a new COG if not yet started
4. RX and TX functions should be synchronized with locks if you plan to use the object in parallel from different COGs
Then you can use the object in every other object and it does not waste HUB-RAM, because the same object is never copied in HUB-RAM. Only the VAR section is duplicated per instance of the object.
Hope that helps.
PS: Ups ... needed far to long for my reply ;o)
I found the SerialMirror.Spin and IT WORKS.....GREAT.....it is exactly what I needed....
THANKS again
Samuel
Post Edited (SamMishal) : 7/9/2009 8:36:28 PM GMT
I looked more closely at the SerialMirror object and it works great as far as allowing multiple
instances from multiple objects to all work together on the same Tx and Rx pins.....BUT.....I think it still
uses multiple cogs if instantiated multiple times.....am I wrong.....if not then is there one that
does not utilize multiple cogs???
Sam
WHY is this step necessary....it is also what MirrorSpin does but I do not understand why it is
a necessary thing to do???
Samuel
·
So, the read/write functions would simply use the wrong buffers except the ones of the first object.
Each object gets its won seperate variables. So, the two versions of the fullDuplex serial have completely different buffers.
Its a problem with spin in general, you have to use the serial mirror hack to get arround it with sperate DAT sections.
Maybe support for parent and child objects sharing the sample driver will be added one day. Maybe not.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Multiple objects can declare SerialMirror, but their method calls to SerialMirror's other methods (DEC,·STR, etc)·will result in data to/from the same tx and rx buffers because there is only one copy of the code and DAT·block for multiple copies of the object.·
After the one start method call, calls to DEC, STR, etc will work from any object/cog so long as they are not executed close enough together that a data collision occurs. This is why I started experimenting with the lock and multiple buffer scheme.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
Post Edited (Andy Lindsay (Parallax)) : 7/9/2009 9:48:56 PM GMT
This will definitely use only one cog.....and since the DAT section is in hub RAM then the same buffer will be used....
·
Ahaaa.....now I get it.....I will try this soon......
·
The lock issue would be needed if multiple objects are likely to send/receive simultaneously.....but in my application
I am not doing that .....so I will look into the locking stuff later.....Unless Andy Lindsay comes out with a new version
that does all that for us.....Please.....
·
But I have learnt a lot from you guys.........THANKS
·
·
Samuel
only locking is required when I may need it ......but not now......SO THANK YOU GUYS....
Solution as well as understanding and learning new stuff......what a GREAT LOT you guys are
and of course Parallax and the Propeller (and SPIN)·are just the best.....
Samuel
·
·
Side notes:
·
The SerialMirror object's start method is actually designed to stop any previously started instances before launching a cog, so you "could" call the start method more than once, and there would still only be one instance running.· This only prevents the same instance of a given object from launching two cogs; you could still launch more than one cog by calling a start in a different instance of the SerialMirror object.· That is why we only want to make one call to a SerialMirror object's Start method.· Then, all the other instances of the object will only communicate through one cog that's running the serial ASM code.
I have a Parallax Serial Terminal debugging application that works with SerialMirror posted in the Propeller Education Kit Labs, Tools & Apps thread, and the next step is to add locks to prevent data collisions.
The existing FullDuplexSerial object can be used with multiple programming tools connected to various pairs of I/O pins so that you could have several simultaneous conversations with one or more PCs or other serial devices.
The Propeller Library also has SimpleSerial, which might be another option for multi-cog debugging. This object uses whatever cog calls its methods to transmit the bytes at up to 19.2 kbps.
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Andy Lindsay
Education Department
Parallax, Inc.
Post Edited (Andy Lindsay (Parallax)) : 7/9/2009 11:25:52 PM GMT
So you would have two objects that use the object FullDuplexSerial and initialize it to the pins.
So if EB500 is on pins P20 and P21 and the LCD is on P10 and P11 (for Tx and Rx) then you would have
two objects say one is called EB500.Spin and the other called LCD.Spin each of these objects would have its
own OBJ section like this
·· Obj
······· Com : "FullDuplexSerial"
And also it would have methods that will enable the Toplevel object to initialize them say
·· Pub Init(TxPin, RxPin,BaudRate)
······· Com.Start(RxPin, TxPin,0,BaudRate)
······· 'do other initialization stuff
· Pub DoSomething(someParam)
····· Com.Tx(somecalue)
····· 'etc.
So then the top level object would instantiate the LCD.Spin and EB500.Spin objects in its Obj section
and then would call the Init method and then can use the other methods of the object
Con
···· _CLKMODE = XTAL1+PLL16X
···· _XINFREQ· = 5_000_000
Obj
··· LCD··· : "LCD"
··· Eb500: "Eb500"
Pub Main
···· LCD.Init(10,11,9600)
···· EB500.Init(20,21,9600)
···· 'do some more stuff
···· LCD.DoSomething(somevalue)
···· EB500.DoSomething(someothervalue)
etc. etc.
·······
Post Edited (SamMishal) : 7/14/2009 8:38:07 PM GMT
As Tom said, this usage is widely known and common. I've never had a good reason want to use SerialMirror (ya, I've seen it).
A similar approach can be used with TV, etc... but it's a little harder to describe the "fix."
For those who don't know, all you have to do is make the change below in FullDuplexSerial.spin to be able to use it from any object (but not with multiple instances on different pins as Andy pointed out). Of course every time you update PropTool, you have to readjust :< vomit.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230
Sam
·
I found pcfullDuplexserial4fc.Spin ....... is it the same?
Regards
Sam
·
I used it and it is VERY Good.............it is definitely another tool I can
and WILL use.....thanks for making it...............
Regards
Samuel