6.  Writing a Comedi driver

6.1. Communication user-space — kernel-space
6.2. Generic functionality
6.3. Board-specific functionality
6.4. Callbacks, events and interrupts
6.5. Device driver caveats
6.6. Integrating the driver in the Comedi library

This section explains the most important implementations aspects of the Comedi device drivers. It tries to give the interested device driver writer an overview of the different steps required to write a new device driver.

This section does not explain all implementation details of the Comedi software itself: Comedi has once and for all solved lots of boring but indispensable infrastructural things, such as: timers, management of which drivers are active, memory management for drivers and buffers, wrapping of RTOS-specific interfaces, interrupt handler management, general error handling, the /proc interface, etc. So, the device driver writers can concentrate on the interesting stuff: implementing their specific interface card's DAQ functionalities.

In order to make a decent Comedi device driver, you must know the answers to the following questions:

6.1.  Communication user-space — kernel-space

In user-space, you interact with the functions implemented in the Comedilib library. Most of the device driver core of the Comedilib library is found in lib subdirectory.

All user-space Comedi instructions and commands are transmitted to kernel space through a traditional ioctl system call. (See lib/ioctl.c in Comedilib.) The user-space information command is encoded as a number in the ioctl call, and decoded in the kernel-space library. There, they are executed by their kernel-space counterparts. This is done in the comedi_fops.c file in the Comedi sources: the comedi_unlocked_ioctl function processes the results of the ioctl system call, interprets its contents, and then calls the corresponding kernel-space do_…_ioctl function(s). For example, a Comedi instruction is further processed by the do_insn_ioctl function. (Which, in turn, uses parse_insn for further detailed processing.)

The data corresponding to instructions and commands is transmitted with the copy_from_user function; acquisition data captured by the interface card passes the kernel/user-space boundary with the help of a copy_to_user function.