/usr/share/doc/libcomedi-dev/html/asyncprogram.html is in libcomedi-dev 0.10.2-4+b3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | <html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>3.4.  Asynchronous acquisition</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="writingprograms.html" title="3.  Writing Comedi programs"><link rel="prev" href="secondprogram.html" title="3.3.  Your second Comedi program"><link rel="next" href="ar01s03s05.html" title="3.5. Further examples"></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">3.4. 
Asynchronous acquisition
</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="secondprogram.html">Prev</a> </td><th width="60%" align="center">3. 
Writing <acronym class="acronym">Comedi</acronym> programs
</th><td width="20%" align="right"> <a accesskey="n" href="ar01s03s05.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="asyncprogram"></a>3.4. 
Asynchronous acquisition
</h3></div></div></div><p>
Of special importance is the so called
"asynchronous data acquisition" where <a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> is sampling
in the background at a given sample rate. The
user can retrieve the data whenever it is convenient.
<a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> stores the data in a ring-buffer so that
programs can perform other tasks in the foreground, for example
plotting data or interacting with the user.
This technique is used in programs such
as <span class="command"><strong>ktimetrace</strong></span> or <span class="command"><strong>comedirecord</strong></span>.
</p><p>
There are two different ways how a sequence of channels is
measured during asynchronous acquisition (see also the Figure in
the introduction):
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
The channels are measured with the help
of a multiplexer which switches to the next channel after each measurement.
This means that the sampling rate is divided by the number
of channels.
</li><li class="listitem">
The channels are all measured at the same time, for example
when every channel has its own converter. In this case the
sampling rate need not to be divided by the number of channels.
</li></ul></div><p>
How your <a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> device handles the asynchronous acquisition can be found out
with the command <span class="command"><strong>comedi_board_info -v</strong></span>.
</p><p>
The program <code class="filename">demo/tut3.c</code> demonstrates the
asynchronous acquisition. The general strategy is always
the same: first, we tell <a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> all sampling parameters such as
the sampling rate,
the number of channels and anything it needs to know
so that it can run independently in the background.
Then <a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> checks our request and it might
modify it. For example we might want to have a sampling rate of
16kHz but we only get 1kHz. Finally we can start
the asynchronous acquisition. Once it has been started we
need to check periodically if data is available and
request it from <a class="ulink" href="http://www.comedi.org" target="_top"><acronym class="acronym">Comedi</acronym></a> so that its internal buffer
won't overrun.
</p><p>
In summary the asynchonous acquisition is performed in the following
way:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
Create a command structure of type <span class="type"><a class="link" href="datatypesstructures.html#ref-type-comedi-cmd" title="5.3.7.  comedi_cmd">comedi_cmd</a></span></li><li class="listitem">
Call the function <code class="function"><a class="link" href="func-ref-comedi-get-cmd-generic-timed.html" title="comedi_get_cmd_generic_timed">comedi_get_cmd_generic_timed</a></code>
to fill the command structure with your comedi device,
subdevice, sampling rate and number of channels.
</li><li class="listitem">
Create a channel-list and store it in the command structure. This
tells comedi which channels should be sampled in the background.
</li><li class="listitem">
Call <code class="function"><a class="link" href="func-ref-comedi-command-test.html" title="comedi_command_test">comedi_command_test</a></code> with your command structure. Comedi might modify your requested sampling rate and channels.
</li><li class="listitem">
Call <code class="function"><a class="link" href="func-ref-comedi-command-test.html" title="comedi_command_test">comedi_command_test</a></code> again which now should return zero for success.
</li><li class="listitem">
Call <code class="function"><a class="link" href="func-ref-comedi-command.html" title="comedi_command">comedi_command</a></code> to start the asynchronous acquisition. From now on the kernel ringbuffer will be filled at the specified sampling rate.
</li><li class="listitem">
Call periodically the standard
function <code class="function">read</code> and receive the data. The
result should always be non zero as long as the acquisition
is running.
</li><li class="listitem">
Convert the received data either into
<span class="type"><a class="link" href="datatypesstructures.html#ref-type-lsampl-t" title="5.3.4.  lsampl_t">lsampl_t</a></span> or
<span class="type"><a class="link" href="datatypesstructures.html#ref-type-sampl-t" title="5.3.3.  sampl_t">sampl_t</a></span> depending
on the subdevice flag <code class="constant">SDF_LSAMPL</code>.
</li><li class="listitem">
Poll for data with <code class="function">read</code> as long as it returns
a positive result or until the program terminates.
</li></ul></div><p>
The program below is a stripped down version of the
program <code class="filename">cmd.c</code> in the demo directory. To
compile it run:
</p><pre class="screen">
gcc tut3.c -lcomedi -lm -o tut3
</pre><p>
It requests data from two channels at
a sampling rate of 1kHz and a total of 10000 samples.
which are then printed to stdout. You can pipe the data
into a file and plot it with gnuplot. As mentioned above, central in this
program is the loop using the standard C <code class="function">read</code> command
which receives the buffer contents. Below is an
extract from <code class="filename">tut3.c</code> showing the
relevant commands:
</p><pre class="programlisting">
<span style="color: red"><xi:include></xi:include></span>
</pre><p>
For advanced programmers the
function <code class="function"><a class="link" href="func-ref-comedi-get-buffer-contents.html" title="comedi_get_buffer_contents">comedi_get_buffer_contents</a></code>
is useful to check if there is actually data in the ringbuffer
so that a call of <code class="function">read</code> can be avoided for example
when the data readout is called by a timer call-back function.
</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="secondprogram.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="writingprograms.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ar01s03s05.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">3.3. 
Your second <acronym class="acronym">Comedi</acronym> program
 </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 3.5. Further examples</td></tr></table></div></body></html>
|