Synchronous Serial Port Protocol messaging With NSOperationQueue/GCD
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
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
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
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
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