© Copyright 2003
RealTimePartner
All rights reserved
Last update 2016-01
Device Driver Design
What is a Device?
A device is a piece of hardware that you can program via registers inside the device so the device can perform the specific functionality that you need in your system. Today many devices may be part of the CPU like a serial interface, a network interface etc. But many devices may also be individual chips on your board like a DUART, network device, disc etc.
What is a Device Driver?
A device driver contains all the software routines that are needed to be able to use the device. Typically a device driver contains a number of main routines like a initialization routine, that is used to setup the device, a reading routine that is used to be able to read data from the device, and a write routine to be able to write data to the device. The device driver may be either interrupt driven or just used as a polling routine.
Basic Device Driver Interface
Many RTOSs have a standard interface to the device driver like create ( ), open ( ), read ( ), write ( ), ioctl ( ). Other RTOSs may have their own propriety interface with the same type of functions but with different names and a faster access time to the device. As many RTOSs offer an interface to be able to call the device drivers, the device drivers and the application do not have to be linked together. This makes it easier to be able to create hardware independent applications.
Design of Device Driver
When you design your system it is very good if you can split up the software into two parts, one that is hardware independent and one that is hardware dependent, to make it easier to replace one piece of the hardware without having to change the whole application. In the hardware dependent part you should include:
The device drivers can then be called from the application using RTOS standard calls. The RTOS creates during its own initialization tables that contain function pointers to all the device driver's routines. But as device drivers are initialized after the RTOS has been initialized you can in your device driver use the functionality of the RTOS.
When you design your system, you also have to specify which type of device driver design you need. Should the device driver be interrupt driven, which is most common today, or should the application be polling the device? It of course depends on the device itself, but also on your deadlines in your system. But you also need to specify if your device driver should called synchronously or asynchronously.
Synchronous Device Driver
When a task calls a synchronous device driver it means that the task will wait until the device has some data that it can give to the task, see figure 2. In this example the task is blocked on a semaphore until the driver has been able to read any data from the device.
Asynchronous Device Driver
When a task calls an asynchronous device driver it means that the task will only check if the device has some data that it can give to the task, see figure 3. In this example the task is just checking if there is a message in the queue. The device driver can independently of the task send data into queue.
Latest Input Only
Sometimes a task only wants to read the actual data from the device, e.g. the speed of a motor or the actual temperature of the oil. So in this case will not the design shown in figure 3 work as in that design data is queued. So instead of using a queue for the data, we use a shared memory area protected by a semaphore, see figure 4.
Serial Input and Output Data Spooler
If the device driver should be able to handle blocks of data by itself, the device driver needs to have internal buffers for storing data. Two examples of a design like this are shown in figure 5 & 6.
Writing a Device Driver
So should you write a device driver from scratch when you need one? Hopefully not, as it
can be a very hard job to do that and time consuming. So try to find one or a similar one
instead. Here is what you should do: