File: boardspecific.html

package info (click to toggle)
comedilib 0.11.0-1
  • links: PTS
  • area: main
  • in suites: buster
  • size: 8,388 kB
  • sloc: xml: 19,779; ansic: 14,719; sh: 4,583; cpp: 2,195; ruby: 1,658; perl: 700; makefile: 604; yacc: 439; lex: 86; python: 17
file content (131 lines) | stat: -rw-r--r-- 9,572 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>6.3.  Board-specific functionality</title><link rel="stylesheet" type="text/css" href="comedilib.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.1"><link rel="home" href="index.html" title="Comedi"><link rel="up" href="driverwriting.html" title="6.  Writing a Comedi driver"><link rel="prev" href="comedikernelgeneric.html" title="6.2.  Generic functionality"><link rel="next" href="drivercallbacks.html" title="6.4.  Callbacks, events and interrupts"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">6.3. 
Board-specific functionality
</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="comedikernelgeneric.html">Prev</a> </td><th width="60%" align="center">6. 
Writing a <acronym class="acronym">Comedi</acronym> driver
</th><td width="20%" align="right"> <a accesskey="n" href="drivercallbacks.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="boardspecific"></a>6.3. 
Board-specific functionality
</h3></div></div></div><p>
The <code class="filename">comedi/drivers</code>
subdirectory contains
the <span class="strong"><strong>board-specific</strong></span> device driver
code. Each new card must get an entry in this directory.
<span class="strong"><strong>Or</strong></span>
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.
</p><p>
To help device driver writers,
<a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> provides the <span class="quote">“<span class="quote">skeleton</span>”</span> of a new device driver,
in the <code class="filename">comedi/drivers/skel.c</code> 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.
</p><p>
The first thing you notice in <code class="filename">skel.c</code> is the
documentation section: the <a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> documentation is partially
generated automatically, from the information that is given in this
section. So, please comply with the structure and the keywords
provided as <a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> standards.
</p><p>
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.
</p><p>
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):
</p><pre class="programlisting">
  mydriver_attach();
  mydriver_detach();
</pre><p>
In the <span class="quote">“<span class="quote">attach</span>”</span> function, memory is allocated for the
necessary <a class="link" href="comedikernelgeneric.html#driverdatastructures" title="6.2.1.  Data structures">data structures</a>,
all properties of a device and its subdevices are defined, and filled
in in the generic <a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> 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 <code class="function">mydriver_attach</code> function must:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
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.
</p></li><li class="listitem"><p>
allocate memory for the private data structures.
</p></li><li class="listitem"><p>
initialize the board registers and possible subdevices (timer, DMA, PCI,
hardware FIFO, etc.).
</p></li><li class="listitem"><p>
return <code class="literal">1</code>, indicating success. If there were any errors along the way,
you should return the appropriate (negative) error number.  If an error is
returned, the <code class="function">mydriver_detach</code> function is
called.  The <code class="function">mydriver_detach</code> function should
check any resources that may have been allocated and release them as
necessary.  The <a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> core frees
<em class="structfield"><code>dev-&gt;subdevices</code></em> and
<em class="structfield"><code>dev-&gt;private</code></em>, so this does not need to be done in
<code class="function">mydriver_detach</code>.
</p></li><li class="listitem"><p>
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.
</p></li></ul></div><p>
Typically, you will be able to implement most of
the above-mentioned functionality by
<span class="emphasis"><em>cut-and-paste</em></span> from already existing drivers. The
<code class="function">mydriver_attach</code> function needs most of your
attention, because it must correctly define and allocate the (private
and generic) data structures that are needed for this device. That is,
each sub-device and each channel must get appropriate data fields, and
an appropriate initialization. The good news, of course, is that
<a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> provides the data structures and the defines that fit very
well with almost all DAQ functionalities found on interface cards.
These can be found in the
<a class="link" href="comedikernelgeneric.html" title="6.2.  Generic functionality">header files</a> of the
<code class="filename">include/linux/</code>
directory.
</p><p>
Drivers with digital I/O subdevices should implement the following functions,
setting the function pointers in the <span class="type">comedi_subdevice</span>:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="function">insn_bits</code>: drivers set this if they have a
function that supports reading and writing multiple bits in a digital
I/O subdevice at the same time.  Most (if not all) of the drivers use
this interface instead of insn_read and insn_write for DIO subdevices.
</p></li><li class="listitem"><p>
<code class="function">insn_config</code>: implements <code class="constant">INSN_CONFIG</code>
instructions.  Currently used for configuring the direction of digital
I/O lines, although will eventually be used for generic configuration
of drivers that is outside the scope of the currently defined <a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a>
interface.
</p></li></ul></div><p>
Finally, the device driver writer must implement the
<code class="function">insn_read</code> and <code class="function">insn_write</code> functions for
the analog channels on the card:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
<code class="function">insn_read</code>: acquire the inputs on the board and
transfer them to the software buffer of the driver.
</p></li><li class="listitem"><p>
<code class="function">insn_write</code>: transfer data from the software
buffer to the card, and execute the appropriate output conversions.
</p></li></ul></div><p>
In some drivers, you want to catch interrupts, and/or want to use the
<code class="constant"><a class="link" href="inttrigconfiguration.html#insn-inttrig">INSN_INTTRIG</a></code>
instruction. In this
case, you must provide and register these
<a class="link" href="drivercallbacks.html" title="6.4.  Callbacks, events and interrupts">callback</a> functions.
</p><p>
Implementation of all of the above-mentioned functions requires
perfect knowledge about the hardware registers and addresses of the
interface card. In general, you can find
<span class="emphasis"><em>some</em></span> inspiration in the already available device
drivers, but don't trust that blind
<span class="emphasis"><em>cut-and-paste</em></span> will bring you far…
</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="comedikernelgeneric.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="driverwriting.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="drivercallbacks.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">6.2. 
Generic functionality
 </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 6.4. 
Callbacks, events and interrupts
</td></tr></table></div></body></html>