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
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:
How does the communication between user-space and kernel-space work?
How to use DMA and interrupts?
What are the addresses and meanings of all the card's registers?
This information is to be found in the so-called “register level manual” of the card. Without it, coding a device driver is close to hopeless. It is also something that Comedi (and hence also this handbook) cannot give any support or information for: board manufacturers all use their own design and nomenclature.
In user-space, you interact with the functions implemented in the
Most of the device driver core of the Comedilib library is found in
All user-space Comedi
are transmitted to kernel space through a traditional
ioctl system call.
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
ioctl system call, interprets its contents,
and then calls the corresponding kernel-space
For example, a Comedi
instruction is further processed
do_insn_ioctl function. (Which, in turn,
parse_insn for further detailed processing.)
The data corresponding to instructions and commands is transmitted
acquisition data captured by the interface card passes the
kernel/user-space boundary with the help of a