Re: Synchronous Serial Port Protocol messaging With NSOperationQueue/GCD
Re: Synchronous Serial Port Protocol messaging With NSOperationQueue/GCD
- Subject: Re: Synchronous Serial Port Protocol messaging With NSOperationQueue/GCD
- From: Vanni Parronchi <email@hidden>
- Date: Wed, 07 Aug 2013 20:03:19 +0200
Hi all,
Thank you all for you contribution and responses. It was my first message
to the list and was a bit intimidated :).
the app is meant to be modular, 10.7 based and it has to manage not only
serial devices (rs485) but also USB ones (through a virtual com port using
an FTDI chip on the device and an external C library some contractor made
quite some time ago for the company i'm working for, that abstracts
communication with the FTDI underlying driver). I'm focusing on the serial
ones for now.
given the modular nature the app uses loadable bundles as plugins so that
every plugin can be updated independently (i'm thinking about using the
famous sparkle <http://sparkle.andymatuschak.org/> by Andy
Matuschak, anyone?).
I've managed to implement a kind of IOC/service
locator<http://www.martinfowler.com/articles/injection.html#UsingAServiceLocator>in
a framework that every bundle can have access to, in order to request
instances belonging to different bundles through protocols. And for
messaging to/from bundles i made use of NSNotificationCenter a lot,
probably abusing it, hoping that this won't bring issues in the future.
Those serial devices can be "daisy chained" together, every device has a
unique integer ID that can be set on the device
Every command sent to the device is an instance of a "high level" message
class that encapsulates all the information a message has to have
(target device id, command and data)
The connection layer plugins (rs485, usb) are abstracted through proper
class (loadable bundle) and every class *has* a message manager that
receives "high level" messages and converts to/from "low level" messages in
form of pure NSData objects. Through a category on NSData i can factorize a
high level message in the proper set of bytes, then send the NSData to
serial port and wait for the response (if no response every message has a
timeout)
I can't talk to different devices at the same time because collisions on
the bus can happen thus corrupting the messages. It has to be strictly half
duplex
I use ORSSerialPort as the serial port library. I found its API to be more
comfortable than the AMSerialPort i tried when i started.
NSOperation and NSOperationQueues enables you to better encapsulate the
logic of sending a message, but at the end all the messages are not so
different in term if implementation at a lower level and the balance
between encapsulating but passing lots of arguments and handling everything
in a dispatch call preserving scope and context led me to go with pure GCD.
I use dispatch_groups to handle high level commands that are in fact the
product of several low level messages to the device, dispatch_async and
dispatch_semaphore to wait for the response, and i also fire a
dispatch_source with a timer to handle timeouts, i.e. discovering devices
from the software implies firing messages to integer IDs in a for loop. So
far, seems that the synchronization is achieved but i'll see when i'll go
further.
It's my first app for Mac OS X, i did entirely iOS before, and i've run
through so much trials and errors that i almost burned out. Hope i'll get
it to be shipped.
For those who managed to read all this, does it seem a reasonable approach
to the problem?
Thank you and Best Regards!
Vanni
2013/8/7 Ken Thomases <email@hidden>
> On Aug 7, 2013, at 2:20 AM, Tom Davie wrote:
>
> > My suggestion would instead be to make an NSOperation subclass for
> sending a message to the device.
> >
> > That subclass should require you to specify to which device you are
> talking. Each device object should carry around a dispatch_semaphore.
> When a message is sent, the semaphore should be checked and set to stop
> any other operations proceeding until the semaphore is unset. When the
> device responds, the semaphore should be unset.
> >
> > You can then make your operation queue a concurrent queue, rather than a
> serial one, so that you can send messages to more than one device at the
> same time, while still maintaining your one-thing-at-a-time per device rule.
>
> Why would you do that? Operation queues are cheap. Have one serial queue
> per device. There's little reason to add another synchronization method on
> top of operations to cause them to serialize with respect to one another.
>
> Regards,
> Ken
>
>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden