Device Drivers

Device drivers, depending on the particular device, design requirements, and kernel or operating system (O/S), consist of a combination of one or more of the following:

  1. Installation software to install the driver "program" on the system, register it with the O/S, and handle any system specific configuration.
  2. An uninstallation program to remove the driver software, undo any registration or other configuration changes that the driver has made to the system.
  3. A software interface which encapsulates the functionality and presents a standardized driver interface to the O/S.  This may actually include multiple separate interfaces, allowing access to the device at a variety of levels of abstraction so that developers using the device can choose the interface which is best suited to their requirements.
  4. Initialization code to verify that the device is installed in the system, handle any device configuration requirements at startup, and to make sure the device starts operation in a "known" state.
  5. Device cleanup code which performs a graceful shutdown of the device and releases all system resources and tasks used by the device when it is no longer required by the system.
  6. Diagnostics to verify that the device is fully functional, and in high reliability systems, to continuously monitor the device whenever it is active (and possibly initiate corrective actions when a problem occurs).
  7. Real-time software, usually in the form of interrupt routines and/or high priority system tasks which manage any "real-time" requirements that the particular device may have.
  8. Non-real-time tasks which handle any remaining processing that the device may require which is not handled by any of the above.

Regardless of the requirements of the O/S being used (or even if no O/S is used), the device driver will need one or more of the above to be written for it, and while all of the above may require some O/S specific code, generally, only the first three are O/S specific, the rest of these items in most cases can be implemented using POSIX and ANSI standard library functions included with most C or C++ compilers (these being the best languages currently available for writing device drivers) as well as a few compiler options which are included with all commercial C/C++ compilers available today.  This does not mean that it will not be necessary to use O/S specific code in the remaining items, only that if and when it is required, it will usually be minimal.  What this means is that when done correctly, most of the software required for writing a device driver of any complexity, is independent of the O/S being used.  Since some systems provide little or no O/S support, it is sometimes necessary to repartition the above items differently, but even in these cases, the functional code should generally remain the same, just used in a different manner.  Probably the most common example of this would be writing for, or porting a driver to a system without any O/S support.  In this type of case it is usually necessary to move some or all of the real-time code into interrupt routines -  usually the device interrupt code, though often system timer routines are useful for handling some of this type of processing as well.  When the driver is properly partitioned, it is simply a matter of where the calls to the driver code are placed in a given O/S environment, requiring little or no modification to the design or implementation of the driver software itself.

While the first three items listed above can be mildly complex for some O/S environments, the implementation is generally fairly straight forward and relatively simple to code and debug.  The real challenge in writing device drivers are the remaining items.  These generally require a good understanding of electronic hardware design and trouble shooting, as well as the design and implementation of operating systems.  These items also require far greater skill to debug, since this type of code almost invariably requires multiple threads of execution which can collide in subtle ways that are difficult to capture and debug.  In addition, for a new device, it is not only the new software for the driver that is being debugged, but the hardware as well, since this is often the first time that hardware design and/or manufacturing problems will show up.  Even for older, "debugged" hardware, a new driver will often find previously undiagnosed problems due to even minor differences in driver behavior.  Because of these issues to name a just a few, it is important that the driver developer be proficient in debugging hardware, and have knowledge which includes:

  • Processor interrupt latencies and other hardware induced delays
  • Ringing
  • Inductive/Capacitive coupling (crosstalk)
  • Circuit Timing Issues (setup/hold times, propagation delays)
  • Ground Bounce
  • Setup and use of oscilloscopes, logic analyzers, emulators, and other test equipment

and their software knowledge should include a good understanding of:

  • Race conditions
  • Semaphores
  • Resource locking
  • Multi-tasking
  • Load balancing and performance tuning
  • Real-time debugging techniques

In an ideal world, you should of course use an device driver developer with experience developing drivers for the desired O/S environment that you are interested in, but if you can't find such a person, it should be fairly clear from the above information, that you are much better off going with an experienced device driver developer for other O/S environments, than you would be going with someone experienced with the O/S but with no driver development experience.  This is because driver development requires a fair amount of specialized knowledge and skills, and the majority of the driver development work is not O/S specific.

DeaTech Research Inc. can provide you with all of the knowledge and experience listed above, and has developed drivers in the past for the following environments:

  • MS-DOS
  • VRTX
  • QNX
  • UNIX
  • A wide variety of embedded systems with custom kernels

previously developed drivers included:

  • Text and graphics video display
  • Graphics printing
  • Tape drive
  • Mechanical antenna tuning
  • Disk drives
  • A number of different serial & parallel I/O ports
  • RF data communication
  • Data acquisition
  • Specialty communication buses