Shop OBEX P1 Docs P2 Docs Learn Events
Full Dup Serial question — Parallax Forums

Full Dup Serial question

T ChapT Chap Posts: 4,198
edited 2006-11-04 17:37 in Propeller 1
If multiple methods/cog are using the ser.tx or ser.str, does the object manage what is received and send out in the order received?

The case would be two cogs want to ser.tx at the same time. I am trying to find a way to have several strings assembled together and send out, while maintaining each ones individual 0 termination so the receiver can split the parts. To have the receiver be able to identify what is coming in and write it to it's respective array or variable, this is the thought process although not execute yet until I see how the object will manage multiple sources of .tx or .str"

say Xcheck is a string(or already converted into an integer) that was just rec'd in the buffer among 3 other integers(Y,Z,R). I want to send those back where they cam from for error checking prior to any action. However, there may be a case where some activity is taking place where a cog(s) may be sending values independently of the error checking Tx getting sent. If in fact the Full Dup object can manage multiple sources of instructions, and tere will be cases where things are competing to get sent, I don't see a tidy way to simply send the error checking string out as it was received without first giving each part a unique identifier first, so that the receiver must first identify something in the batch of stuff, split it's part out and assign it back to some arrays as needed.... compare, and then resend a confimation. In other words this is a brain twister.

Here is a feeble attempt:

1. receive a string with 4 integers included
2. split the numbers out to X, Y, Z, R
3. Assemble a new string by some method:

TAB = $09
CR = $0D
ser.str("Xcheck" + TAB + X + TAB + "Ycheck" + TAB + Y + TAB + "Zcheck" + TAB + Z + TAB + "Rcheck" + TAB + R + CR)

4. The receiver looks for Xcheck, if true stores that whole string in an array ErrorCheck()

5. Split and compare the parts

On the right path or what?

Thanks

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2006-11-04 05:34
    The FullDuplexSerial object can only handle one COG putting stuff into a buffer or removing stuff from a buffer at a time. To share it among several other COGs, you'd have to use a semaphore (LOCKxxx) so that only one COG can access the buffer at a time. There really isn't a built-in way to assemble a string the way you're thinking, so just lock the transmit buffer access, then do a series of ser.str/ser.out/ser.dec, etc., then release the lock. If you need a bigger buffer, you can modify the FullDuplexSerial routines. They use a bit mask to wraparound the buffer pointer, so you'd need to go from 16 to 32 to 64, etc. You can do something similar on the receive end that can distribute different messages to different COGs. That's a whole 'nother reply.

    Mike
  • T ChapT Chap Posts: 4,198
    edited 2006-11-04 07:04
    There are 4 cogs running motors(send step outputs to = the X value), when they are done they send a ser.tx back to the app to say it is done, and how far it moved. The 4 cogs were talking all over each other, so I built a homemade Lock

    This may not be kosher but here is my workaround I was about to test.

    'codehere  just finished sending out X steps
    if S == 1
       repeat while s == 1   'wait till it goes low by whoever has it high
       s:= 1                       'make it high again
       ser.tx("x")
       ser.tx(" ")
       ser.tx(x)
       ser.str("LED1")   'app scans for LED1 and turns on a fake LEd for feedback saying done
       s:=0                'let somebody else have it now
       
    
    

    Post Edited (originator99) : 11/4/2006 7:45:59 AM GMT
  • Cliff L. BiffleCliff L. Biffle Posts: 206
    edited 2006-11-04 07:15
    So, that'll be iffy because you've constructed what's called a read-modify write operation.

    Between the time you check S the last time in "while S == 1" and the time you set it to 1, someone else may have already set it. In this case, both cogs would think they had set it to 1, and had taken unique ownership of it.

    This will cause weird, difficult-to-track errors. (You think it's weird here, try it with a million processes.)

    As Mike pointed out, use the lock operations in SPIN. You can use them exactly the same way you're using S -- there's an example in the manual that shows how. It's not complex, and it's the easiest way to do this sort of "in use" flag on the Propeller.
  • T ChapT Chap Posts: 4,198
    edited 2006-11-04 07:35
    I will dig into the lock feature, but I had some unfounded thinking that even though there were all 4 separate cogs, that they still had to to get their turn at the variables to read or write. I'll take your advice though and adapt the lock implementaion.

    So far it has solved the problem and my test feedback window that displays all incoming data to the app is now showing everything in order, not mangled parts thrown together like in a blender as before.
  • T ChapT Chap Posts: 4,198
    edited 2006-11-04 08:24
    that lock trick was pretty simple, thanks for the tip

    repeat until not lockset(SemID)

    'read or write some shared junk

    lockclr(SemID)
  • T ChapT Chap Posts: 4,198
    edited 2006-11-04 10:20
    BTW Mike this does the job nicely to assemble the string from various parts:

    ser.dec(x)
    ser.tx(tab)
    ser.dec(y)
    ser.tx(tab)
    ser.dec(z)
    ser.tx(tab)
    ser.dec(r)
    ser.tx(cr)
    ser.tx(0)
    
    



    can be split as folows:
    Xsplit = Split(RxData,  CHR(9))
    xsplit0.text = xsplit(0)
    xsplit1.text = xsplit(1)
    xsplit2.text = xsplit(2)
    xsplit3.text = xsplit(3)
    
    
  • Cliff L. BiffleCliff L. Biffle Posts: 206
    edited 2006-11-04 17:37
    originator99 said...
    I will dig into the lock feature, but I had some unfounded thinking that even though there were all 4 separate cogs, that they still had to to get their turn at the variables to read or write.

    Not completely unfounded, actually -- taken literally, that statement is correct.

    They have to get their turn at the variables to read or write -- but not both! A cog can read the variable and decide "Oh, great, it's clear! I will set it." Then it must wait its turn to set it -- and in the meantime, another Cog may have reached the same conclusion. *sad music plays*
    originator99 said...
    that lock trick was pretty simple, thanks for the tip

    repeat until not lockset(SemID)

    'read or write some shared junk

    lockclr(SemID)

    You nailed it. Good work! smile.gif
Sign In or Register to comment.