To evaluate the best driver implementation strategy, it is important to examine some key properties of the device. The complexity of the driver is usually related directly to the complexity of the device, which can vary widely.
Some devices are very simple in function, such as a switch module in which a driver directly controls the state of each relay by setting individual bits in its control/status registers (CSRs). A driver for this type of device can usually be implemented with relatively little effort.
Other devices have more complicated register maps that do not directly map to the functionality desired in a typical application. For example, the configuration, status, and data information related to a single I/O function may be mapped to several registers. Conversely multiple I/O functions can be mapped to several bit fields within a single register. An instrument driver for this type of device must translate the functionality provided through its API to the programming logic required by the hardware registers.
Devices that generate asynchronous events or transfer large amounts of data often use interrupts and/or DMA to reduce the workload on the processor. These features will add another level of complexity to the driver.
In summary, as device complexity increases, the driver must do more work to translate the driver API functions to sequences of register operations.
Note: For core I/O interfaces (keyboard, mouse, video, disk storage, networking, serial port, printer port, etc.) the operating system provides software infrastructure that handles standard protocols and APIs. It is important to understand that under VISA a driver communicates with the device, VISA does not provide access to the device through standard interfaces such as file I/O or TCP/IP. For this reason, core I/O interfaces are typically not good candidates for VISA-based driver development.