Synchronous Serial Port Protocol messaging With NSOperationQueue/GCD

2013-08-07 Thread Vanni Parronchi
hi everyone,

I'm writing a mac osx app that needs to talk to a serial device.

There's a well known protocol to adhere to (implemented in the device
firmware) and is a kind of a half-duplex synchronous protocol where if i
send a message to the device from my app i have to wait till i get a
response from the device, inspect it and then i'm allowed to send another
message. This has to go for several messages i need to send to the device.

Given this synchronous nature, i'm trying to keep the UI free so i'm doing
all the messaging stuff on background threads. My choice is to use
NSOperation and NSOperationQueue, where the queue is configured with
maxConcurrentOperations set to 1 in order to have a strict serial behavior
(this is due to the constraints given by the implemented protocol). How can
i make an NSOperation subclass waiting for a signal given by the serial
port delegate to make it fire isFinished KVO to the queue and make that
queue consequently execute the next NSOperation?

Does this approach make sense to you?

I'm open to any suggestions of course.

Thank you!

Vanni
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Synchronous Serial Port Protocol messaging With NSOperationQueue/GCD

2013-08-07 Thread Tom Davie

On 1 Aug 2013, at 12:03, Vanni Parronchi vanniparron...@gmail.com wrote:

 hi everyone,
 
 I'm writing a mac osx app that needs to talk to a serial device.
 
 There's a well known protocol to adhere to (implemented in the device
 firmware) and is a kind of a half-duplex synchronous protocol where if i
 send a message to the device from my app i have to wait till i get a
 response from the device, inspect it and then i'm allowed to send another
 message. This has to go for several messages i need to send to the device.
 
 Given this synchronous nature, i'm trying to keep the UI free so i'm doing
 all the messaging stuff on background threads. My choice is to use
 NSOperation and NSOperationQueue, where the queue is configured with
 maxConcurrentOperations set to 1 in order to have a strict serial behavior
 (this is due to the constraints given by the implemented protocol). How can
 i make an NSOperation subclass waiting for a signal given by the serial
 port delegate to make it fire isFinished KVO to the queue and make that
 queue consequently execute the next NSOperation?
 
 Does this approach make sense to you?

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.

Tom Davie

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Synchronous Serial Port Protocol messaging With NSOperationQueue/GCD

2013-08-07 Thread Sean McBride
On Thu, 1 Aug 2013 12:03:01 +0200, Vanni Parronchi said:

hi everyone,

I'm writing a mac osx app that needs to talk to a serial device.

Have you considered using the open source AMSerialPort class?  It doesn't use 
GCD, but does have an NSThread option.  It could probably be retrofitted to use 
GCD also... which I have been thinking I might one day have time to do...

Cheers,

-- 

Sean McBride, B. Eng s...@rogue-research.com
Rogue Researchwww.rogue-research.com 
Mac Software Developer  Montréal, Québec, Canada



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Synchronous Serial Port Protocol messaging With NSOperationQueue/GCD

2013-08-07 Thread Ken Thomases
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 (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Synchronous Serial Port Protocol messaging With NSOperationQueue/GCD

2013-08-07 Thread Vanni Parronchi
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/%E2%80%8E by Andy
Matuschak, anyone?).

I've managed to implement a kind of IOC/service
locatorhttp://www.martinfowler.com/articles/injection.html#UsingAServiceLocatorin
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 k...@codeweavers.com

 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 (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com