Specifications

Comedi
145 / 148
int comedi_register_callback(comedi_t
*
d,unsigned int subdevice, unsigned int mask,int (
*
-
cb)(unsigned int,void
*
),void
*
arg);
int comedi_poll(comedi_t
*
d, unsigned int subdevice);
void comedi_perror(const char
*
message);
The file comedi/rt.c provides interrupt handling for real-time tasks (one interrupt per device!):
int comedi_request_irq(unsigned irq,void (
*
handler)(int, void
*
,struct pt_regs
*
), -
unsigned long flags,const char
*
device,comedi_device
*
dev_id);
void comedi_free_irq(unsigned int irq,comedi_device
*
dev_id)
6.3 Board-specific functionality
The comedi/drivers subdirectory contains the board-specific device driver code. Each new card must get an entry in this
directory. Or extend the functionality of an already existing driver file if the new card is quite similar to that implemented in an
already existing driver. For example, many of the National Instruments DAQ cards use the same driver files.
To help device driver writers, Comedi provides the ‘skeleton’ of a new device driver, in the comedi/drivers/skel.c file.
Before starting to write a new driver, make sure you understand this file, and compare it to what you find in the other already
available board-specific files in the same directory.
The first thing you notice in skel.c is the documentation section: the Comedi documentation is partially generated automat-
ically, from the information that is given in this section. So, please comply with the structure and the keywords provided as
Comedi standards.
The second part of the device driver contains board-specific static data structure and defines: addresses of hardware registers;
defines and function prototypes for functionality that is only used inside of the device driver for this board; the encoding of the
types and number of available channels; PCI information; etc.
Each driver has to register two functions which are called when you load and unload your board’s device driver (typically via a
kernel module):
mydriver_attach();
mydriver_detach();
In the ‘attach’ function, memory is allocated for the necessary data structures, all properties of a device and its subdevices are
defined, and filled in in the generic Comedi data structures. As part of this, pointers to the low level instructions being supported
by the subdevice have to be set, which define the basic functionality. In somewhat more detail, the mydriver_attach()
function must:
check and request the I/O port region, IRQ, DMA, and other hardware resources. It is convenient here if you verify the
existence of the hardware and the correctness of the other information given. Sometimes, unfortunately, this cannot be done.
allocate memory for the private data structures.
initialize the board registers and possible subdevices (timer, DMA, PCI, hardware FIFO, etc.).
return 1, indicating success. If there were any errors along the way, you should return the appropriate (negative) error number.
If an error is returned, the mydriver_detach() function is called. The mydriver_detach() function should check
any resources that may have been allocated and release them as necessary. The Comedi core frees dev->subdevices and
dev->private, so this does not need to be done in mydriver_detach().
If the driver has the possibility to offer asynchronous data acquisition, you have to code an interrupt service routine, event
handling routines, and/or callback routines.