How to think about Architecture for writing a device interfacing software

by Nitin Kumar on February 16, 2010

Computer port (hardware)
Image via Wikipedia

This is a brief on how to think about architecture of a software which needs to talk to devices to implement its use cases. Devices can vary from printers, routers, proprietary communication devices, etc.

The ASIC and firmware team has come up with a command specification document which describes the low level commands which their device can understand. Now how do we move from here and make a robust, asynchronous, device driver, controller or application which uses this device to deliver functionality.

First, Start with the use cases of the device. I know that in case you are working on a device driver which is going to provide services to “other components”, then it might be tricky to think in terms of use cases. You may visualize in terms of all things you can do with the device, including things like on, off, reset, change cartridge, print photo, service, troubleshoot etc. Lets take an example of a printer. Now the use cases could look like, initiate printer, send print job, read settings, etc.

Next, Decide to have a subsystem which will provide only the commands which the device hardware is providing, “as it is” and will just take care of reliable communication with the device. Lets say the device can be connected through USB or RS-232 or Ethernet port. Now for each type of communication channel, create a separate subsystem which will communicate with the specific communication medium. So, in the end your subsystems will look like. Command subsystem, and then USB delivery, RS232 delivery and Ethernet Delivery.

Now choose the delivery subsystems to be implemented using operating system specific libraries as this will ensure more control and speed. If you want to write a driver which will run on all operating systems, you can chose Java based libraries which would have different versions for different operating systems. You need to write code using the performance optimized functions and libraries so be sure to check this out and write a cook book for all developers on which functions are “architecturally approved” to be used among the packages and external components you are using. At the delivery level, you need to focus on time out, number of times you want to retry etc.

Moving onto the next subsystem “command” here you can implement command pattern to make all hardware commands of the printer encapsulated. You do not need to implement any applications specific functionality in any of the command, this will allow you to add new commands easily and keep “changing” with the hardware specifications.

Then comes the applications or functionalities you want to build on top of these commands, these would be directly related to the actual use cases of the printer. e.g. print a document, print a photo etc. Here you can choose to break your subsystem depending on the level of processing you would need to do for each specific type of print request. It will be a good idea to provide a generic print subsystem which will provide printing of a multipage file.
Take example of print a photo, the printer may be providing you a command to print a photo, you would like to resize the image, set ink levels, etc. so all this would be done in your print photo subsystem.

And so on keep moving away from the hardware with each subsystem.

So, what are the best practices you follow while designing architecture for device interfacing software. Share in the comments.

If you enjoyed this post, please consider subscribing to the feed to receive future articles delivered to your feed reader.

Reblog this post [with Zemanta]

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Previous post: Can you charge for the software you are bundling with your hardware device?

Next post: How Use Cases can align the development teams and help reduce rework in product development