source: SVN/cambria/redboot/packages/io/common/current/doc/io.sgml @ 1

Last change on this file since 1 was 1, checked in by Tim Harvey, 2 years ago

restored latest version of files from server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 119.0 KB
Line 
1<!-- {{{ Banner                         -->
2
3<!-- =============================================================== -->
4<!--                                                                 -->
5<!--     io.sgml                                                     -->
6<!--                                                                 -->
7<!--     Generic I/O subsystem documentation                         -->
8<!--                                                                 -->
9<!-- =============================================================== -->
10<!-- ####COPYRIGHTBEGIN####                                          -->
11<!--                                                                 -->
12<!-- =============================================================== -->
13<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.  -->
14<!-- This material may be distributed only subject to the terms      -->
15<!-- and conditions set forth in the Open Publication License, v1.0  -->
16<!-- or later (the latest version is presently available at          -->
17<!-- http://www.opencontent.org/openpub/)                            -->
18<!-- Distribution of the work or derivative of the work in any       -->
19<!-- standard (paper) book form is prohibited unless prior           -->
20<!-- permission obtained from the copyright holder                   -->
21<!-- =============================================================== -->
22<!--                                                                 -->     
23<!-- ####COPYRIGHTEND####                                            -->
24<!-- =============================================================== -->
25<!-- #####DESCRIPTIONBEGIN####                                       -->
26<!--                                                                 -->
27<!-- ####DESCRIPTIONEND####                                          -->
28<!-- =============================================================== -->
29
30<!-- }}} -->
31
32<PART id="io">
33<TITLE>I/O Package (Device Drivers)</TITLE>
34
35<!-- {{{ Intro -->
36
37<CHAPTER id="io-package-intro">
38<TITLE>Introduction</TITLE>
39
40<PARA>
41The I/O package is designed as a general purpose framework for
42supporting device drivers. This includes all classes of
43drivers from simple serial to networking stacks and beyond.
44</PARA>
45
46<PARA>
47Components of the I/O package, such as device drivers, are
48configured into the system just like all other components.
49Additionally, end users may add their own drivers to this set.
50</PARA>
51
52<PARA>
53While the set of drivers (and the devices they represent) may be
54considered static, they must be accessed via an opaque
55&ldquo;handle&rdquo;. Each device in the system has a unique name and
56the <FUNCTION>cyg_io_lookup()</FUNCTION> function is used to map that
57name onto the handle for the device. This &ldquo;hiding&rdquo; of the
58device implementation allows for generic, named devices, as well as
59more flexibility. Also, the <FUNCTION>cyg_io_lookup()</FUNCTION>
60function provides drivers the opportunity to initialize the device
61when usage actually starts.
62</PARA>
63
64<PARA>
65All devices have a name. The standard provided devices use names such
66as <filename>&ldquo;/dev/console&rdquo;</filename> and
67<filename>&ldquo;/dev/serial0&rdquo;</filename>, where the
68<filename>&ldquo;/dev/&rdquo;</filename> prefix indicates that this is
69the name of a device.
70</PARA>
71
72<PARA>The entire I/O package API, as well as the standard
73set of provided drivers, is written in C. </PARA>
74
75<PARA>Basic functions are provided to send data to and receive data
76from a device. The details of how this is done is left to the device [class] itself.
77For example, writing data to a block device like a disk drive may
78have different semantics than writing to a serial port. </PARA>
79
80<PARA>Additional functions are provided to manipulate the state
81of the driver and/or the actual device. These functions
82are, by design, quite specific to the actual driver. </PARA>
83
84<PARA>This driver model supports layering; in other words, a device
85may actually be created &ldquo;on top of&rdquo; another device.
86For example, the &ldquo;tty&rdquo; (terminal-like) devices are
87built on top of simple serial devices. The upper layer then has
88the flexibility to add features and functions not found at the lower
89layers. In this case the &ldquo;tty&rdquo; device provides
90for line buffering and editing not available from the simple serial
91drivers.
92</PARA>
93
94<PARA>Some drivers will support visibility of the layers they depend
95upon. The &ldquo;tty&rdquo; driver allows information about
96the actual serial device to be manipulated by passing get/set
97config calls that use a serial driver &ldquo;key&rdquo; down
98to the serial driver itself. </PARA>
99
100</CHAPTER>
101
102<!-- }}} -->
103<!-- {{{ User API -->
104
105<CHAPTER id="io-user-api">
106<TITLE><!-- <index></index> -->User API</TITLE>
107
108<PARA>
109All functions, except <FUNCTION>cyg_io_lookup()</FUNCTION>
110require an I/O &ldquo;<!-- <index></index> -->handle&rdquo;.
111</PARA>
112
113<PARA>
114All functions return a value of the type <type>Cyg_ErrNo</type>. If an
115error condition is detected, this value will be negative and the
116absolute value indicates the actual error, as specified in
117<filename>cyg/error/codes.h</filename>. The only other legal return
118value will be <varname>ENOERR</varname>. All other function arguments
119are pointers (references). This allows the drivers to pass information
120efficiently, both into and out of the driver. The most striking
121example of this is the &ldquo;length&rdquo; value passed to the read
122and write functions. This parameter contains the desired length of
123data on input to the function and the actual transferred length on
124return.
125</PARA>
126
127<PROGRAMLISTING>
128// Lookup a device and return its handle
129  Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_lookup</function>(
130    const char <parameter>*name</parameter>,
131    cyg_io_handle_t <parameter>*handle</parameter> )
132</PROGRAMLISTING>
133
134<PARA>
135This function maps a device name onto an appropriate handle. If the
136named device is not in the system, then the error
137<varname>-ENOENT</varname> is returned. If the device is found, then
138the handle for the device is returned by way of the handle pointer
139<parameter>*handle</parameter>.
140</PARA>
141
142<PROGRAMLISTING>
143// Write data to a device
144Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_write</function>(
145    cyg_io_handle_t <parameter>handle</parameter>,
146    const void <parameter>*buf</parameter>,
147    cyg_uint32 <parameter>*len</parameter> )
148</PROGRAMLISTING>
149
150<PARA>
151This function sends data to a device. The size of data to send is
152contained in <parameter>*len</parameter> and the actual size sent will
153be returned in the same place.
154</PARA>
155
156<PROGRAMLISTING>
157// Read data from a device
158Cyg_ErrNo <!-- <index></index> --><function>cyg_io_read</function>(
159    cyg_io_handle_t <parameter>handle</parameter>,
160    void <parameter>*buf</parameter>,
161    cyg_uint32 <parameter>*len</parameter> )
162</PROGRAMLISTING>
163
164<PARA>
165This function receives data from a device. The desired size of data to
166receive is contained in <parameter>*len</parameter> and the actual
167size obtained will be returned in the same place.
168</PARA>
169
170<PROGRAMLISTING>
171// Get the configuration of a device
172Cyg_ErrNo <FUNCTION><!-- <index></index> -->cyg_io_get_config</FUNCTION>(
173    cyg_io_handle_t <parameter>handle</parameter>,
174    cyg_uint32 <parameter>key</parameter>,
175    void *<parameter>buf</parameter>,
176    cyg_uint32 *<parameter>len</parameter> )
177</PROGRAMLISTING>
178
179<PARA>
180This function is used to obtain run-time configuration about a
181device. The type of information retrieved is specified by the
182<parameter>key</parameter>. The data will be returned in the given
183buffer. The value of <parameter>*len</parameter> should contain the
184amount of data requested, which must be at least as large as the size
185appropriate to the selected key. The actual size of data retrieved is
186placed in <parameter> *len</parameter>. The appropriate key values
187differ for each driver and are all listed in the file
188<filename>&lt;cyg/io/config_keys.h&gt;</filename>.
189</PARA>
190
191<PROGRAMLISTING>
192// Change the configuration of a device
193Cyg_ErrNo <!-- <index></index> --><function>cyg_io_set_config</function>(
194    cyg_io_handle_t <parameter>handle</parameter>,
195    cyg_uint32 <parameter>key</parameter>,
196    const void <parameter>*buf</parameter>,
197    cyg_uint32 <parameter>*len</parameter> )
198</PROGRAMLISTING>
199
200<PARA>
201This function is used to manipulate or change the run-time
202configuration of a device. The type of information is specified by the
203<parameter>key</parameter>. The data will be obtained from the given
204buffer. The value of <parameter>*len</parameter> should contain the
205amount of data provided, which must match the size appropriate to the
206selected key.  The appropriate key values differ for each driver and
207are all listed in the file
208<filename>&lt;cyg/io/config_keys.h&gt;</filename>.
209</PARA>
210
211</CHAPTER>
212
213<!-- }}} -->
214<!-- {{{ Serial Drivers  -->
215
216<CHAPTER id="io-serial-driver-details">
217<TITLE>Serial driver details</TITLE>
218
219<PARA>
220Two different classes of serial drivers are provided as a standard
221part of the eCos system. These are described as &ldquo;raw
222serial&rdquo; (serial) and &ldquo;tty-like&rdquo; (tty).
223</PARA>
224
225<!-- {{{ Raw Serial Drivers -->
226
227<SECTION id="io-simple-serial-driver">
228<TITLE>Raw Serial Driver</TITLE>
229
230<PARA>
231Use the include file <FILENAME>&lt;cyg/io/serialio.h&gt;</FILENAME> for
232this driver.
233</PARA>
234
235<PARA>
236The <!-- <index></index> -->raw serial driver is capable of sending
237and receiving blocks of raw data to a serial device. Controls are
238provided to configure the actual hardware, but there is no manipulation
239of the data by this driver.
240</PARA>
241
242<PARA>
243There may be many instances of this driver in a given system,
244one for each serial channel. Each channel corresponds to a physical
245device and there will typically be a device module created for this
246purpose. The device modules themselves are configurable, allowing
247specification of the actual hardware details, as well as such details
248as whether the channel should be buffered by the serial driver,
249etc.
250</PARA>
251
252<!-- {{{ Runtime Configuration -->
253
254<SECTION>
255<TITLE>Runtime Configuration</TITLE>
256
257<para>
258Runtime configuration is achieved by exchanging data structures with
259the driver via the <function>cyg_io_set_config()</function> and
260<function>cyg_io_get_config()</function> functions.
261</para>
262
263<PROGRAMLISTING>
264typedef struct {
265 cyg_serial_baud_rate_t baud;
266 cyg_serial_stop_bits_t stop;
267 cyg_serial_parity_t parity;
268 cyg_serial_word_length_t word_length;
269 cyg_uint32 flags;
270} cyg_serial_info_t;
271</PROGRAMLISTING>
272
273<PARA>
274The field <structfield><!-- <index></index>
275-->word_length</structfield> contains the number of data bits per word
276(character). This must be one of the values:
277</PARA>
278
279<PROGRAMLISTING>
280 CYGNUM_SERIAL_WORD_LENGTH_5
281 CYGNUM_SERIAL_WORD_LENGTH_6
282 CYGNUM_SERIAL_WORD_LENGTH_7
283 CYGNUM_SERIAL_WORD_LENGTH_8
284</PROGRAMLISTING>
285
286<PARA>
287The field <structfield><!-- <index></index>
288-->baud</structfield> contains a baud rate selection.  This must be
289one of the values:
290</PARA>
291
292<PROGRAMLISTING>
293 CYGNUM_SERIAL_BAUD_50
294 CYGNUM_SERIAL_BAUD_75
295 CYGNUM_SERIAL_BAUD_110
296 CYGNUM_SERIAL_BAUD_134_5
297 CYGNUM_SERIAL_BAUD_150
298 CYGNUM_SERIAL_BAUD_200
299 CYGNUM_SERIAL_BAUD_300
300 CYGNUM_SERIAL_BAUD_600
301 CYGNUM_SERIAL_BAUD_1200
302 CYGNUM_SERIAL_BAUD_1800
303 CYGNUM_SERIAL_BAUD_2400
304 CYGNUM_SERIAL_BAUD_3600
305 CYGNUM_SERIAL_BAUD_4800
306 CYGNUM_SERIAL_BAUD_7200
307 CYGNUM_SERIAL_BAUD_9600
308 CYGNUM_SERIAL_BAUD_14400
309 CYGNUM_SERIAL_BAUD_19200
310 CYGNUM_SERIAL_BAUD_38400
311 CYGNUM_SERIAL_BAUD_57600
312 CYGNUM_SERIAL_BAUD_115200
313 CYGNUM_SERIAL_BAUD_234000
314</PROGRAMLISTING>
315
316<PARA>The field <structfield><!-- <index></index>
317-->stop</structfield> contains the number of stop bits. This must be
318one of the values:</PARA>
319
320<PROGRAMLISTING>
321 CYGNUM_SERIAL_STOP_1
322 CYGNUM_SERIAL_STOP_1_5
323 CYGNUM_SERIAL_STOP_2
324</PROGRAMLISTING>
325
326<NOTE>
327<title>Note</title>
328<PARA>
329On most hardware, a selection of 1.5 stop bits is only valid
330if the word (character) length is 5.
331</PARA>
332</NOTE>
333
334<PARA>The field <structfield><!-- <index></index>
335-->parity</structfield> contains the parity mode.  This must be one of
336the values: </PARA>
337
338<PROGRAMLISTING>
339 CYGNUM_SERIAL_PARITY_NONE
340 CYGNUM_SERIAL_PARITY_EVEN
341 CYGNUM_SERIAL_PARITY_ODD
342 CYGNUM_SERIAL_PARITY_MARK
343 CYGNUM_SERIAL_PARITY_SPACE
344</PROGRAMLISTING>
345
346<PARA>The field <structfield><!-- <index></index>
347-->flags</structfield> is a bitmask which controls the behavior of the
348serial device driver. It should be built from the values
349<literal>CYG_SERIAL_FLAGS_xxx</literal> defined below:
350</PARA>
351
352<PROGRAMLISTING>
353#define CYG_SERIAL_FLAGS_RTSCTS 0x0001
354</PROGRAMLISTING>
355
356<PARA>If this bit is set then the port is placed in &ldquo;hardware
357handshake&rdquo; mode. In this mode, the CTS and RTS pins control
358when data is allowed to be sent/received at the port. This
359bit is ignored if the hardware does not support this level of
360handshake.
361</PARA>
362
363<PROGRAMLISTING>
364typedef struct {
365  cyg_int32 rx_bufsize;
366  cyg_int32 rx_count;
367  cyg_int32 tx_bufsize;
368  cyg_int32 tx_count;
369} cyg_serial_buf_info_t;     
370</PROGRAMLISTING>
371
372<PARA>The field <structfield>rx_bufsize</structfield> contains
373the total size of the incoming data buffer. This is set to zero on
374devices that do not support buffering (i.e. polled devices).</PARA>
375
376<PARA>The field <structfield>rx_count</structfield> contains the
377number of bytes currently occupied in the incoming data buffer.
378This is set to zero on devices that do not support buffering (i.e. polled
379devices).</PARA>
380
381<PARA>The field <structfield>tx_bufsize</structfield> contains the
382total size of the transmit data buffer. This is set to zero on devices
383that do not support buffering (i.e. polled devices).</PARA>
384
385<PARA>The field <structfield>tx_count</structfield> contains the
386number of bytes currently occupied in the transmit data buffer.  This
387is set to zero on devices that do not support buffering (i.e. polled
388devices).</PARA>
389
390</SECTION>
391
392<!-- }}} -->
393<!-- {{{ API Details -->
394
395<SECTION>
396<TITLE><!-- <index></index> -->API Details</TITLE>
397
398<!-- {{{ cyg_io_write -->
399
400<section id="io-serial-cyg-io-write">
401<title>cyg_io_write</title>
402
403<PROGRAMLISTING>
404cyg_io_write(handle, buf, len)
405</PROGRAMLISTING>
406
407<PARA>
408Send the data from <parameter>buf</parameter> to the device. The
409driver maintains a buffer to hold the data. The size of the
410intermediate buffer is configurable within the interface module. The
411data is not modified at all while it is being buffered. On return,
412<parameter>*len</parameter> contains the amount of characters actually
413consumed .</PARA>
414
415<PARA>
416It is possible to configure the write call to be blocking
417(default) or non-blocking. Non-blocking mode requires both the configuration
418option <literal>CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING</literal>
419to be enabled, and the specific device to be set to non-blocking
420mode for writes (see <function>cyg_io_set_config()</function>).
421</para>
422
423<para>
424In blocking mode, the call will not return until there is space in the
425buffer and the entire contents of <parameter>buf</parameter> have been
426consumed.
427</PARA>
428
429<PARA>
430In non-blocking mode, as much as possible gets consumed from
431<parameter>buf</parameter>. If everything was consumed, the call
432returns <literal>ENOERR</literal>. If only part of the
433<parameter>buf</parameter> contents was consumed,
434<literal>-EAGAIN</literal> is returned and the caller must try
435again. On return, <parameter>*len</parameter> contains the number of characters actually
436consumed .</PARA>
437
438<PARA>
439The call can also return <literal>-EINTR</literal> if interrupted
440via the <function>cyg_io_get_config()</function>/<literal>ABORT</literal> key.
441</para>
442
443</section>
444
445<!-- }}} -->
446<!-- {{{ cyg_io_read -->
447
448<section id="io-serial-cyg-io-read">
449<title>cyg_io_read</title>
450
451<programlisting>
452cyg_io_read(handle, buf, len)
453</programlisting>
454
455<PARA>
456Receive data into the buffer, <parameter>buf</parameter>, from the
457device. No manipulation of the data is performed before being
458transferred.  An interrupt driven interface module will support data
459arriving when no read is pending by buffering the data in the serial
460driver.  Again, this buffering is completely configurable. On return,
461<parameter>*len</parameter> contains the number of characters actually
462received.</PARA>
463
464<PARA>
465It is possible to configure the read call to be blocking (default)
466or  non-blocking. Non-blocking mode requires both the configuration
467option  <literal>CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING</literal>
468to be enabled, and the specific device to be set to non-blocking
469mode for reads (see <function>cyg_io_set_config()</function>).
470</PARA>
471
472<PARA>
473In blocking mode, the call will not return until the requested
474amount of data has been read.</PARA>
475
476<PARA>
477In non-blocking mode, data waiting in the device buffer is copied to
478<parameter>buf</parameter>, and the call returns immediately. If there
479was enough data in the buffer to fulfill the request,
480<literal>ENOERR</literal> is returned.  If only part of the request
481could be fulfilled, <literal>-EAGAIN</literal> is returned and the
482caller must try again. On return, <parameter>*len</parameter> contains
483the number of characters actually received.</PARA>
484
485<PARA>
486The call can also return <literal>-EINTR</literal> if interrupted via
487the <function>cyg_io_get_config()</function>/<literal>ABORT</literal>
488key.
489</PARA>
490
491</section>
492
493<!-- }}} -->
494<!-- {{{ cyg_io_get_config -->
495
496<section id="io-serial-cyg-get-config">
497<title>cyg_io_get_config</title>
498
499<PROGRAMLISTING>
500cyg_io_get_config(handle, key, buf, len)
501</PROGRAMLISTING>
502
503<PARA>This function returns current [runtime] information
504about the device and/or driver. </PARA>
505
506<VARIABLELIST>
507  <VARLISTENTRY>
508    <TERM><literal>CYG_IO_GET_CONFIG_SERIAL_INFO</literal></TERM>
509    <LISTITEM>
510      <variablelist>
511        <VARLISTENTRY>
512          <TERM>Buf type:</TERM>
513          <LISTITEM>
514            <PARA>cyg_serial_info_t</PARA>
515          </LISTITEM>
516        </VARLISTENTRY>
517        <VARLISTENTRY>
518          <TERM>Function:</TERM>
519          <LISTITEM>
520            <PARA>
521              This function retrieves the current state of the driver
522              and hardware. This information contains fields for
523              hardware baud rate, number of stop bits, and parity
524              mode. It also includes a set of flags that control the
525              port, such as hardware flow control.
526            </PARA>
527          </LISTITEM>
528        </VARLISTENTRY>
529      </variablelist>
530    </LISTITEM>
531  </VARLISTENTRY>
532
533  <VARLISTENTRY>
534    <TERM><literal>CYG_IO_GET_CONFIG_SERIAL_BUFFER_INFO</literal></TERM>
535    <LISTITEM>
536       <variablelist>
537         <VARLISTENTRY>
538           <TERM>Buf type:</TERM>
539           <LISTITEM>
540             <PARA>cyg_serial_buf_info_t</PARA>
541           </LISTITEM>
542         </VARLISTENTRY>
543         <VARLISTENTRY>
544           <TERM>Function:</TERM>
545           <LISTITEM>
546             <PARA>
547               This function retrieves the current state of the
548               software buffers in the serial drivers. For both
549               receive and transmit buffers it returns the total
550               buffer size and the current number of bytes occupied in
551               the buffer. It does not take into account any buffering
552               such as FIFOs or holding registers that the serial
553               device itself may have.
554             </PARA>
555           </LISTITEM>
556         </VARLISTENTRY>
557       </variablelist>
558    </LISTITEM>
559  </VARLISTENTRY>
560
561  <VARLISTENTRY>
562    <TERM><literal>CYG_IO_GET_CONFIG_SERIAL_OUTPUT_DRAIN</literal></TERM>
563    <LISTITEM>
564      <variablelist>
565        <VARLISTENTRY>
566          <TERM>Buf type:</TERM>
567          <LISTITEM>
568            <PARA>void *</PARA>
569          </LISTITEM>
570        </VARLISTENTRY>
571        <VARLISTENTRY>
572          <TERM>Function:</TERM>
573          <LISTITEM>
574            <PARA>
575              This function waits for any buffered output to
576              complete. This function only completes when there is no
577              more data remaining to be sent to the device.
578            </PARA>
579          </LISTITEM>
580        </VARLISTENTRY>
581      </variablelist>
582    </LISTITEM>
583  </VARLISTENTRY>
584
585  <VARLISTENTRY>
586    <TERM><literal>CYG_IO_GET_CONFIG_SERIAL_OUTPUT_FLUSH</literal></TERM>
587    <LISTITEM>
588      <variablelist>
589        <VARLISTENTRY>
590          <TERM>Buf type:</TERM>
591          <LISTITEM>
592            <PARA>void *</PARA>
593          </LISTITEM>
594        </VARLISTENTRY>
595        <VARLISTENTRY>
596          <TERM>Function:</TERM>
597          <LISTITEM>
598            <PARA>
599              This function discards any buffered output for the
600              device.
601            </PARA>
602          </LISTITEM>
603        </VARLISTENTRY>
604      </variablelist>
605    </LISTITEM>
606  </VARLISTENTRY>
607
608  <VARLISTENTRY>
609    <TERM><literal>CYG_IO_GET_CONFIG_SERIAL_INPUT_DRAIN</literal></term>
610    <LISTITEM>
611      <variablelist>
612        <VARLISTENTRY>
613          <TERM>Buf type:</TERM>
614          <LISTITEM>
615            <PARA>void *</PARA>
616          </LISTITEM>
617        </VARLISTENTRY>
618        <VARLISTENTRY>
619          <TERM>Function:       </TERM>
620          <LISTITEM>
621            <PARA>This function discards any buffered input for the
622            device.</PARA>
623          </LISTITEM>
624        </VARLISTENTRY>
625      </variablelist>
626    </LISTITEM>
627  </VARLISTENTRY>
628
629  <VARLISTENTRY>
630    <TERM><literal>CYG_IO_GET_CONFIG_SERIAL_ABORT</literal></TERM>
631    <LISTITEM>
632      <variablelist>
633        <VARLISTENTRY>
634          <TERM>Buf type:</TERM>
635          <LISTITEM>
636            <PARA> void*</PARA>
637          </LISTITEM>
638        </VARLISTENTRY>
639        <VARLISTENTRY>
640          <TERM>Function:</TERM>
641          <LISTITEM>
642            <PARA>This function will cause any pending read or write calls on
643            this device to return with <literal>-EABORT</literal>.</PARA>
644          </LISTITEM>
645        </VARLISTENTRY>
646      </variablelist>
647    </LISTITEM>
648  </VARLISTENTRY>
649
650  <VARLISTENTRY>
651    <TERM><literal>CYG_IO_GET_CONFIG_SERIAL_READ_BLOCKING</literal></TERM>
652    <LISTITEM>
653      <variablelist>
654        <VARLISTENTRY>
655          <TERM>Buf type:</TERM>
656          <LISTITEM>
657            <PARA> cyg_uint32 (values 0 or 1)</PARA>
658          </LISTITEM>
659        </VARLISTENTRY>
660        <VARLISTENTRY>
661          <TERM>Function:</TERM>
662          <LISTITEM>
663            <PARA>This function will read back the blocking-mode
664            setting for read calls on this device. This call is only
665            available if the configuration option
666            <literal>CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING</literal> is
667            enabled.</PARA>
668          </LISTITEM>
669        </VARLISTENTRY>
670      </variablelist>
671    </LISTITEM>
672  </VARLISTENTRY>
673
674  <VARLISTENTRY>
675    <TERM><literal>CYG_IO_GET_CONFIG_SERIAL_WRITE_BLOCKING</literal></TERM>
676    <LISTITEM>
677      <variablelist>
678        <VARLISTENTRY>
679          <TERM>Buf type:</TERM>
680          <LISTITEM>
681            <PARA> cyg_uint32 (values 0 or 1)</PARA>
682          </LISTITEM>
683        </VARLISTENTRY>
684        <VARLISTENTRY>
685          <TERM>Function:</TERM>
686          <LISTITEM>
687            <PARA>
688            This function will read back the blocking-mode
689            setting for write calls on this device. This call is only
690            available if the configuration option
691            <literal>CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING</literal> is enabled.</PARA>
692          </listitem>
693        </varlistentry>
694      </variablelist>
695    </listitem>
696  </varlistentry>
697</variablelist>
698
699</section>
700
701<!-- }}} -->
702<!-- {{{ cyg_io_set_config -->
703
704<section id="io-serial-cyg-set-config">
705<title>cyg_io_set_config</title>
706
707<PROGRAMLISTING>
708cyg_io_set_config(handle, key, buf,len)
709</PROGRAMLISTING>
710
711<PARA>This function is used to update or change runtime configuration
712of a port. </PARA>
713
714<variablelist>
715  <VARLISTENTRY>
716    <TERM><literal>CYG_IO_SET_CONFIG_SERIAL_INFO</literal></TERM>
717    <LISTITEM>
718      <variablelist>
719        <VARLISTENTRY>
720          <TERM>Buf type:</TERM>
721          <LISTITEM>
722            <PARA>cyg_serial_info_t</PARA>
723          </LISTITEM>
724        </VARLISTENTRY>
725        <VARLISTENTRY>
726          <TERM>Function:</TERM>
727          <LISTITEM>
728            <PARA>This function updates the information for the driver
729            and hardware.  The information contains fields for
730            hardware baud rate, number of stop bits, and parity
731            mode. It also includes a set of flags that control the
732            port, such as hardware flow control.
733            </PARA>
734          </LISTITEM>
735        </VARLISTENTRY>
736      </variablelist>
737    </LISTITEM>
738  </VARLISTENTRY>
739
740  <VARLISTENTRY>
741    <TERM><literal>CYG_IO_SET_CONFIG_SERIAL_READ_BLOCKING</literal></TERM>
742    <LISTITEM>
743      <variablelist>
744        <VARLISTENTRY>
745          <TERM>Buf type:</TERM>
746          <LISTITEM>
747            <PARA> cyg_uint32 (values 0 or 1)</PARA>
748          </LISTITEM>
749        </VARLISTENTRY>
750        <VARLISTENTRY>
751          <TERM>Function:</TERM>
752          <LISTITEM>
753            <PARA>This function will set the blocking-mode for read
754            calls on this device. This call is only available if the
755            configuration option <literal>CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING</literal>
756            is enabled.
757            </PARA>
758          </LISTITEM>
759        </VARLISTENTRY>
760      </variablelist>
761    </LISTITEM>
762  </VARLISTENTRY>
763
764  <VARLISTENTRY>
765    <TERM><literal>CYG_IO_SET_CONFIG_SERIAL_WRITE_BLOCKING</literal></TERM>
766    <LISTITEM>
767      <variablelist>
768        <VARLISTENTRY>
769          <TERM>Buf type:</TERM>
770          <LISTITEM>
771            <PARA>cyg_uint32 (values 0 or 1)</PARA>
772          </LISTITEM>
773        </VARLISTENTRY>
774        <VARLISTENTRY>
775          <TERM>Function:</TERM>
776          <LISTITEM>
777            <PARA>This function will set the blocking-mode for write
778            calls on this device. This call is only available if the
779            configuration option <literal>CYGOPT_IO_SERIAL_SUPPORT_NONBLOCKING</literal>
780            is enabled.
781            </PARA>
782          </LISTITEM>
783        </VARLISTENTRY>
784      </variablelist>
785    </LISTITEM>
786  </VARLISTENTRY>
787</VARIABLELIST>
788
789</section>
790
791<!-- }}} -->
792
793</SECTION>
794
795<!-- }}} -->
796
797</SECTION>
798
799<!-- }}} -->
800<!-- {{{ TTY Drivers -->
801
802<SECTION id="io-tty-driver">
803<TITLE> TTY driver</TITLE>
804
805<PARA>
806Use the include file <filename>&lt;cyg/io/ttyio.h&gt;</filename> for
807this driver.
808</PARA>
809
810<PARA>
811This <!-- <index></index> -->driver is built on top of the simple
812serial driver and is typically used for a device that interfaces with
813humans such as a terminal. It provides some minimal formatting of data
814on output and allows for line-oriented editing on input.
815</PARA>
816
817<!-- {{{ Runtime Configuration -->
818
819<SECTION>
820<TITLE>Runtime configuration</TITLE>
821
822<para>
823Runtime configuration is achieved by exchanging data structures with
824the driver via the <function>cyg_io_set_config()</function> and
825<function>cyg_io_get_config()</function> functions.
826</para>
827
828
829<PROGRAMLISTING>
830typedef struct {
831 cyg_uint32 tty_out_flags;
832 cyg_uint32 tty_in_flags;
833} cyg_tty_info_t;
834</PROGRAMLISTING>
835
836<PARA>The field <structfield><!-- <index></index> -->tty_out_flags</structfield>
837is used to control what happens to data as it is send to the serial
838port. It contains a bitmap comprised of the bits as defined by the
839<literal>CYG_TTY_OUT_FLAGS_xxx</literal> values below. </PARA>
840
841<PROGRAMLISTING>
842#define CYG_TTY_OUT_FLAGS_CRLF 0x0001 // Map '\n' =&gt; '\r\n' on output
843</PROGRAMLISTING>
844
845<PARA>If this bit is set in <structfield>tty_out_flags</structfield>,
846any occurrence of the character &quot;\n&quot; will
847be replaced by the sequence &quot;\r\n&quot; before
848being sent to the device.</PARA>
849
850<PARA>The field <structfield><!-- <index></index> -->tty_in_flags</structfield>
851is used to control how data is handled as it comes from the serial
852port. It contains a bitmap comprised of the bits as defined by the
853<literal>CYG_TTY_IN_FLAGS_xxx</literal> values below. </PARA>
854
855<PROGRAMLISTING>
856#define CYG_TTY_IN_FLAGS_CR 0x0001 // Map '\r' =&gt; '\n' on input
857</PROGRAMLISTING>
858
859<PARA>If this bit is set in <structfield>tty_in_flags</structfield>, the
860character &quot;\r&quot; (&ldquo;return&rdquo; or &ldquo;enter&rdquo; on
861most keyboards) will be mapped to &quot;\n&quot;.</PARA>
862
863<PROGRAMLISTING>
864#define CYG_TTY_IN_FLAGS_CRLF 0x0002 // Map '\r\n' =&gt; '\n' on input
865</PROGRAMLISTING>
866
867<PARA>
868If this bit is set in <structfield>tty_in_flags</structfield>, the
869character sequence &quot;\r\n&quot; (often sent by DOS/Windows
870based terminals) will be mapped to &quot;\n&quot;. </PARA>
871
872<PROGRAMLISTING>
873#define CYG_TTY_IN_FLAGS_BINARY 0x0004 // No input processing
874</PROGRAMLISTING>
875
876<PARA>If this bit is set in <structfield>tty_in_flags</structfield>, the
877input will not be manipulated in any way before being placed in
878the user&rsquo;s buffer. </PARA>
879
880<PROGRAMLISTING>
881#define CYG_TTY_IN_FLAGS_ECHO 0x0008 // Echo characters as processed
882</PROGRAMLISTING>
883
884<PARA>
885If this bit is set in <structfield>tty_in_flags</structfield>, characters
886will be echoed back to the serial port as they are processed. </PARA>
887
888</SECTION>
889
890<!-- }}} -->
891<!-- {{{ API Details -->
892
893<SECTION>
894<TITLE><!-- <index></index> -->API details</TITLE>
895
896<PROGRAMLISTING>
897cyg_io_read(handle, buf, len)
898</PROGRAMLISTING>
899
900<PARA>This function is used to read data from the device. In the
901default case, data is read until an end-of-line character ("\n"
902or "\r") is read. Additionally, the characters are echoed
903back to the [terminal] device. Minimal editing
904of the input is also supported. </PARA>
905
906<NOTE>
907<PARA>When connecting to a remote target via GDB it is not possible
908to provide console input while GDB is connected. The GDB remote
909protocol does not support input. Users must disconnect from GDB
910if this functionality is required.</PARA>
911</NOTE>
912
913<PROGRAMLISTING>        
914cyg_io_write(handle, buf, len)
915</PROGRAMLISTING>
916
917<PARA>This function is used to send data to the device. In the default
918case, the end-of-line character "\n" is replaced by the
919sequence "\r\n". </PARA>
920
921<PROGRAMLISTING>
922cyg_io_get_config(handle, key, buf, len)
923</PROGRAMLISTING>
924
925<PARA>This function is used to get information about the channel&rsquo;s
926configuration at runtime. </PARA>
927
928<VARIABLELIST>
929  <VARLISTENTRY>
930    <TERM><literal>CYG_IO_GET_CONFIG_TTY_INFO</literal></TERM>
931    <LISTITEM>
932      <variablelist>
933        <VARLISTENTRY>
934          <TERM>Buf type:</TERM>
935          <LISTITEM>
936            <PARA>cyg_tty_info_t</PARA>
937          </LISTITEM>
938        </VARLISTENTRY>
939        <VARLISTENTRY>
940          <TERM>Function:</TERM>
941          <LISTITEM>
942            <PARA>This function retrieves the current state of the
943            driver.
944            </PARA>
945          </listitem>
946        </varlistentry>
947      </variablelist>
948    </listitem>
949  </varlistentry>
950</variablelist>
951
952<PARA>Serial driver keys (see above) may also be specified
953in which case the call is passed directly to the serial
954driver. </PARA>
955
956<PROGRAMLISTING>
957cyg_io_set_config(handle, key, buf, len)
958</PROGRAMLISTING>
959
960<PARA>This function is used to modify the channel&rsquo;s configuration
961at runtime. </PARA>
962
963
964<VARIABLELIST>
965  <VARLISTENTRY>
966    <TERM><literal>CYG_IO_SET_CONFIG_TTY_INFO</literal></term>
967    <LISTITEM>
968      <VARIABLELIST>
969        <VARLISTENTRY>
970          <TERM>Buf type:</TERM>
971          <LISTITEM>
972            <PARA>cyg_tty_info_t</PARA>
973          </LISTITEM>
974        </VARLISTENTRY>
975        <VARLISTENTRY>
976          <TERM>Function:       </TERM>
977          <LISTITEM>
978            <PARA>This function changes the current state of the
979            driver.</PARA>
980          </LISTITEM>
981        </VARLISTENTRY>
982      </variablelist>
983    </LISTITEM>
984  </VARLISTENTRY>
985</VARIABLELIST>
986
987<PARA>Serial driver
988keys (see above) may also be specified in which case the
989call is passed directly to the serial driver. </PARA>
990
991</SECTION>
992
993<!-- }}} -->
994
995</SECTION>
996
997<!-- }}} -->
998<!-- {{{ DSP Driver -->
999
1000
1001<!-- }}} -->
1002
1003</CHAPTER>
1004
1005<!-- }}} -->
1006<!-- {{{ How to Write a Driver -->
1007
1008<CHAPTER id="io-how-to-write-a-driver">
1009<TITLE>How to Write a Driver</TITLE>
1010
1011<!-- {{{ Intro -->
1012
1013<PARA>
1014A <!-- <index></index> -->device driver is nothing more than a
1015named entity that supports the basic I/O functions - read, write, get
1016config, and set config. Typically a device driver also uses and
1017manages interrupts from the device. While the interface is generic and
1018device driver independent, the actual driver implementation is
1019completely up to the device driver designer. </PARA>
1020
1021<PARA>That said, the reason for using a device driver is to provide
1022access to a device from application code in as general purpose a
1023fashion as reasonable. Most driver writers are also concerned with
1024making this access as simple as possible while being as efficient
1025as possible. </PARA>
1026
1027<PARA>Most device drivers are concerned with the movement of information,
1028for example data bytes along a serial interface, or packets in a
1029network. In order to make the most efficient use of system resources,
1030interrupts are used. This will allow other application processing
1031to take place while the data transfers are under way, with interrupts
1032used to indicate when various events have occurred. For example,
1033a serial port typically generates an interrupt after a character
1034has been sent &ldquo;down the wire&rdquo; and the interface
1035is ready for another. It makes sense to allow further application
1036processing while the data is being sent since this can take quite
1037a long time. The interrupt can be used to allow the driver to send
1038a character as soon as the current one is complete, without any
1039active participation by the application code. </PARA>
1040
1041<PARA>The main building blocks for device drivers are found in the
1042include file: <filename>&lt;cyg/io/devtab.h&gt;</filename></PARA>
1043
1044<PARA>All device drivers in <EMPHASIS>eCos</EMPHASIS> are described
1045by a device table entry, using the <type>cyg_devtab_entry_t</type> type.
1046The entry should be created using the <FUNCTION>DEVTAB_ENTRY()</FUNCTION> macro,
1047like this:</PARA>
1048
1049<PROGRAMLISTING><function>
1050DEVTAB_ENTRY</function>(l, name, dep_name, handlers, init, lookup, priv)
1051</PROGRAMLISTING>
1052
1053<variablelist>
1054<title>Arguments</title>
1055  <varlistentry>
1056    <term><parameter>l</parameter></term>
1057    <listitem><para>The "C" label for this device table entry.</para></listitem>
1058  </varlistentry>
1059  <varlistentry>
1060    <term><parameter>name</parameter></term>
1061    <listitem><para>The "C" string name for the device.</para></listitem>
1062  </varlistentry>
1063  <varlistentry>
1064    <term><parameter>dep_name</parameter></term>
1065    <listitem><para>For a layered device, the "C" string name of the
1066    device this device is built upon.</para></listitem>
1067  </varlistentry>
1068  <varlistentry>
1069    <term><parameter>handlers</parameter></term>
1070    <listitem><para>A pointer to the I/O function "handlers" (see below).</para></listitem>
1071  </varlistentry>
1072  <varlistentry>
1073    <term><parameter>init</parameter></term>
1074    <listitem><para>A function called when eCos is initialized. This
1075    function can query the device, setup hardware, etc.</para></listitem>
1076  </varlistentry>
1077  <varlistentry>
1078    <term><parameter>lookup</parameter></term>
1079    <listitem><para>A function called when <function>cyg_io_lookup()</function> is called
1080    for this device. </para></listitem>
1081  </varlistentry>
1082  <varlistentry>
1083    <term><parameter>priv</parameter></term>
1084    <listitem><para>A placeholder for any device specific data
1085    required by the driver.</para></listitem>
1086  </varlistentry>
1087</variablelist>
1088
1089<PARA>The interface to the driver is through the <structfield><!--
1090<index></index> -->handlers</structfield> field.  This is a pointer to
1091a set of functions which implement the various <function>cyg_io_XXX()</function>
1092routines. This table is defined by the macro:</PARA>
1093
1094
1095<PROGRAMLISTING>
1096DEVIO_TABLE(l, write, read, get_config, set_config)
1097</PROGRAMLISTING>
1098
1099<variablelist>
1100<title>Arguments</title>
1101  <varlistentry>
1102    <term><parameter>l</parameter></term>
1103    <listitem><para>The "C" label for this table of handlers.</para></listitem>
1104  </varlistentry>
1105  <varlistentry>
1106    <term>write</term>
1107    <listitem><para>The function called as a result of
1108    <function>cyg_io_write()</function>.</para></listitem>
1109  </varlistentry>
1110  <varlistentry>
1111    <term>read</term>
1112    <listitem><para>The function called as a result of
1113    <function>cyg_io_read()</function>. </para></listitem>
1114  </varlistentry>
1115  <varlistentry>
1116    <term>get_config</term>
1117    <listitem><para>The function called as a result of
1118    <function>cyg_io_get_config()</function>.</para></listitem>
1119  </varlistentry>
1120  <varlistentry>
1121    <term>set_config</term>
1122    <listitem><para>The function called as a result of
1123    <function>cyg_io_set_config()</function>. </para></listitem>
1124  </varlistentry>
1125</variablelist>
1126
1127<PARA>
1128When <EMPHASIS>eCos</EMPHASIS> is initialized (sometimes called
1129&ldquo;boot&rdquo; time), the <function>init()</function> function is called
1130for all devices in the system. The <function>init()</function> function is
1131allowed to return an error in which case the device will be placed
1132&ldquo;off line&rdquo; and all I/O requests to that device will be
1133considered in error.
1134</PARA>
1135
1136<PARA>
1137The <function>lookup()</function> function is called whenever
1138the <FUNCTION>cyg_io_lookup()</FUNCTION> function
1139is called with this device name. The lookup function may cause the device
1140to come &ldquo;on line&rdquo; which would then allow I/O
1141operations to proceed. Future versions of the I/O system
1142will allow for other states, including power saving modes,
1143etc.
1144</PARA>
1145
1146<!-- }}} -->
1147<!-- {{{ How to Write a Serial Hardware Interface Driver -->
1148
1149<SECTION id="io-how-to-write-serial-interface-driver">
1150<TITLE>How to Write a Serial Hardware Interface Driver</TITLE>
1151
1152
1153<PARA>The standard serial driver supplied with
1154<EMPHASIS>eCos</EMPHASIS> is structured as a hardware independent
1155portion and a hardware dependent interface module. To add support for
1156a new serial port, the user should be able to use the existing
1157hardware independent portion and just add their own <!--
1158<index></index> -->interface driver which handles the details of the
1159actual device. The user should have no need to change the hardware
1160independent portion. </PARA>
1161
1162<PARA>The interfaces used by the serial driver and serial implementation
1163modules are contained in the file <filename>&lt;cyg/io/serial.h&gt;</filename>
1164</PARA>
1165
1166<NOTE>
1167<PARA>In the sections below we use the notation &lt;&lt;xx&gt;&gt; to
1168mean a module specific value, referred to as &ldquo;xx&rdquo; below.</PARA>
1169</NOTE>
1170
1171<!-- {{{ DevTab Entry -->
1172
1173<section>
1174<title>DevTab Entry</title>
1175
1176<PARA>The interface module contains the devtab entry (or entries
1177if a single module supports more than one interface). This entry
1178should have the form: </PARA>
1179
1180<PROGRAMLISTING>
1181DEVTAB_ENTRY(&lt;&lt;module_name&gt;&gt;,
1182             &lt;&lt;device_name&gt;&gt;,
1183             0,
1184             &amp;serial_devio,
1185             &lt;&lt;module_init&gt;&gt;,
1186             &lt;&lt;module_lookup&gt;&gt;,
1187             &amp;&lt;&lt;serial_channel&gt;&gt;
1188            );
1189</PROGRAMLISTING>
1190
1191<variablelist>
1192<title>Arguments</title>
1193  <varlistentry>
1194    <term><parameter>module_name</parameter></term>
1195    <listitem><para>The "C" label for this devtab entry</para></listitem>
1196  </varlistentry>
1197  <varlistentry>
1198    <term><parameter>device_name</parameter></term>
1199    <listitem><para>The "C" string for the
1200    device. E.g. <filename>/dev/serial0</filename>.</para></listitem>
1201  </varlistentry>
1202  <varlistentry>
1203    <term><parameter>serial_devio</parameter></term>
1204    <listitem><para>The table of I/O functions. This set is defined in
1205    the hardware independent serial driver and should be used.</para>
1206    </listitem>
1207  </varlistentry>
1208  <varlistentry>
1209    <term><parameter>module_init</parameter></term>
1210    <listitem><para>The module initialization function.</para></listitem>
1211  </varlistentry>
1212  <varlistentry>
1213    <term><parameter>module_lookup</parameter></term>
1214    <listitem><para>The device lookup function. This function
1215    typically sets up the device for actual use, turning on
1216    interrupts, configuring the port, etc.</para></listitem>
1217  </varlistentry>
1218  <varlistentry>
1219    <term><parameter>serial_channel</parameter></term>
1220    <listitem><para>This table (defined below) contains the interface
1221    between the interface module and the serial driver proper.</para></listitem>
1222  </varlistentry>
1223</variablelist>
1224
1225</section>
1226
1227<!-- }}} -->
1228<!-- {{{ Serial Channel Structure -->
1229
1230<section>
1231<title>Serial Channel Structure</title>
1232
1233<PARA>Each serial device must have a &ldquo;serial channel&rdquo;.
1234This is a set of data which describes all operations on the device.
1235It also contains buffers, etc., if the device is to be buffered.
1236The serial channel is created by the macro: </PARA>
1237
1238<PROGRAMLISTING>
1239SERIAL_CHANNEL_USING_INTERRUPTS(l, funs, dev_priv, baud,stop, parity, word_length,
1240                                flags, out_buf, out_buflen, in_buf, in_buflen)
1241</PROGRAMLISTING>
1242
1243<variablelist>
1244  <title>Arguments</title>
1245  <varlistentry>
1246    <term><parameter>l</parameter></term>
1247    <listitem><para>The "C" label for this structure.</para></listitem>
1248  </varlistentry>
1249  <varlistentry>
1250    <term><parameter>funs</parameter></term>
1251    <listitem><para>The set of interface functions (see below).</para></listitem>
1252  </varlistentry>
1253  <varlistentry>
1254    <term><structfield>dev_priv</structfield></term>
1255    <listitem><para>A placeholder for any device specific data for
1256    this channel.</para></listitem>
1257  </varlistentry>
1258  <varlistentry>
1259    <term><structfield>baud</structfield></term>
1260    <listitem><para>The initial baud rate value
1261    (<type>cyg_serial_baud_t</type>).</para></listitem>
1262  </varlistentry>
1263  <varlistentry>
1264    <term><structfield>stop</structfield></term>
1265    <listitem><para>The initial stop bits value
1266    (<type>cyg_serial_stop_bits_t</type>).</para></listitem>
1267  </varlistentry>
1268  <varlistentry>
1269    <term><structfield>parity</structfield></term>
1270    <listitem><para>The initial parity mode value
1271    (<type>cyg_serial_parity_t</type>).</para></listitem>
1272  </varlistentry>
1273  <varlistentry>
1274    <term><structfield>word_length</structfield></term>
1275    <listitem><para>The initial word length value
1276    (<type>cyg_serial_word_length_t</type>).</para></listitem>
1277  </varlistentry>
1278  <varlistentry>
1279    <term><structfield>flags</structfield></term>
1280    <listitem><para>The initial driver flags value.</para></listitem>
1281  </varlistentry>
1282  <varlistentry>
1283    <term><structfield>out_buf</structfield></term>
1284    <listitem><para>Pointer to the output
1285    buffer. <literal>NULL</literal> if none required.</para></listitem>
1286  </varlistentry>
1287  <varlistentry>
1288    <term><structfield>out_buflen</structfield></term>
1289    <listitem><para>The length of the output buffer.</para></listitem>
1290  </varlistentry>
1291  <varlistentry>
1292    <term><structfield>in_buf</structfield></term>
1293    <listitem><para>pointer to the input
1294    buffer. <literal>NULL</literal> if none required.</para></listitem>
1295  </varlistentry>
1296  <varlistentry>
1297    <term><structfield>in_buflen</structfield></term>
1298    <listitem><para>The length of the input buffer. </PARA></listitem>
1299  </varlistentry>
1300</variablelist>
1301
1302<PARA>
1303If either buffer length is zero, no buffering will take place
1304in that direction and only polled mode functions will be used.
1305</PARA>
1306
1307<PARA>
1308The interface from the hardware independent driver into the
1309hardware interface module is contained in the <structfield>funs</structfield> table.
1310This is defined by the macro:
1311</PARA>
1312
1313</section>
1314
1315<!-- }}} -->
1316<!-- {{{ Serial Functions Structure -->
1317
1318<section>
1319<title>Serial Functions Structure</title>
1320
1321<PROGRAMLISTING>
1322SERIAL_FUNS(l, putc, getc, set_config, start_xmit, stop_xmit)
1323</PROGRAMLISTING>
1324
1325
1326<variablelist>
1327  <title>Arguments</title>
1328  <varlistentry>
1329    <term><structfield>l</structfield></term>
1330    <listitem><para>The "C" label for this structure.</para></listitem>
1331  </varlistentry>
1332  <varlistentry>
1333    <term><structfield>putc</structfield></term>
1334    <listitem>
1335      <para><literal>bool (*putc)(serial_channel *priv, unsigned char
1336      c)</literal></para>
1337      <para>
1338      This function sends one character to the interface. It should
1339      return <literal>true</literal> if the character is actually consumed. It should
1340      return <literal>false</literal> if there is no space in the interface
1341      </para>
1342    </listitem>
1343  </varlistentry>
1344  <varlistentry>
1345    <term><structfield>getc</structfield></term>
1346    <listitem>
1347      <para><literal>unsigned char (*getc)(serial_channel *priv)</literal></para>
1348      <para>
1349      This function fetches one character from the interface. It will
1350      be only called in a non-interrupt driven mode, thus it should
1351      wait for a character by polling the device until ready.
1352      </para>
1353    </listitem>
1354  </varlistentry>
1355  <varlistentry>
1356    <term><structfield>set_config</structfield></term>
1357    <listitem>
1358      <para><literal>bool (*set_config)(serial_channel
1359      *priv,cyg_serial_info_t *config)</literal></para>
1360      <para>
1361        This function is used to configure the port. It should return
1362        <literal>true</literal> if the hardware is updated to match the desired
1363        configuration. It should return <literal>false</literal> if the port cannot
1364        support some parameter specified by the given
1365        configuration. E.g. selecting 1.5 stop bits and 8 data bits is
1366        invalid for most serial devices and should not be allowed.
1367      </para>
1368    </listitem>
1369  </varlistentry>
1370  <varlistentry>
1371    <term><parameter>start_xmit</parameter></term>
1372    <listitem><para><literal>void (*start_xmit)(serial_channel *priv)</literal></para>
1373      <para>
1374        In interrupt mode, turn on the transmitter and allow for
1375        transmit interrupts.
1376      </para>
1377    </listitem>
1378  </varlistentry>
1379  <varlistentry>
1380    <term><parameter>stop_xmit</parameter></term>
1381    <listitem>
1382      <para><literal>void (*stop_xmit)(serial_channel *priv)</literal></para>
1383      <para>In interrupt mode, turn off the transmitter.</PARA>
1384    </listitem>
1385  </varlistentry>
1386</variablelist>
1387
1388</section>
1389
1390<!-- }}} -->
1391<!-- {{{ Callbacks -->
1392
1393<section>
1394<title>Callbacks</title>
1395
1396<PARA>
1397The device interface module can execute functions in the
1398hardware independent driver via <literal>chan-&gt;callbacks</literal>.
1399These functions are available:
1400</PARA>
1401
1402<PROGRAMLISTING>
1403void (*serial_init)( serial_channel *chan )
1404</PROGRAMLISTING>
1405
1406<PARA>This function is used to initialize the serial channel. It
1407is only required if the channel is being used in interrupt
1408mode.</PARA>
1409
1410<PROGRAMLISTING>
1411void (*xmt_char)( serial_channel *chan )
1412</PROGRAMLISTING>
1413
1414<PARA>
1415This function would be called from an interrupt handler after a
1416transmit interrupt indicating that additional characters may be
1417sent. The upper driver will call the <function>putc</function>
1418function as appropriate to send more data to the device.</PARA>
1419
1420<PROGRAMLISTING>
1421void (*rcv_char)( serial_channel *chan, unsigned char c )
1422</PROGRAMLISTING>
1423
1424
1425<PARA>
1426This function is used to tell the driver that a character has arrived
1427at the interface. This function is typically called from the interrupt
1428handler. </PARA>
1429
1430<PARA>
1431Furthermore, if the device has a FIFO it should require the hardware
1432independent driver to provide block transfer functionality (driver CDL
1433should include &quot;implements
1434CYGINT_IO_SERIAL_BLOCK_TRANSFER&quot;).  In that case, the following
1435functions are available as well:</PARA>
1436
1437<PROGRAMLISTING>
1438bool (*data_xmt_req)(serial_channel *chan,
1439                     int space,
1440                     int* chars_avail,
1441                     unsigned char** chars)
1442void (*data_xmt_done)(serial_channel *chan)
1443</PROGRAMLISTING>
1444
1445<PARA>
1446Instead of calling <function>xmt_char()</function> to get a single
1447character for transmission at a time, the driver should call
1448<function>data_xmt_req()</function> in a loop, requesting character
1449blocks for transfer. Call with a <parameter>space</parameter> argument of how much space
1450there is available in the FIFO.</PARA>
1451
1452<PARA>If the call returns <literal>true</literal>, the driver can read
1453<parameter>chars_avail</parameter> characters from
1454<parameter>chars</parameter> and copy them into the FIFO.</PARA>
1455
1456<PARA>If the call returns <literal>false</literal>, there are
1457no more buffered characters and the driver should continue without
1458filling up the FIFO.</PARA>
1459
1460<PARA>When all data has been unloaded, the
1461driver must call <function>data_xmt_done()</function>.</PARA>
1462
1463
1464<PROGRAMLISTING>
1465bool (*data_rcv_req)(serial_channel *chan,
1466                     int avail,
1467                     int* space_avail,
1468                     unsigned char** space)
1469void (*data_rcv_done)(serial_channel *chan)
1470</PROGRAMLISTING>
1471
1472<PARA>Instead of calling <function>rcv_char()</function> with a single
1473character at a time, the driver should call
1474<function>data_rcv_req()</function> in a loop, requesting space to
1475unload the FIFO to. <parameter>avail</parameter> is the number of
1476characters the driver wishes to unload.</PARA>
1477
1478
1479<PARA>If the call returns <literal>true</literal>, the driver can copy
1480<parameter>space_avail</parameter> characters to
1481<parameter>space</parameter>. </PARA>
1482
1483
1484<PARA>If the call returns <literal>false</literal>, the input buffer is
1485full. It is up to the driver to decide what to do in that case
1486(callback functions for registering overflow are being planned for
1487later versions of the serial driver).
1488</PARA>
1489
1490<PARA>When all data has been unloaded, the driver must call
1491<function>data_rcv_done()</function>.</PARA>
1492
1493</section>
1494
1495<!-- }}} -->
1496
1497</SECTION>
1498
1499<!-- }}} -->
1500<!-- {{{ Serial Testing -->
1501
1502<section id="io-serial-testing-with-serfilter">
1503<title>Serial testing with ser_filter</title>
1504
1505<!-- {{{ Rationale -->
1506
1507<section id="io-serfilter-rationale">
1508<title>Rationale</title>
1509
1510<para>
1511Since some targets only have one serial connection, a serial testing harness
1512needs to be able to share the connection with <application>GDB</application>
1513(however, the test and <application>GDB</application> can also run on separate
1514lines).
1515</para>
1516
1517<para>
1518The <firstterm>serial filter</firstterm> (<application>ser_filter</application>)
1519sits between the serial port and <application>GDB</application> and monitors
1520the exchange of data between <application>GDB</application> and the target.
1521Normally, no changes are made to the data.
1522</para>
1523
1524<para>
1525When a test request packet is sent from the test on the target, it is
1526intercepted by the filter.
1527</para>
1528
1529<para>
1530The filter and target then enter a loop, exchanging protocol data between
1531them which <application>GDB</application> never sees.
1532</para>
1533
1534<para>
1535In the event of a timeout, or a crash on the target, the filter falls
1536back into its pass-through mode. If this happens due to a crash it should be
1537possible to start regular debugging with <application>GDB</application>. The
1538filter will stay in the pass-though mode until <application>GDB</application>
1539disconnects.
1540</para>
1541</section>
1542
1543<!-- }}} -->
1544<!-- {{{ The Protocol -->
1545
1546<section id="io-serfilter-protocol">
1547<title>The Protocol</title>
1548
1549<para>The protocol commands are prefixed with an <literal>&quot;@&quot;</literal>
1550character which the serial filter is looking for. The protocol
1551commands include:
1552</para>
1553
1554<variablelist>
1555  <varlistentry>
1556    <term><literal>PING</literal></term>
1557    <listitem>
1558      <para>Allows the test on the target to probe for the filter. The
1559      filter responds with <literal>OK</literal>, while
1560      <application>GDB</application> would just ignore the
1561      command. This allows the tests to do nothing if they require the
1562      filter and it is not present.</para>
1563    </listitem>
1564  </varlistentry>
1565  <varlistentry>
1566    <term><literal>CONFIG</literal></term>
1567    <listitem>
1568      <para>Requests a change of serial line configuration. Arguments
1569      to the command specify baud rate, data bits, stop bits, and
1570      parity. [This command is not fully implemented yet - there is no
1571      attempt made to recover if the new configuration turns out to
1572      cause loss of data.]</para>
1573    </listitem>
1574  </varlistentry>
1575  <varlistentry>
1576    <term><literal>BINARY</literal></term>
1577    <listitem>
1578      <para>Requests data to be sent from the filter to the
1579      target. The data is checksummed, allowing errors in the transfer
1580      to be detected.  Sub-options of this command control how the
1581      data transfer is made:</para>
1582      <variablelist>
1583        <varlistentry>
1584          <term><literal>NO_ECHO</literal></term>
1585          <listitem>
1586            <para>(serial driver receive test) Just send data from the
1587            filter to the target. The test verifies the checksum and
1588            PASS/FAIL depending on the result. </para>
1589          </listitem>
1590        </varlistentry>
1591        <varlistentry>
1592          <term><literal>EOP_ECHO</literal></term>
1593          <listitem>
1594            <para>(serial driver half-duplex receive and send test) As
1595            <literal>NO_ECHO</literal> but the test echoes back the
1596            data to the filter.  The filter does a checksum on the
1597            received data and sends the result to the target. The test
1598            PASS/FAIL depending on the result of both checksum
1599            verifications.</para>
1600          </listitem>
1601        </varlistentry>
1602        <varlistentry>
1603          <term><literal>DUPLEX_ECHO</literal></term>
1604          <listitem>
1605            <para>(serial driver duplex receive and send test) Smaller
1606            packets of data are sent back and forth in a pattern that
1607            ensures that the serial driver will be both sending and
1608            receiving at the same time. Again, checksums are computed
1609            and verified resulting in PASS/FAIL.
1610            </para>
1611          </listitem>
1612        </varlistentry>
1613      </variablelist>
1614    </listitem>
1615  </varlistentry>
1616  <varlistentry>
1617    <term><literal>TEXT</literal></term>
1618    <listitem>
1619      <para> This is a test of the text translations in the TTY layer.
1620      Requests a transfer of text data from the target to the filter
1621      and possibly back again. The filter treats this as a binary
1622      transfer, while the target ma be doing translations on the
1623      data. The target provides the filter with checksums for what it
1624      should expect to see. This test is not implemented yet.
1625      </para>
1626    </listitem>
1627  </varlistentry>
1628</variablelist>
1629
1630<para>The above commands may be extended, and new commands added, as
1631required to test (new) parts of the serial drivers in
1632<productname>eCos</productname>.
1633</para>
1634
1635</section>
1636
1637<!-- }}} -->
1638<!-- {{{ The Serial Tests -->
1639
1640<section id="io-serfilter-serial-tests">
1641<title>The Serial Tests</title>
1642
1643<para>
1644The serial tests are built as any other eCos test. After running the
1645<command>make tests</command> command, the tests can be found in
1646<filename>install/tests/io_serial/</filename></para>
1647
1648<variablelist>
1649  <varlistentry>
1650    <term><filename>serial1</filename></term>
1651    <listitem><para>A simple API test.</para></listitem>
1652  </varlistentry>
1653  <varlistentry>
1654    <term><filename>serial2</filename></term>
1655    <listitem>
1656      <para>A simple serial send test. It writes out two strings, one
1657      raw and one encoded as a <application>GDB</application>
1658      O-packet</para>
1659    </listitem>
1660  </varlistentry>
1661  <varlistentry>
1662    <term><filename>serial3</filename> [ requires the serial filter ]</term>
1663    <listitem>
1664      <para>This tests the half-duplex send and receive capabilities
1665      of the serial driver. </para>
1666    </listitem>
1667  </varlistentry>
1668  <varlistentry>
1669    <term><filename>serial4</filename> [ requires the serial filter ]</term>
1670    <listitem>
1671      <para>This test attempts to use a few different serial
1672      configurations, testing the driver's configuration/setup
1673      functionality. </para>
1674    </listitem>
1675  </varlistentry>
1676  <varlistentry>
1677    <term><filename>serial5</filename> [ requires the serial filter ]</term>
1678    <listitem>
1679      <para>This tests the duplex send and receive capabilities of the
1680      serial driver. </para>
1681    </listitem>
1682  </varlistentry>
1683</variablelist>
1684
1685<para>All tests should complete in less than 30 seconds.</para>
1686
1687</section>
1688
1689<!-- }}} -->
1690<!-- {{{ Serial Filter Usage-->
1691
1692<section id="io-serfilter-usage">
1693<title>Serial Filter Usage</title>
1694
1695<para>Running the ser_filter program with no (or wrong) arguments results in
1696the following output:
1697</para>
1698
1699<screen>
1700Usage: ser_filter [-t -S] TcpIPport SerialPort BaudRate
1701or: ser_filter -n [-t -S] SerialPort BaudRate
1702-t: Enable tracing.
1703-S: Output data read from serial line.
1704-c: Output data on console instead of via GDB.
1705-n: No GDB.
1706</screen>
1707
1708<para>The normal way to use it with GDB is to start the filter:</para>
1709
1710<screen>
1711$ <userinput>ser_filter -t 9000 com1 38400</userinput>
1712</screen>
1713
1714<para>
1715In this case, the filter will be listening on port 9000 and connect to the
1716target via the serial port <literal>COM1</literal> at 38400 baud. On a UNIX
1717host, replace "<literal>COM1</literal>" with a device such as
1718"<filename>/dev/ttyS0</filename>".
1719</para>
1720
1721<para>
1722The <option>-t</option> option enables tracing which will cause the
1723filter to describe its actions on the console.
1724</para>
1725
1726<para>Now start <application>GDB</application> with one of the tests as an
1727argument:
1728</para>
1729
1730<screen>
1731$ <userinput>mips-tx39-elf-gdb -nw install/tests/io_serial/serial3</userinput>
1732</screen>
1733
1734<para>Then connect to the filter:</para>
1735
1736<screen>
1737(gdb) <userinput>target remote localhost:9000</userinput>
1738</screen>
1739
1740<para>
1741This should result in a connection in exactly the same way as if you
1742had connected directly to the target on the serial line.
1743</para>
1744
1745<screen>
1746(gdb) <userinput>c</userinput>
1747</screen>
1748
1749<para>
1750Which should result in output similar to the below:
1751</para>
1752
1753<screen>
1754Continuing.
1755INFO: &lt;BINARY:16:1!&gt;
1756PASS: &lt;Binary test completed&gt;
1757INFO: &lt;BINARY:128:1!&gt;
1758PASS: &lt;Binary test completed&gt;
1759INFO: &lt;BINARY:256:1!&gt;
1760PASS: &lt;Binary test completed&gt;
1761INFO: &lt;BINARY:1024:1!&gt;
1762PASS: &lt;Binary test completed&gt;
1763INFO: &lt;BINARY:512:0!&gt;
1764PASS: &lt;Binary test completed&gt;
1765...
1766PASS: &lt;Binary test completed&gt;
1767INFO: &lt;BINARY:16384:0!&gt;
1768PASS: &lt;Binary test completed&gt;
1769PASS: &lt;serial13 test OK&gt;
1770EXIT: &lt;done&gt;
1771</screen>
1772
1773<para>
1774If any of the individual tests fail the testing will terminate with a
1775<computeroutput>FAIL</computeroutput>.
1776</para>
1777
1778<para>
1779With tracing enabled, you would also see the filter's status output:
1780</para>
1781
1782<para>
1783The <literal>PING</literal> command sent from the target to determine the
1784presence of the filter:
1785</para>
1786
1787<screen>
1788[400 11:35:16] Dispatching command PING
1789[400 11:35:16] Responding with status OK
1790</screen>
1791
1792<para>Each of the binary commands result in output similar to:</para>
1793
1794<screen>
1795[400 11:35:16] Dispatching command BINARY
1796[400 11:35:16] Binary data (Size:16, Flags:1).
1797[400 11:35:16] Sending CRC: '170231!', len: 7.
1798[400 11:35:16] Reading 16 bytes from target.
1799[400 11:35:16] Done. in_crc 170231, out_crc 170231.
1800[400 11:35:16] Responding with status OK
1801[400 11:35:16] Received DONE from target.
1802</screen>
1803
1804<para>
1805This tracing output is normally sent as O-packets to <application>GDB
1806</application> which will display the tracing text. By using the
1807<option>-c </option> option, the tracing text can be redirected to the
1808console from which ser_filter was started.
1809</para>
1810
1811</section>
1812
1813<!-- }}} -->
1814<!-- {{{ A Note on Failures -->
1815
1816<section id="io-serfilter-failures">
1817<title>A Note on Failures</title>
1818
1819<para>
1820A serial connection (especially when driven at a high baud rate) can garble the
1821transmitted data because of noise from the environment. It is not the job of
1822the serial driver to ensure data integrity - that is the job of protocols
1823layering on top of the serial driver. </para>
1824
1825<para>In the current implementation the serial tests and the serial filter are
1826not resilient to such data errors. This means that the test may crash or hang
1827(possibly without reporting a <computeroutput>FAIL</computeroutput>). It also
1828means that you should be aware of random errors - a <computeroutput>FAIL
1829</computeroutput> is not necessarily caused by a bug in the serial driver.
1830</para>
1831
1832<para>Ideally, the serial testing infrastructure should be able to distinguish
1833random errors from consistent errors - the former are most likely due to noise
1834in the transfer medium, while the latter are more likely to be caused by faulty
1835drivers. The current implementation of the infrastructure does not have this
1836capability.</para>
1837
1838</section>
1839
1840<!-- }}} -->
1841<!-- {{{ Debugging -->
1842
1843<section id="io-serfilter-debugging">
1844<title>Debugging</title>
1845
1846<para>If a test fails, the serial filter's output may provide some hints about
1847what the problem is. If the option <option>-S</option> is used when starting
1848the filter, data received from the target is printed out:
1849</para>
1850
1851<screen>
1852[400 11:35:16] 0000 50 41 53 53 3a 3c 42 69 'PASS:&lt;Bi'
1853[400 11:35:16] 0008 6e 61 72 79 20 74 65 73 'nary.tes'
1854[400 11:35:16] 0010 74 20 63 6f 6d 70 6c 65 't.comple'
1855[400 11:35:16] 0018 74 65 64 3e 0d 0a 49 4e 'ted&gt;..IN'
1856[400 11:35:16] 0020 46 4f 3a 3c 42 49 4e 41 'FO:&lt;BINA'
1857[400 11:35:16] 0028 52 59 3a 31 32 38 3a 31 'RY:128:1'
1858[400 11:35:16] 0030 21 3e 0d 0a 40 42 49 4e '!..@BIN'
1859[400 11:35:16] 0038 41 52 59 3a 31 32 38 3a 'ARY:128:'
1860[400 11:35:16] 0040 31 21 .. .. .. .. .. .. '1!'
1861</screen>
1862
1863<para>In the case of an error during a testing command the data received by the
1864filter will be printed out, as will the data that was expected. This allows
1865the two data sets to be compared which may give some idea of what the problem
1866is.</para>
1867
1868</section>
1869
1870<!-- }}} -->
1871
1872</section>
1873
1874<!-- }}} -->
1875
1876</chapter>
1877
1878<!-- }}} -->
1879<!-- {{{ Device Driver API -->
1880
1881<CHAPTER id="devapi-device-driver-interface-to-the-kernel">
1882<TITLE>Device Driver Interface to the Kernel</TITLE>
1883
1884<PARA>
1885This chapter describes the API that device drivers may use
1886to interact with the kernel and HAL. It is primarily concerned with
1887the control and management of interrupts and the synchronization of
1888ISRs, DSRs and threads.
1889</PARA>
1890
1891<PARA>
1892The same API will be present in configurations where the kernel
1893is not present. In this case the functions will be supplied by code
1894acting directly on the HAL.
1895</PARA>
1896
1897
1898<!-- {{{ Interrupt Model -->
1899
1900<SECTION id="devapi-interrupt-model">
1901<TITLE>Interrupt Model</TITLE>
1902
1903<PARA>
1904<EMPHASIS>eCos</EMPHASIS> presents a three level interrupt model to
1905<!-- <index></index> -->device drivers. This consists of <!--
1906<index></index> -->Interrupt Service Routines (ISRs) that are invoked
1907in response to a hardware interrupt; <!-- <index></index> -->Deferred
1908Service Routines (DSRs) that are invoked in response to a request by
1909an ISR; and threads that are the clients of the driver. </PARA>
1910
1911<PARA>
1912Hardware interrupts are delivered with minimal intervention to an
1913ISR. The HAL decodes the hardware source of the interrupt and calls
1914the ISR of the attached interrupt object. This ISR may manipulate the
1915hardware but is only allowed to make a restricted set of calls on the
1916driver API. When it returns, an ISR may request that its DSR should be
1917scheduled to run.
1918</PARA>
1919
1920<PARA>
1921A DSR will be run when it is safe to do so without interfering with
1922the scheduler. Most of the time the DSR will run immediately after the
1923ISR, but if the current thread is in the scheduler, it will be delayed
1924until the thread is finished. A DSR is allowed to make a larger set of
1925driver API calls, including, in particular, being able to call
1926<FUNCTION>cyg_drv_cond_signal()</FUNCTION> to wake up waiting
1927threads.
1928</PARA>
1929
1930<PARA>
1931Finally, threads are able to make all API calls and in particular are
1932allowed to wait on mutexes and condition variables. </PARA>
1933
1934
1935<PARA>
1936For a device driver to receive interrupts it must first define ISR and
1937DSR routines as shown below, and then call
1938<FUNCTION>cyg_drv_interrupt_create()</FUNCTION>.  Using the handle
1939returned, the driver must then call
1940<FUNCTION>cyg_drv_interrupt_attach()</FUNCTION> to actually attach the
1941interrupt to the hardware vector.
1942</PARA>
1943
1944
1945</SECTION>
1946
1947<!-- }}} -->
1948<!-- {{{ Synchronization -->
1949
1950<SECTION id="devapi-synchronization">
1951<TITLE><!-- <index></index> -->Synchronization</TITLE>
1952
1953<PARA>There are three levels of synchronization supported:</PARA>
1954
1955<ORDEREDLIST>
1956  <LISTITEM>
1957    <PARA>
1958    Synchronization with ISRs. This normally means disabling
1959    interrupts to prevent the ISR running during a critical
1960    section. In an SMP environment, this will also require the use of
1961    a spinlock to synchronize with ISRs, DSRs or threads running on
1962    other CPUs.  This is implemented by the
1963    <FUNCTION>cyg_drv_isr_lock()</FUNCTION> and
1964    <FUNCTION>cyg_drv_isr_unlock()</FUNCTION> functions. This
1965    mechanism should be used sparingly and for short periods only.
1966    For finer grained synchronization, individual spinlocks are also
1967    supplied.
1968    </PARA>
1969  </LISTITEM>
1970
1971  <LISTITEM>
1972    <PARA>
1973    Synchronization with DSRs. This will be implemented in the kernel
1974    by taking the scheduler lock to prevent DSRs running during
1975    critical sections. In non-kernel configurations it will be
1976    implemented by non-kernel code. This is implemented by the
1977    <FUNCTION>cyg_drv_dsr_lock()</FUNCTION> and
1978    <FUNCTION>cyg_drv_dsr_unlock()</FUNCTION> functions. As with ISR
1979    synchronization, this mechanism should be used sparingly. Only
1980    DSRs and threads may use this synchronization mechanism, ISRs are
1981    not allowed to do this.
1982    </PARA>
1983  </LISTITEM>
1984  <LISTITEM>
1985    <PARA>
1986    Synchronization with threads. This is implemented with mutexes
1987    and condition variables. Only threads may lock the mutexes and
1988    wait on the condition variables, although DSRs may signal
1989    condition variables.
1990    </PARA>
1991  </LISTITEM>
1992</ORDEREDLIST>
1993
1994<PARA>
1995Any data that is accessed from more than one level must be protected
1996against concurrent access. Data that is accessed by ISRs must be
1997protected with the ISR lock, or a spinlock at all times,
1998<emphasis>even in ISRs</emphasis>. Data that is shared between DSRs
1999and threads should be protected with the DSR lock. Data that is only
2000accessed by threads must be protected with mutexes.
2001</PARA>
2002
2003</SECTION>
2004
2005<!-- }}} -->
2006<!-- {{{ SMP Support -->
2007
2008<SECTION id="devapi-smp-support">
2009<TITLE><!-- <index></index> -->SMP Support</TITLE>
2010
2011<para>
2012Some eCos targets contain support for Symmetric Multi-Processing (SMP)
2013configurations, where more than one CPU may be present. This option
2014has a number of ramifications for the way in which device drivers must
2015be written if they are to be SMP-compatible.
2016</para>
2017
2018<para>
2019Since it is possible for the ISR, DSR and thread components of a
2020device driver to execute on different CPUs, it is important that
2021SMP-compatible device drivers use the driver API routines correctly.
2022</para>
2023
2024<para>
2025Synchronization between threads and DSRs continues to require that the
2026thread-side code use <function>cyg_drv_dsr_lock()</function> and
2027<function>cyg_drv_dsr_unlock()</function> to protect access to shared
2028data. While it is not strictly necessary for DSR code to claim the DSR
2029lock, since DSRs are run with it claimed already, it is good practice
2030to do so.
2031</para>
2032
2033<para>
2034Synchronization between ISRs and DSRs or threads requires that access
2035to sensitive data be protected, in all places, by calls to
2036<function>cyg_drv_isr_lock()</function> and
2037<function>cyg_drv_isr_unlock()</function>. Disabling or masking
2038interrupts is not adequate, since the thread or DSR may be running on
2039a different CPU and interrupt enable/disable only work on the current
2040CPU.
2041</para>
2042
2043<para>
2044The ISR lock, for SMP systems, not only disables local interrupts, but
2045also acquires a spinlock to protect against concurrent access from
2046other CPUs. This is necessary because ISRs are not run with the
2047scheduler lock claimed. Hence they can run in parallel with the other
2048components of the device driver.
2049</para>
2050
2051<para>
2052The ISR lock provided by the driver API is just a shared spinlock that
2053is available for use by all drivers. If a driver needs to implement a
2054finer grain of locking, it can use private spinlocks, accessed via the
2055<function>cyg_drv_spinlock_*()</function> functions.
2056</para>
2057
2058</section>
2059
2060<!-- }}} -->
2061<!-- {{{ Device Driver Models -->
2062
2063<SECTION id="devapi-device-driver-models">
2064<TITLE>Device Driver Models</TITLE>
2065
2066<PARA>
2067There are several ways in which <!-- <index></index> -->device drivers
2068may be built. The exact model chosen will depend on the properties of
2069the device and the behavior desired. There are three basic models that
2070may be adopted.
2071</PARA>
2072
2073<PARA>
2074The first model is to do all device processing in the ISR.  When it is
2075invoked the ISR programs the device hardware directly and accesses
2076data to be transferred directly in memory. The ISR should also call
2077<FUNCTION>cyg_drv_interrupt_acknowledge()</FUNCTION>.  When it is
2078finished it may optionally request that its DSR be invoked.  The DSR
2079does nothing but call <FUNCTION>cyg_drv_cond_signal()</FUNCTION> to
2080cause a thread to be woken up. Thread level code must call
2081<FUNCTION>cyg_drv_isr_lock()</FUNCTION>, or
2082<FUNCTION>cyg_drv_interrupt_mask()</FUNCTION> to prevent ISRs running
2083while it manipulates shared memory.
2084</PARA>
2085
2086<PARA>
2087The second model is to defer device processing to the DSR.  The ISR
2088simply prevents further delivery of interrupts by either programming
2089the device, or by calling
2090<FUNCTION>cyg_drv_interrupt_mask()</FUNCTION>.  It must then call
2091<FUNCTION>cyg_drv_interrupt_acknowledge()</FUNCTION> to allow other
2092interrupts to be delivered and then request that its DSR be
2093called. When the DSR runs it does the majority of the device handling,
2094optionally signals a condition variable to wake a thread, and finishes
2095by calling <FUNCTION>cyg_drv_interrupt_unmask()</FUNCTION> to re-allow
2096device interrupts. Thread level code uses
2097<FUNCTION>cyg_drv_dsr_lock()</FUNCTION> to prevent DSRs running while
2098it manipulates shared memory.  The eCos serial device drivers use this
2099approach.
2100</PARA>
2101
2102<PARA>
2103The third model is to defer device processing even further to a
2104thread. The ISR behaves exactly as in the previous model and simply
2105blocks and acknowledges the interrupt before request that the DSR
2106run. The DSR itself only calls
2107<FUNCTION>cyg_drv_cond_signal()</FUNCTION> to wake the thread. When
2108the thread awakens it performs all device processing, and has full
2109access to all kernel facilities while it does so. It should finish by
2110calling <FUNCTION>cyg_drv_interrupt_unmask()</FUNCTION> to re-allow
2111device interrupts.  The eCos ethernet device drivers are written to
2112this model.
2113</PARA>
2114
2115<PARA>
2116The first model is good for devices that need immediate processing and
2117interact infrequently with thread level. The second model trades a
2118little latency in dealing with the device for a less intrusive
2119synchronization mechanism. The last model allows device processing to
2120be scheduled with other threads and permits more complex device
2121handling.
2122</PARA>
2123
2124</SECTION>
2125
2126<!-- }}} -->
2127<!-- {{{ Synchronization Levels -->
2128
2129<SECTION id="devapi-synchronization-levels">
2130<TITLE>Synchronization Levels</TITLE>
2131
2132<PARA>
2133Since it would be dangerous for an ISR or DSR to make a call
2134that might reschedule the current thread (by trying to lock a mutex
2135for example) all functions in this API have an associated synchronization
2136level. These levels are:
2137</PARA>
2138
2139<VARIABLELIST>
2140  <VARLISTENTRY>
2141    <TERM>Thread</TERM>
2142    <LISTITEM>
2143      <PARA>
2144      This function may only be called from within threads. This is
2145      usually the client code that makes calls into the device driver.
2146      In a non-kernel configuration, this will be code running at the
2147      default non-interrupt level.
2148      </PARA>
2149    </LISTITEM>
2150  </VARLISTENTRY>
2151
2152  <VARLISTENTRY>
2153    <TERM>DSR</TERM>
2154    <LISTITEM>
2155      <PARA>
2156      This function may be called by either DSR or thread code.
2157      </PARA>
2158    </LISTITEM>
2159  </VARLISTENTRY>
2160
2161  <VARLISTENTRY>
2162    <TERM>ISR</TERM>
2163    <LISTITEM>
2164      <PARA>
2165      This function may be called from ISR, DSR or thread code.
2166      </PARA>
2167    </LISTITEM>
2168  </VARLISTENTRY>
2169</VARIABLELIST>
2170
2171<PARA>
2172The following table shows, for each API function, the levels
2173at which is may be called:
2174</PARA>
2175
2176<PROGRAMLISTING role="ascii-art">
2177                                  Callable from:
2178Function                       ISR     DSR    Thread
2179-------------------------------------------------------------------------
2180
2181cyg_drv_isr_lock                X       X       X
2182cyg_drv_isr_unlock              X       X       X
2183cyg_drv_spinlock_init                           X
2184cyg_drv_spinlock_destroy                        X
2185cyg_drv_spinlock_spin           X       X       X
2186cyg_drv_spinlock_clear          X       X       X
2187cyg_drv_spinlock_try            X       X       X
2188cyg_drv_spinlock_test           X       X       X
2189cyg_drv_spinlock_spin_intsave   X       X       X
2190cyg_drv_spinlock_clear_intsave  X       X       X
2191cyg_drv_dsr_lock                        X       X
2192cyg_drv_dsr_unlock                      X       X
2193cyg_drv_mutex_init                              X
2194cyg_drv_mutex_destroy                           X
2195cyg_drv_mutex_lock                              X
2196cyg_drv_mutex_trylock                           X
2197cyg_drv_mutex_unlock                            X
2198cyg_drv_mutex_release                           X
2199cyg_drv_cond_init                               X
2200cyg_drv_cond_destroy                            X
2201cyg_drv_cond_wait                               X
2202cyg_drv_cond_signal                     X       X
2203cyg_drv_cond_broadcast                  X       X
2204cyg_drv_interrupt_create                        X
2205cyg_drv_interrupt_delete                        X
2206cyg_drv_interrupt_attach        X       X       X
2207cyg_drv_interrupt_detach        X       X       X
2208cyg_drv_interrupt_mask          X       X       X
2209cyg_drv_interrupt_unmask        X       X       X
2210cyg_drv_interrupt_acknowledge   X       X       X
2211cyg_drv_interrupt_configure     X       X       X
2212cyg_drv_interrupt_level         X       X       X
2213cyg_drv_interrupt_set_cpu       X       X       X
2214cyg_drv_interrupt_get_cpu       X       X       X
2215
2216</PROGRAMLISTING>
2217</SECTION>
2218
2219<!-- }}} -->
2220<!-- {{{ The API -->
2221
2222<SECTION id="devapi-api">
2223<TITLE>The API</TITLE>
2224
2225<PARA>
2226This section details the <!-- <index></index> -->Driver Kernel
2227Interface. Note that most of these functions are identical to Kernel C
2228API calls, and will in most configurations be wrappers for them. In
2229non-kernel configurations they will be supported directly by the HAL,
2230or by code to emulate the required behavior.
2231</PARA>
2232
2233<PARA>This API is defined in the header file
2234<FILENAME>&lt;cyg/hal/drv_api.h&gt;</FILENAME>.
2235</PARA>
2236
2237<!-- {{{ cyg_drv_isr_lock -->
2238
2239<SECTION>
2240<TITLE><!-- <index></index> -->cyg_drv_isr_lock</TITLE>
2241
2242<VARIABLELIST>
2243  <VARLISTENTRY>
2244    <TERM>Function:</TERM>
2245    <LISTITEM>
2246      <programlisting>void cyg_drv_isr_lock()</programlisting>
2247    </LISTITEM>
2248  </VARLISTENTRY>
2249  <VARLISTENTRY>
2250    <TERM>Arguments:</TERM>
2251    <LISTITEM>
2252      <PARA>None</PARA>
2253    </LISTITEM>
2254  </VARLISTENTRY>
2255  <VARLISTENTRY>
2256    <TERM>Result:</TERM>
2257    <LISTITEM>
2258      <PARA>None </PARA>
2259    </LISTITEM>
2260  </VARLISTENTRY>
2261  <VARLISTENTRY>
2262    <TERM>Level:</TERM>
2263    <LISTITEM>
2264      <PARA>ISR</PARA>
2265    </LISTITEM>
2266  </VARLISTENTRY>
2267  <VARLISTENTRY>
2268    <TERM>Description:</TERM>
2269    <LISTITEM>
2270      <PARA>
2271      Disables delivery of interrupts, preventing all ISRs running.  This
2272      function maintains a counter of the number of times it is
2273      called.
2274      </PARA>
2275    </LISTITEM>
2276  </VARLISTENTRY>
2277</VARIABLELIST>
2278</SECTION>
2279
2280<!-- }}} -->
2281<!-- {{{ cyg_drv_isr_unlock -->
2282
2283<SECTION>
2284<TITLE><!-- <index></index> -->cyg_drv_isr_unlock</TITLE>
2285
2286<VARIABLELIST>
2287  <VARLISTENTRY>
2288    <TERM>Function:     </TERM>
2289    <LISTITEM>
2290      <programlisting>void cyg_drv_isr_unlock()</programlisting>
2291    </LISTITEM>
2292  </VARLISTENTRY>
2293  <VARLISTENTRY>
2294    <TERM>Arguments:</TERM>
2295    <LISTITEM>
2296      <PARA>None</PARA>
2297    </LISTITEM>
2298  </VARLISTENTRY>
2299  <VARLISTENTRY>
2300    <TERM>Result:       </TERM>
2301    <LISTITEM>
2302      <PARA>None </PARA>
2303    </LISTITEM>
2304  </VARLISTENTRY>
2305  <VARLISTENTRY>
2306    <TERM>Level:        </TERM>
2307    <LISTITEM>
2308      <PARA>ISR</PARA>
2309    </LISTITEM>
2310  </VARLISTENTRY>
2311  <VARLISTENTRY>
2312    <TERM>Description:  </TERM>
2313    <LISTITEM>
2314      <PARA>Re-enables delivery of interrupts, allowing ISRs to
2315      run. This function decrements the counter maintained by
2316      <FUNCTION>cyg_drv_isr_lock()</FUNCTION>, and only re-allows
2317      interrupts when it goes to zero. </PARA>
2318    </LISTITEM>
2319  </VARLISTENTRY>
2320</VARIABLELIST>
2321
2322</SECTION>
2323
2324<!-- }}} -->
2325<!-- {{{ cyg_drv_spinlock_init -->
2326
2327<SECTION>
2328<TITLE><!-- <index></index> -->cyg_drv_spinlock_init</TITLE>
2329
2330<VARIABLELIST>
2331  <VARLISTENTRY>
2332    <TERM>Function:</TERM>
2333    <LISTITEM>
2334<programlisting>
2335void cyg_drv_spinlock_init(cyg_spinlock_t *lock, cyg_bool_t locked )
2336</programlisting>
2337    </LISTITEM>
2338  </VARLISTENTRY>
2339  <VARLISTENTRY>
2340    <TERM>Arguments:</TERM>
2341    <LISTITEM>
2342      <PARA><parameter>lock</parameter> - pointer to spinlock to initialize</PARA>
2343      <PARA><parameter>locked</parameter> - initial state of lock</PARA>
2344    </LISTITEM>
2345  </VARLISTENTRY>
2346  <VARLISTENTRY>
2347    <TERM>Result:</TERM>
2348    <LISTITEM>
2349      <PARA>None</PARA>
2350    </LISTITEM>
2351  </VARLISTENTRY>
2352  <VARLISTENTRY>
2353    <TERM>Level:</TERM>
2354    <LISTITEM>
2355      <PARA>Thread</PARA>
2356    </LISTITEM>
2357  </VARLISTENTRY>
2358  <VARLISTENTRY>
2359    <TERM>Description:</TERM>
2360    <LISTITEM>
2361      <para>
2362      Initialize a spinlock. The <parameter>locked</parameter>
2363      argument indicates how the spinlock should be initialized:
2364      <literal>TRUE</literal> for locked or <literal>FALSE</literal>
2365      for unlocked state.
2366      </para>
2367    </LISTITEM>
2368  </VARLISTENTRY>
2369</VARIABLELIST>
2370
2371</SECTION>
2372
2373<!-- }}} -->
2374<!-- {{{ cyg_drv_spinlock_destroy -->
2375
2376<SECTION>
2377<TITLE><!-- <index></index> -->cyg_drv_spinlock_destroy</TITLE>
2378
2379<VARIABLELIST>
2380  <VARLISTENTRY>
2381    <TERM>Function:</TERM>
2382    <LISTITEM>
2383      <programlisting>void cyg_drv_spinlock_destroy(cyg_spinlock_t *lock )</programlisting>
2384    </LISTITEM>
2385  </VARLISTENTRY>
2386  <VARLISTENTRY>
2387    <TERM>Arguments:</TERM>
2388    <LISTITEM>
2389      <PARA><parameter>lock</parameter> - pointer to spinlock destroy</PARA>
2390    </LISTITEM>
2391  </VARLISTENTRY>
2392  <VARLISTENTRY>
2393    <TERM>Result:</TERM>
2394    <LISTITEM>
2395      <PARA>None</PARA>
2396    </LISTITEM>
2397  </VARLISTENTRY>
2398  <VARLISTENTRY>
2399    <TERM>Level:</TERM>
2400    <LISTITEM>
2401      <PARA>Thread</PARA>
2402    </LISTITEM>
2403  </VARLISTENTRY>
2404  <VARLISTENTRY>
2405    <TERM>Description:</TERM>
2406    <LISTITEM>
2407      <para>
2408      Destroy a spinlock that is no longer of use. There should be no
2409      CPUs attempting to claim the lock at the time this function is
2410      called, otherwise the behavior is undefined.
2411      </para>
2412    </LISTITEM>
2413  </VARLISTENTRY>
2414</VARIABLELIST>
2415
2416</SECTION>
2417
2418<!-- }}} -->
2419<!-- {{{ cyg_drv_spinlock_spin -->
2420
2421<SECTION>
2422<TITLE><!-- <index></index> -->cyg_drv_spinlock_spin</TITLE>
2423
2424<VARIABLELIST>
2425  <VARLISTENTRY>
2426    <TERM>Function:</TERM>
2427    <LISTITEM>
2428      <programlisting>void cyg_drv_spinlock_spin(cyg_spinlock_t *lock )</programlisting>
2429    </LISTITEM>
2430  </VARLISTENTRY>
2431  <VARLISTENTRY>
2432    <TERM>Arguments:</TERM>
2433    <LISTITEM>
2434      <PARA><parameter>lock</parameter> - pointer to spinlock to claim</PARA>
2435    </LISTITEM>
2436  </VARLISTENTRY>
2437  <VARLISTENTRY>
2438    <TERM>Result:</TERM>
2439    <LISTITEM>
2440      <PARA>None</PARA>
2441    </LISTITEM>
2442  </VARLISTENTRY>
2443  <VARLISTENTRY>
2444    <TERM>Level:</TERM>
2445    <LISTITEM>
2446      <PARA>ISR</PARA>
2447    </LISTITEM>
2448  </VARLISTENTRY>
2449  <VARLISTENTRY>
2450    <TERM>Description:</TERM>
2451    <LISTITEM>
2452      <para>
2453      Claim a spinlock, waiting in a busy loop until it is
2454      available. Wherever this is called from, this operation
2455      effectively pauses the CPU until it succeeds. This operations
2456      should therefore be used sparingly, and in situations where
2457      deadlocks/livelocks cannot occur. Also see
2458      <function>cyg_drv_spinlock_spin_intsave()</function>.
2459      </para>
2460    </LISTITEM>
2461  </VARLISTENTRY>
2462</VARIABLELIST>
2463
2464</SECTION>
2465
2466<!-- }}} -->
2467<!-- {{{ cyg_drv_spinlock_clear -->
2468
2469<SECTION>
2470<TITLE><!-- <index></index> -->cyg_drv_spinlock_clear</TITLE>
2471
2472<VARIABLELIST>
2473  <VARLISTENTRY>
2474    <TERM>Function:</TERM>
2475    <LISTITEM>
2476      <programlisting>void cyg_drv_spinlock_clear(cyg_spinlock_t *lock )</programlisting>
2477    </LISTITEM>
2478  </VARLISTENTRY>
2479  <VARLISTENTRY>
2480    <TERM>Arguments:</TERM>
2481    <LISTITEM>
2482      <PARA><parameter>lock</parameter> - pointer to spinlock to clear </PARA>
2483    </LISTITEM>
2484  </VARLISTENTRY>
2485  <VARLISTENTRY>
2486    <TERM>Result:</TERM>
2487    <LISTITEM>
2488      <PARA>None</PARA>
2489    </LISTITEM>
2490  </VARLISTENTRY>
2491  <VARLISTENTRY>
2492    <TERM>Level:</TERM>
2493    <LISTITEM>
2494      <PARA>ISR</PARA>
2495    </LISTITEM>
2496  </VARLISTENTRY>
2497  <VARLISTENTRY>
2498    <TERM>Description:</TERM>
2499    <LISTITEM>
2500      <para>
2501      Clear a spinlock. This clears the spinlock and allows another
2502      CPU to claim it. If there is more than one CPU waiting in
2503      <function>cyg_drv_spinlock_spin()</function> then just one of
2504      them will be allowed to proceed.
2505      </para>
2506    </LISTITEM>
2507  </VARLISTENTRY>
2508</VARIABLELIST>
2509
2510</SECTION>
2511
2512<!-- }}} -->
2513<!-- {{{ cyg_drv_spinlock_try -->
2514
2515<SECTION>
2516<TITLE><!-- <index></index> -->cyg_drv_spinlock_try</TITLE>
2517
2518<VARIABLELIST>
2519  <VARLISTENTRY>
2520    <TERM>Function:</TERM>
2521    <LISTITEM>
2522      <programlisting>cyg_bool_t cyg_drv_spinlock_try(cyg_spinlock_t *lock )</programlisting>
2523    </LISTITEM>
2524  </VARLISTENTRY>
2525  <VARLISTENTRY>
2526    <TERM>Arguments:</TERM>
2527    <LISTITEM>
2528      <PARA><parameter>lock</parameter> - pointer to spinlock to try</PARA>
2529    </LISTITEM>
2530  </VARLISTENTRY>
2531  <VARLISTENTRY>
2532    <TERM>Result:</TERM>
2533    <LISTITEM>
2534      <PARA><literal>TRUE</literal> if the spinlock was claimed,
2535      <literal>FALSE</literal> otherwise.</PARA>
2536    </LISTITEM>
2537  </VARLISTENTRY>
2538  <VARLISTENTRY>
2539    <TERM>Level:</TERM>
2540    <LISTITEM>
2541      <PARA>ISR</PARA>
2542    </LISTITEM>
2543  </VARLISTENTRY>
2544  <VARLISTENTRY>
2545    <TERM>Description:</TERM>
2546    <LISTITEM>
2547      <para>
2548      Try to claim the spinlock without waiting. If the spinlock could
2549      be claimed immediately then <literal>TRUE</literal> is
2550      returned. If the spinlock is already claimed then the result is
2551      <literal>FALSE</literal>.
2552      </para>
2553    </LISTITEM>
2554  </VARLISTENTRY>
2555</VARIABLELIST>
2556
2557</SECTION>
2558
2559<!-- }}} -->
2560<!-- {{{ cyg_drv_spinlock_test -->
2561
2562<SECTION>
2563<TITLE><!-- <index></index> -->cyg_drv_spinlock_test</TITLE>
2564
2565<VARIABLELIST>
2566  <VARLISTENTRY>
2567    <TERM>Function:</TERM>
2568    <LISTITEM>
2569      <programlisting>cyg_bool_t cyg_drv_spinlock_test(cyg_spinlock_t *lock )</programlisting>
2570    </LISTITEM>
2571  </VARLISTENTRY>
2572  <VARLISTENTRY>
2573    <TERM>Arguments:</TERM>
2574    <LISTITEM>
2575      <PARA><parameter>lock</parameter> - pointer to spinlock to test</PARA>
2576    </LISTITEM>
2577  </VARLISTENTRY>
2578  <VARLISTENTRY>
2579    <TERM>Result:</TERM>
2580    <LISTITEM>
2581      <PARA><literal>TRUE</literal> if the spinlock is available,
2582      <literal>FALSE</literal> otherwise.</PARA>
2583    </LISTITEM>
2584  </VARLISTENTRY>
2585  <VARLISTENTRY>
2586    <TERM>Level:</TERM>
2587    <LISTITEM>
2588      <PARA>ISR</PARA>
2589    </LISTITEM>
2590  </VARLISTENTRY>
2591  <VARLISTENTRY>
2592    <TERM>Description:</TERM>
2593    <LISTITEM>
2594      <para>
2595      Inspect the state of the spinlock. If the spinlock is not locked
2596      then the result is <literal>TRUE</literal>. If it is locked then
2597      the result will be <literal>FALSE</literal>.
2598      </para>
2599    </LISTITEM>
2600  </VARLISTENTRY>
2601</VARIABLELIST>
2602
2603</SECTION>
2604
2605<!-- }}} -->
2606<!-- {{{ cyg_drv_spinlock_spin_intsave -->
2607
2608<SECTION>
2609<TITLE><!-- <index></index> -->cyg_drv_spinlock_spin_intsave</TITLE>
2610
2611<VARIABLELIST>
2612  <VARLISTENTRY>
2613    <TERM>Function:</TERM>
2614    <LISTITEM>
2615<programlisting>
2616void cyg_drv_spinlock_spin_intsave(cyg_spinlock_t *lock,
2617                                   cyg_addrword_t *istate )
2618</programlisting>
2619    </LISTITEM>
2620  </VARLISTENTRY>
2621  <VARLISTENTRY>
2622    <TERM>Arguments:</TERM>
2623    <LISTITEM>
2624      <PARA><parameter>lock</parameter> - pointer to spinlock to claim</PARA>
2625      <PARA><parameter>istate</parameter> - pointer to interrupt state save location</PARA>
2626    </LISTITEM>
2627  </VARLISTENTRY>
2628  <VARLISTENTRY>
2629    <TERM>Result:</TERM>
2630    <LISTITEM>
2631      <PARA>None</PARA>
2632    </LISTITEM>
2633  </VARLISTENTRY>
2634  <VARLISTENTRY>
2635    <TERM>Level:</TERM>
2636    <LISTITEM>
2637      <PARA>ISR</PARA>
2638    </LISTITEM>
2639  </VARLISTENTRY>
2640  <VARLISTENTRY>
2641    <TERM>Description:</TERM>
2642    <LISTITEM>
2643      <para>
2644      This function behaves exactly like
2645      <function>cyg_drv_spinlock_spin()</function> except that it also
2646      disables interrupts before attempting to claim the lock. The
2647      current interrupt enable state is saved in
2648      <parameter>*istate</parameter>. Interrupts remain disabled once
2649      the spinlock had been claimed and must be restored by calling
2650      <function>cyg_drv_spinlock_clear_intsave()</function>.
2651      </para>
2652      <para>
2653      In general, device drivers should use this function to claim and
2654      release spinlocks rather than the
2655      non-<function>_intsave()</function> variants, to ensure proper
2656      exclusion with code running on both other CPUs and this CPU.
2657      </para>
2658    </LISTITEM>
2659  </VARLISTENTRY>
2660</VARIABLELIST>
2661
2662</SECTION>
2663
2664<!-- }}} -->
2665<!-- {{{ cyg_drv_spinlock_clear_intsave -->
2666
2667<SECTION>
2668<TITLE><!-- <index></index> -->cyg_drv_spinlock_clear_intsave</TITLE>
2669
2670<VARIABLELIST>
2671  <VARLISTENTRY>
2672    <TERM>Function:</TERM>
2673    <LISTITEM>
2674<programlisting>
2675void cyg_drv_spinlock_clear_intsave( cyg_spinlock_t *lock,
2676                                     cyg_addrword_t istate )
2677</programlisting>
2678    </LISTITEM>
2679  </VARLISTENTRY>
2680  <VARLISTENTRY>
2681    <TERM>Arguments:</TERM>
2682    <LISTITEM>
2683      <PARA><parameter>lock</parameter> - pointer to spinlock to clear </PARA>
2684      <PARA><parameter>istate</parameter> - interrupt state to restore </PARA>
2685    </LISTITEM>
2686  </VARLISTENTRY>
2687  <VARLISTENTRY>
2688    <TERM>Result:</TERM>
2689    <LISTITEM>
2690      <PARA>None</PARA>
2691    </LISTITEM>
2692  </VARLISTENTRY>
2693  <VARLISTENTRY>
2694    <TERM>Level:</TERM>
2695    <LISTITEM>
2696      <PARA>ISR</PARA>
2697    </LISTITEM>
2698  </VARLISTENTRY>
2699  <VARLISTENTRY>
2700    <TERM>Description:</TERM>
2701    <LISTITEM>
2702      <para>
2703      This function behaves exactly like
2704      <function>cyg_drv_spinlock_clear()</function> except that it
2705      also restores an interrupt state saved by
2706      <function>cyg_drv_spinlock_spin_intsave()</function>. The
2707      <parameter>istate</parameter> argument must have been
2708      initialized by a previous call to
2709      <function>cyg_drv_spinlock_spin_intsave()</function>.
2710      </para>
2711    </LISTITEM>
2712  </VARLISTENTRY>
2713</VARIABLELIST>
2714
2715</SECTION>
2716
2717<!-- }}} -->
2718<!-- {{{ cyg_drv_dsr_lock -->
2719
2720<SECTION>
2721<TITLE><!-- <index></index> -->cyg_drv_dsr_lock</TITLE>
2722
2723<VARIABLELIST>
2724  <VARLISTENTRY>
2725    <TERM>Function:</TERM>
2726    <LISTITEM>
2727      <programlisting>void cyg_drv_dsr_lock()</programlisting>
2728    </LISTITEM>
2729  </VARLISTENTRY>
2730  <VARLISTENTRY>
2731    <TERM>Arguments:</TERM>
2732    <LISTITEM>
2733      <PARA>None</PARA>
2734    </LISTITEM>
2735  </VARLISTENTRY>
2736  <VARLISTENTRY>
2737    <TERM>Result:       </TERM>
2738    <LISTITEM>
2739      <PARA>None </PARA>
2740    </LISTITEM>
2741  </VARLISTENTRY>
2742  <VARLISTENTRY>
2743    <TERM>Level:        </TERM>
2744    <LISTITEM>
2745      <PARA>DSR</PARA>
2746    </LISTITEM>
2747  </VARLISTENTRY>
2748  <VARLISTENTRY>
2749    <TERM>Description:  </TERM>
2750    <LISTITEM>
2751      <PARA>Disables scheduling of DSRs. This function maintains a
2752      counter of the number of times it has been called. </PARA>
2753    </LISTITEM>
2754  </VARLISTENTRY>
2755</VARIABLELIST>
2756</SECTION>
2757
2758<!-- }}} -->
2759<!-- {{{ cyg_drv_dsr_unlock -->
2760
2761<SECTION>
2762<TITLE><!-- <index></index> -->cyg_drv_dsr_unlock</TITLE>
2763
2764<VARIABLELIST>
2765  <VARLISTENTRY>
2766    <TERM>Function:     </TERM>
2767    <LISTITEM>
2768      <programlisting>void cyg_drv_dsr_unlock()</programlisting>
2769    </LISTITEM>
2770  </VARLISTENTRY>
2771  <VARLISTENTRY>
2772    <TERM>Arguments:</TERM>
2773    <LISTITEM>
2774      <PARA>None</PARA>
2775    </LISTITEM>
2776  </VARLISTENTRY>
2777  <VARLISTENTRY>
2778    <TERM>Result:</TERM>
2779    <LISTITEM>
2780      <PARA>            </PARA>
2781      <PARA>None </PARA>
2782    </LISTITEM>
2783  </VARLISTENTRY>
2784  <VARLISTENTRY>
2785    <TERM>Level:</TERM>
2786    <LISTITEM>
2787      <PARA>DSR</PARA>
2788    </LISTITEM>
2789  </VARLISTENTRY>
2790  <VARLISTENTRY>
2791    <TERM>Description:  </TERM>
2792    <LISTITEM>
2793      <PARA>Re-enables scheduling of DSRs. This function decrements
2794      the counter incremented by
2795      <FUNCTION>cyg_drv_dsr_lock()</FUNCTION>.  DSRs are only allowed
2796      to be delivered when the counter goes to zero. </PARA>
2797    </LISTITEM>
2798  </VARLISTENTRY>
2799</VARIABLELIST>
2800</SECTION>
2801
2802<!-- }}} -->
2803<!-- {{{ cyg_drv_mutex_init -->
2804
2805<SECTION>
2806<TITLE><!-- <index></index> -->cyg_drv_mutex_init</TITLE>
2807
2808<VARIABLELIST>
2809  <VARLISTENTRY>
2810    <TERM>Function:     </TERM>
2811    <LISTITEM>
2812      <programlisting>void cyg_drv_mutex_init(cyg_drv_mutex *mutex)</programlisting>
2813    </LISTITEM>
2814  </VARLISTENTRY>
2815  <VARLISTENTRY>
2816    <TERM>Arguments:</TERM>
2817    <LISTITEM>
2818      <PARA><parameter>mutex</parameter> - pointer to mutex to initialize</PARA>
2819    </LISTITEM>
2820  </VARLISTENTRY>
2821  <VARLISTENTRY>
2822    <TERM>Result:       </TERM>
2823    <LISTITEM>
2824      <PARA>None </PARA>
2825    </LISTITEM>
2826  </VARLISTENTRY>
2827  <VARLISTENTRY>
2828    <TERM>Level:        </TERM>
2829    <LISTITEM>
2830      <PARA>Thread</PARA>
2831    </LISTITEM>
2832  </VARLISTENTRY>
2833  <VARLISTENTRY>
2834    <TERM>Description:  </TERM>
2835    <LISTITEM>
2836      <PARA>Initialize the mutex pointed to by the
2837      <literal>mutex</literal> argument. </PARA>
2838    </LISTITEM>
2839  </VARLISTENTRY>
2840</VARIABLELIST>
2841
2842</SECTION>
2843
2844<!-- }}} -->
2845<!-- {{{ cyg_drv_mutex_destroy -->
2846
2847<SECTION>
2848<TITLE><!-- <index></index> -->cyg_drv_mutex_destroy</TITLE>
2849
2850<VARIABLELIST>
2851  <VARLISTENTRY>
2852    <TERM>Function:     </TERM>
2853    <LISTITEM>
2854      <programlisting>void cyg_drv_mutex_destroy( cyg_drv_mutex *mutex )</programlisting>
2855    </LISTITEM>
2856  </VARLISTENTRY>
2857  <VARLISTENTRY>
2858    <TERM>Arguments:</TERM>
2859    <LISTITEM>
2860      <PARA><parameter>mutex</parameter> - pointer to mutex to destroy</PARA>
2861    </LISTITEM>
2862  </VARLISTENTRY>
2863  <VARLISTENTRY>
2864    <TERM>Result:       </TERM>
2865    <LISTITEM>
2866      <PARA>None </PARA>
2867    </LISTITEM>
2868  </VARLISTENTRY>
2869  <VARLISTENTRY>
2870    <TERM>Level:        </TERM>
2871    <LISTITEM>
2872      <PARA>Thread</PARA>
2873    </LISTITEM>
2874  </VARLISTENTRY>
2875  <VARLISTENTRY>
2876    <TERM>Description:  </TERM>
2877    <LISTITEM>
2878      <PARA>Destroy the mutex pointed to by the
2879      <parameter>mutex</parameter> argument. The mutex should be unlocked
2880      and there should be no threads waiting to lock it when this call
2881      in made.</PARA>
2882    </LISTITEM>
2883  </VARLISTENTRY>
2884</VARIABLELIST>
2885
2886</SECTION>
2887
2888<!-- }}} -->
2889<!-- {{{ cyg_drv_mutex_lock -->
2890
2891<SECTION>
2892<TITLE><!-- <index></index> -->cyg_drv_mutex_lock</TITLE>
2893
2894<VARIABLELIST>
2895  <VARLISTENTRY>
2896    <TERM>Function:     </TERM>
2897    <LISTITEM>
2898      <programlisting>cyg_bool cyg_drv_mutex_lock( cyg_drv_mutex *mutex )</programlisting>
2899    </LISTITEM>
2900  </VARLISTENTRY>
2901  <VARLISTENTRY>
2902    <TERM>Arguments:</TERM>
2903    <LISTITEM>
2904      <PARA><parameter>mutex</parameter> - pointer to mutex to lock</PARA>
2905    </LISTITEM>
2906  </VARLISTENTRY>
2907  <VARLISTENTRY>
2908    <TERM>Result:</TERM>
2909    <LISTITEM>
2910      <PARA><literal>TRUE</literal> it the thread has claimed the
2911      lock, <literal>FALSE</literal> otherwise.</PARA>
2912    </LISTITEM>
2913  </VARLISTENTRY>
2914  <VARLISTENTRY>
2915    <TERM>Level:</TERM>
2916    <LISTITEM>
2917      <PARA>Thread</PARA>
2918    </LISTITEM>
2919  </VARLISTENTRY>
2920  <VARLISTENTRY>
2921    <TERM>Description:  </TERM>
2922    <LISTITEM>
2923      <PARA>Attempt to lock the mutex pointed to by the
2924      <parameter>mutex</parameter> argument.  If the mutex is already
2925      locked by another thread then this thread will wait until that
2926      thread is finished. If the result from this function is
2927      <literal>FALSE</literal> then the thread was broken out of its
2928      wait by some other thread. In this case the mutex will not have
2929      been locked. </PARA>
2930    </LISTITEM>
2931  </VARLISTENTRY>
2932</VARIABLELIST>
2933
2934</SECTION>
2935
2936<!-- }}} -->
2937<!-- {{{ cyg_drv_mutex_trylock -->
2938
2939<SECTION>
2940<TITLE><!-- <index></index> -->cyg_drv_mutex_trylock</TITLE>
2941
2942<VARIABLELIST>
2943  <VARLISTENTRY>
2944    <TERM>Function:</TERM>
2945    <LISTITEM>
2946      <PARA><programlisting>cyg_bool cyg_drv_mutex_trylock( cyg_drv_mutex *mutex )</programlisting></PARA>
2947    </LISTITEM>
2948  </VARLISTENTRY>
2949  <VARLISTENTRY>
2950    <TERM>Arguments:</TERM>
2951    <LISTITEM>
2952      <PARA><parameter>mutex</parameter> - pointer to mutex to lock</PARA>
2953    </LISTITEM>
2954  </VARLISTENTRY>
2955  <VARLISTENTRY>
2956    <TERM>Result:</TERM>
2957    <LISTITEM>
2958      <PARA><literal>TRUE</literal> if the mutex has been locked,
2959      <literal>FALSE</literal> otherwise. </PARA>
2960    </LISTITEM>
2961  </VARLISTENTRY>
2962  <VARLISTENTRY>
2963    <TERM>Level:</TERM>
2964    <LISTITEM>
2965      <PARA>Thread</PARA>
2966    </LISTITEM>
2967  </VARLISTENTRY>
2968  <VARLISTENTRY>
2969    <TERM>Description:</TERM>
2970    <LISTITEM>
2971      <PARA>Attempt to lock the mutex pointed to by the
2972      <parameter>mutex</parameter> argument without waiting. If the
2973      mutex is already locked by some other thread then this function
2974      returns <literal>FALSE</literal>. If the function can lock the
2975      mutex without waiting, then <literal>TRUE</literal> is
2976      returned. </PARA>
2977    </LISTITEM>
2978  </VARLISTENTRY>
2979</VARIABLELIST>
2980
2981</SECTION>
2982
2983<!-- }}} -->
2984<!-- {{{ cyg_drv_mutex_unlock -->
2985
2986<SECTION>
2987<TITLE><!-- <index></index> -->cyg_drv_mutex_unlock</TITLE>
2988
2989<VARIABLELIST>
2990  <VARLISTENTRY>
2991    <TERM>Function:     </TERM>
2992    <LISTITEM>
2993      <programlisting>void cyg_drv_mutex_unlock( cyg_drv_mutex *mutex )</programlisting>
2994    </LISTITEM>
2995  </VARLISTENTRY>
2996  <VARLISTENTRY>
2997    <TERM>Arguments:</TERM>
2998    <LISTITEM>
2999      <PARA><parameter>mutex</parameter> - pointer to mutex to unlock</PARA>
3000    </LISTITEM>
3001  </VARLISTENTRY>
3002  <VARLISTENTRY>
3003    <TERM>Result:       </TERM>
3004    <LISTITEM>
3005    <PARA>None </PARA>
3006    </LISTITEM>
3007  </VARLISTENTRY>
3008  <VARLISTENTRY>
3009    <TERM>Level:        </TERM>
3010    <LISTITEM>
3011      <PARA>Thread</PARA>
3012    </LISTITEM>
3013  </VARLISTENTRY>
3014  <VARLISTENTRY>
3015    <TERM>Description:  </TERM>
3016    <LISTITEM>
3017      <PARA>Unlock the mutex pointed to by the
3018      <parameter>mutex</parameter> argument. If there are any threads
3019      waiting to claim the lock, one of them is woken up to try and
3020      claim it. </PARA>
3021    </LISTITEM>
3022  </VARLISTENTRY>
3023</VARIABLELIST>
3024
3025</SECTION>
3026
3027<!-- }}} -->
3028<!-- {{{ cyg_drv_mutex_release -->
3029
3030<SECTION>
3031<TITLE><!-- <index></index> -->cyg_drv_mutex_release</TITLE>
3032
3033<VARIABLELIST>
3034  <VARLISTENTRY>
3035    <TERM>Function:     </TERM>
3036    <LISTITEM>
3037      <programlisting>void cyg_drv_mutex_release( cyg_drv_mutex *mutex )</programlisting>
3038    </LISTITEM>
3039  </VARLISTENTRY>
3040  <VARLISTENTRY>
3041    <TERM>Arguments:</TERM>
3042    <LISTITEM>
3043      <PARA><literal>mutex</literal> - pointer to mutex to release</PARA>
3044    </LISTITEM>
3045  </VARLISTENTRY>
3046  <VARLISTENTRY>
3047    <TERM>Result:       </TERM>
3048    <LISTITEM>
3049      <PARA>None </PARA>
3050    </LISTITEM>
3051  </VARLISTENTRY>
3052  <VARLISTENTRY>
3053    <TERM>Level:        </TERM>
3054    <LISTITEM>
3055      <PARA>Thread</PARA>
3056    </LISTITEM>
3057  </VARLISTENTRY>
3058  <VARLISTENTRY>
3059    <TERM>Description:  </TERM>
3060    <LISTITEM>
3061      <PARA>Release all threads waiting on the mutex pointed to by the
3062      <parameter>mutex</parameter> argument. These threads will return
3063      from <FUNCTION>cyg_drv_mutex_lock()</FUNCTION> with a
3064      <literal>FALSE</literal> result and will not have claimed the
3065      mutex. This function has no effect on any thread that may have
3066      the mutex claimed. </PARA>
3067    </LISTITEM>
3068  </VARLISTENTRY>
3069</VARIABLELIST>
3070
3071</SECTION>
3072
3073<!-- }}} -->
3074<!-- {{{ cyg_drv_cond_init -->
3075
3076<SECTION>
3077<TITLE><!-- <index></index> -->cyg_drv_cond_init</TITLE>
3078
3079<VARIABLELIST>
3080  <VARLISTENTRY>
3081    <TERM>Function:     </TERM>
3082    <LISTITEM>
3083      <programlisting> void cyg_drv_cond_init( cyg_drv_cond *cond, cyg_drv_mutex *mutex )
3084              </programlisting>
3085    </LISTITEM>
3086  </VARLISTENTRY>
3087  <VARLISTENTRY>
3088    <TERM>Arguments:</TERM>
3089    <LISTITEM>
3090      <PARA><parameter>cond</parameter> - condition variable to initialize</PARA>
3091      <PARA><parameter>mutex</parameter> - mutex to associate with this condition variable</PARA>
3092    </LISTITEM>
3093  </VARLISTENTRY>
3094  <VARLISTENTRY>
3095    <TERM>Result:       </TERM>
3096    <LISTITEM>
3097      <PARA>None</PARA>
3098    </LISTITEM>
3099  </VARLISTENTRY>
3100  <VARLISTENTRY>
3101    <TERM>Level:        </TERM>
3102    <LISTITEM>
3103      <PARA>Thread </PARA>
3104    </LISTITEM>
3105  </VARLISTENTRY>
3106  <VARLISTENTRY>
3107    <TERM>Description:  </TERM>
3108    <LISTITEM>
3109      <PARA>Initialize the condition variable pointed to by the
3110      <parameter>cond</parameter> argument.  The
3111      <parameter>mutex</parameter> argument must point to a mutex with
3112      which this condition variable is associated. A thread may only
3113      wait on this condition variable when it has already locked the
3114      associated mutex. Waiting will cause the mutex to be unlocked,
3115      and when the thread is reawakened, it will automatically claim
3116      the mutex before continuing. </PARA>
3117    </LISTITEM>
3118  </VARLISTENTRY>
3119</VARIABLELIST>
3120
3121</SECTION>
3122
3123<!-- }}} -->
3124<!-- {{{ cyg_drv_cond_destroy -->
3125
3126<SECTION>
3127<TITLE><!-- <index></index> -->cyg_drv_cond_destroy</TITLE>
3128
3129<VARIABLELIST>
3130  <VARLISTENTRY>
3131    <TERM>Function:     </TERM>
3132    <LISTITEM>
3133      <programlisting> void cyg_drv_cond_destroy( cyg_drv_cond *cond )</programlisting>
3134    </LISTITEM>
3135  </VARLISTENTRY>
3136  <VARLISTENTRY>
3137    <TERM>Arguments:</TERM>
3138    <LISTITEM>
3139      <PARA><parameter>cond</parameter> - condition variable to destroy</PARA>
3140    </LISTITEM>
3141  </VARLISTENTRY>
3142  <VARLISTENTRY>
3143    <TERM>Result:       </TERM>
3144    <LISTITEM>
3145      <PARA>None </PARA>
3146    </LISTITEM>
3147  </VARLISTENTRY>
3148  <VARLISTENTRY>
3149    <TERM>Level:        </TERM>
3150    <LISTITEM>
3151      <PARA>Thread</PARA>
3152    </LISTITEM>
3153  </VARLISTENTRY>
3154  <VARLISTENTRY>
3155    <TERM>Description:  </TERM>
3156    <LISTITEM>
3157      <PARA>Destroy the condition variable pointed to by the
3158      <parameter>cond</parameter> argument. </PARA>
3159    </LISTITEM>
3160  </VARLISTENTRY>
3161</VARIABLELIST>
3162
3163</SECTION>
3164
3165<!-- }}} -->
3166<!-- {{{ cyg_drv_cond_wait -->
3167
3168<SECTION>
3169<TITLE><!-- <index></index> -->cyg_drv_cond_wait</TITLE>
3170
3171<VARIABLELIST>
3172  <VARLISTENTRY>
3173    <TERM>Function:     </TERM>
3174    <LISTITEM>
3175      <programlisting>void cyg_drv_cond_wait( cyg_drv_cond *cond )</programlisting>
3176    </LISTITEM>
3177  </VARLISTENTRY>
3178  <VARLISTENTRY>
3179    <TERM>Arguments:</TERM>
3180    <LISTITEM>
3181      <PARA><parameter>cond</parameter> - condition variable to wait on</PARA>
3182    </LISTITEM>
3183  </VARLISTENTRY>
3184  <VARLISTENTRY>
3185    <TERM>Result:       </TERM>
3186    <LISTITEM>
3187      <PARA>None </PARA>
3188    </LISTITEM>
3189  </VARLISTENTRY>
3190  <VARLISTENTRY>
3191    <TERM>Level:        </TERM>
3192    <LISTITEM>
3193      <PARA>Thread</PARA>
3194    </LISTITEM>
3195  </VARLISTENTRY>
3196  <VARLISTENTRY>
3197    <TERM>Description:  </TERM>
3198    <LISTITEM>
3199      <PARA>Wait for a signal on the condition variable pointed to by
3200      the <parameter>cond</parameter> argument. The thread must have
3201      locked the associated mutex, supplied in
3202      <function>cyg_drv_cond_init()</function>, before waiting on this
3203      condition variable. While the thread waits, the mutex will be
3204      unlocked, and will be re-locked before this function returns. It
3205      is possible for threads waiting on a condition variable to
3206      occasionally wake up spuriously. For this reason it is necessary
3207      to use this function in a loop that re-tests the condition each
3208      time it returns. Note that this function performs an implicit
3209      scheduler unlock/relock sequence, so that it may be used within
3210      an explicit
3211      <literal>cyg_drv_dsr_lock()...cyg_drv_dsr_unlock()</literal>
3212      structure.</PARA>
3213    </LISTITEM>
3214  </VARLISTENTRY>
3215</VARIABLELIST>
3216
3217</SECTION>
3218
3219<!-- }}} -->
3220<!-- {{{ cyg_drv_cond_signal -->
3221
3222<SECTION>
3223<TITLE><!-- <index></index> -->cyg_drv_cond_signal</TITLE>
3224
3225<VARIABLELIST>
3226  <VARLISTENTRY>
3227    <TERM>Function:     </TERM>
3228    <LISTITEM>
3229      <programlisting>void cyg_drv_cond_signal( cyg_drv_cond *cond )</programlisting>
3230    </LISTITEM>
3231  </VARLISTENTRY>
3232  <VARLISTENTRY>
3233    <TERM>Arguments:</TERM>
3234    <LISTITEM>
3235      <PARA><parameter>cond</parameter> - condition variable to signal</PARA>
3236    </LISTITEM>
3237  </VARLISTENTRY>
3238  <VARLISTENTRY>
3239    <TERM>Result:       </TERM>
3240    <LISTITEM>
3241      <PARA>None </PARA>
3242    </LISTITEM>
3243  </VARLISTENTRY>
3244  <VARLISTENTRY>
3245    <TERM>Level:        </TERM>
3246    <LISTITEM>
3247      <PARA>DSR</PARA>
3248    </LISTITEM>
3249  </VARLISTENTRY>
3250  <VARLISTENTRY>
3251    <TERM>Description:  </TERM>
3252    <LISTITEM>
3253      <PARA>Signal the condition variable pointed to by the <parameter>cond</parameter>
3254      argument.  If there are any threads waiting on this variable at
3255      least one of them will be awakened. Note that in some
3256      configurations there may not be any difference between this
3257      function and <FUNCTION>cyg_drv_cond_broadcast()</FUNCTION>.
3258      </PARA>
3259    </LISTITEM>
3260  </VARLISTENTRY>
3261</VARIABLELIST>
3262
3263</SECTION>
3264
3265<!-- }}} -->
3266<!-- {{{ cyg_drv_cond_broadcast -->
3267
3268<SECTION>
3269<TITLE><!-- <index></index> -->cyg_drv_cond_broadcast</TITLE>
3270
3271<VARIABLELIST>
3272  <VARLISTENTRY>
3273    <TERM>Function:     </TERM>
3274    <LISTITEM>
3275      <programlisting>void cyg_drv_cond_broadcast( cyg_drv_cond *cond )</programlisting>
3276    </LISTITEM>
3277  </VARLISTENTRY>
3278  <VARLISTENTRY>
3279    <TERM>Arguments:</TERM>
3280    <LISTITEM>
3281      <PARA><parameter>cond</parameter> - condition variable to broadcast to</PARA>
3282    </LISTITEM>
3283  </VARLISTENTRY>
3284  <VARLISTENTRY>
3285    <TERM>Result:       </TERM>
3286    <LISTITEM>
3287      <PARA>None </PARA>
3288    </LISTITEM>
3289  </VARLISTENTRY>
3290  <VARLISTENTRY>
3291    <TERM>Level:        </TERM>
3292    <LISTITEM>
3293      <PARA>DSR</PARA>
3294    </LISTITEM>
3295  </VARLISTENTRY>
3296  <VARLISTENTRY>
3297    <TERM>Description:  </TERM>
3298    <LISTITEM>
3299      <PARA>Signal the condition variable pointed to by the
3300      <parameter>cond</parameter> argument.  If there are any threads
3301      waiting on this variable they will all be awakened. </PARA>
3302    </LISTITEM>
3303  </VARLISTENTRY>
3304</VARIABLELIST>
3305
3306</SECTION>
3307
3308<!-- }}} -->
3309<!-- {{{ cyg_drv_interrupt_create -->
3310
3311<SECTION>
3312<TITLE><!-- <index></index> -->cyg_drv_interrupt_create</TITLE>
3313
3314<VARIABLELIST>
3315  <VARLISTENTRY>
3316    <TERM>Function:     </TERM>
3317    <LISTITEM>
3318<PROGRAMLISTING>
3319void cyg_drv_interrupt_create( cyg_vector_t vector,
3320                               cyg_priority_t priority,
3321                               cyg_addrword_t data,
3322                               cyg_ISR_t *isr,
3323                               cyg_DSR_t *dsr,
3324                               cyg_handle_t *handle,
3325                               cyg_interrupt *intr
3326                             )
3327</PROGRAMLISTING>
3328    </LISTITEM>
3329  </VARLISTENTRY>
3330  <VARLISTENTRY>
3331    <TERM>Arguments:</TERM>
3332    <LISTITEM>
3333      <PARA><parameter>vector</parameter> - vector to attach to</PARA>
3334      <PARA><parameter>priority</parameter> - queuing priority</PARA>
3335      <PARA><parameter>data</parameter> - data pointer</PARA>
3336      <PARA><parameter>isr</parameter> - interrupt service routine</PARA>
3337      <PARA><parameter>dsr</parameter> - deferred service routine</PARA>
3338      <PARA><parameter>handle</parameter> - returned handle</PARA>
3339      <PARA><parameter>intr</parameter> - put interrupt object here</PARA>
3340    </LISTITEM>
3341  </VARLISTENTRY>
3342  <VARLISTENTRY>
3343    <TERM>Result:       </TERM>
3344    <LISTITEM>
3345      <PARA>None</PARA>
3346    </LISTITEM>
3347  </VARLISTENTRY>
3348  <VARLISTENTRY>
3349    <TERM>Level:        </TERM>
3350    <LISTITEM>
3351      <PARA>Thread</PARA>
3352    </LISTITEM>
3353  </VARLISTENTRY>
3354  <VARLISTENTRY>
3355    <TERM>Description:  </TERM>
3356    <LISTITEM>
3357      <PARA>Create an interrupt object and returns a handle to it. The
3358      object contains information about which interrupt vector to use
3359      and the ISR and DSR that will be called after the interrupt
3360      object is attached to the vector. The interrupt object will be
3361      allocated in the memory passed in the
3362      <parameter>intr</parameter> parameter. The interrupt object is
3363      not immediately attached; it must be attached with the
3364      <FUNCTION>cyg_interrupt_attach()</FUNCTION> call. </PARA>
3365    </LISTITEM>
3366  </VARLISTENTRY>
3367</VARIABLELIST>
3368</SECTION>
3369
3370<!-- }}} -->
3371<!-- {{{ cyg_drv_interrupt_delete -->
3372
3373<SECTION>
3374<TITLE><!-- <index></index> -->cyg_drv_interrupt_delete</TITLE>
3375
3376<VARIABLELIST>
3377  <VARLISTENTRY>
3378    <TERM>Function:     </TERM>
3379    <LISTITEM>
3380      <programlisting> void cyg_drv_interrupt_delete( cyg_handle_t interrupt )</programlisting>
3381    </LISTITEM>
3382  </VARLISTENTRY>
3383  <VARLISTENTRY>
3384    <TERM>Arguments:</TERM>
3385    <LISTITEM>
3386      <PARA><parameter>interrupt</parameter> - interrupt to delete</PARA>
3387    </LISTITEM>
3388  </VARLISTENTRY>
3389  <VARLISTENTRY>
3390    <TERM>Result:       </TERM>
3391    <LISTITEM>
3392      <PARA>None </PARA>
3393    </LISTITEM>
3394  </VARLISTENTRY>
3395  <VARLISTENTRY>
3396    <TERM>Level:        </TERM>
3397    <LISTITEM>
3398      <PARA>Thread</PARA>
3399    </LISTITEM>
3400  </VARLISTENTRY>
3401  <VARLISTENTRY>
3402    <TERM>Description:  </TERM>
3403    <LISTITEM>
3404      <PARA>Detach the interrupt from the vector and free the memory
3405      passed in the <parameter>intr</parameter> argument to
3406      <FUNCTION>cyg_drv_interrupt_create()</FUNCTION> for
3407      reuse. </PARA>
3408    </LISTITEM>
3409  </VARLISTENTRY>
3410</VARIABLELIST>
3411
3412</SECTION>
3413
3414<!-- }}} -->
3415<!-- {{{ cyg_drv_interrupt_attach -->
3416
3417<SECTION>
3418<TITLE><!-- <index></index> -->cyg_drv_interrupt_attach</TITLE>
3419
3420<VARIABLELIST>
3421  <VARLISTENTRY>
3422    <TERM>Function:     </TERM>
3423    <LISTITEM>
3424      <programlisting>void cyg_drv_interrupt_attach( cyg_handle_t interrupt )</programlisting>
3425    </LISTITEM>
3426  </VARLISTENTRY>
3427  <VARLISTENTRY>
3428    <TERM>Arguments:</TERM>
3429    <LISTITEM>
3430      <PARA><parameter>interrupt</parameter> - interrupt to attach</PARA>
3431    </LISTITEM>
3432  </VARLISTENTRY>
3433  <VARLISTENTRY>
3434    <TERM>Result:       </TERM>
3435    <LISTITEM>
3436      <PARA>None </PARA>
3437    </LISTITEM>
3438  </VARLISTENTRY>
3439  <VARLISTENTRY>
3440    <TERM>Level:        </TERM>
3441    <LISTITEM>
3442      <PARA>ISR</PARA>
3443    </LISTITEM>
3444  </VARLISTENTRY>
3445  <VARLISTENTRY>
3446    <TERM>Description:  </TERM>
3447    <LISTITEM>
3448      <PARA>Attach the interrupt to the vector so that interrupts will
3449      be delivered to the ISR when the interrupt occurs. </PARA>
3450    </LISTITEM>
3451  </VARLISTENTRY>
3452</VARIABLELIST>
3453</SECTION>
3454
3455<!-- }}} -->
3456<!-- {{{ cyg_drv_interrupt_detach -->
3457
3458<SECTION>
3459<TITLE><!-- <index></index> -->cyg_drv_interrupt_detach</TITLE>
3460
3461<VARIABLELIST>
3462  <VARLISTENTRY>
3463    <TERM>Function:     </TERM>
3464    <LISTITEM>
3465      <programlisting>void cyg_drv_interrupt_detach( cyg_handle_t interrupt )</programlisting>
3466    </LISTITEM>
3467  </VARLISTENTRY>
3468  <VARLISTENTRY>
3469    <TERM>Arguments:</TERM>
3470    <LISTITEM>
3471      <PARA><parameter>interrupt</parameter> - interrupt to detach</PARA>
3472    </LISTITEM>
3473  </VARLISTENTRY>
3474  <VARLISTENTRY>
3475    <TERM>Result:       </TERM>
3476    <LISTITEM>
3477      <PARA>None </PARA>
3478    </LISTITEM>
3479  </VARLISTENTRY>
3480  <VARLISTENTRY>
3481    <TERM>Level:        </TERM>
3482    <LISTITEM>
3483      <PARA>ISR</PARA>
3484    </LISTITEM>
3485  </VARLISTENTRY>
3486  <VARLISTENTRY>
3487    <TERM>Description:  </TERM>
3488    <LISTITEM>
3489      <PARA>Detach the interrupt from the vector so that interrupts
3490      will no longer be delivered to the ISR. </PARA>
3491    </LISTITEM>
3492  </VARLISTENTRY>
3493</VARIABLELIST>
3494
3495</SECTION>
3496
3497<!-- }}} -->
3498<!-- {{{ cyg_drv_interrupt_mask -->
3499
3500<SECTION>
3501<TITLE><!-- <index></index> -->cyg_drv_interrupt_mask</TITLE>
3502
3503<VARIABLELIST>
3504  <VARLISTENTRY>
3505    <TERM>Function:     </TERM>
3506    <LISTITEM>
3507      <programlisting>void cyg_drv_interrupt_mask(cyg_vector_t vector )</programlisting>
3508    </LISTITEM>
3509  </VARLISTENTRY>
3510  <VARLISTENTRY>
3511    <TERM>Arguments:</TERM>
3512    <LISTITEM>
3513      <PARA><parameter>vector</parameter> - vector to mask</PARA>
3514    </LISTITEM>
3515  </VARLISTENTRY>
3516  <VARLISTENTRY>
3517    <TERM>Result:       </TERM>
3518    <LISTITEM>
3519      <PARA>None </PARA>
3520    </LISTITEM>
3521  </VARLISTENTRY>
3522  <VARLISTENTRY>
3523    <TERM>Level:        </TERM>
3524    <LISTITEM>
3525      <PARA>ISR</PARA>
3526    </LISTITEM>
3527  </VARLISTENTRY>
3528  <VARLISTENTRY>
3529    <TERM>Description:  </TERM>
3530    <LISTITEM>
3531      <PARA>Program the interrupt controller to stop delivery of
3532      interrupts on the given vector. On architectures which implement
3533      interrupt priority levels this may also disable all lower
3534      priority interrupts. </PARA>
3535    </LISTITEM>
3536  </VARLISTENTRY>
3537</VARIABLELIST>
3538</SECTION>
3539
3540<!-- }}} -->
3541<!-- {{{ cyg_drv_interrupt_mask_intunsafe -->
3542
3543<SECTION>
3544<TITLE><!-- <index></index> -->cyg_drv_interrupt_mask_intunsafe</TITLE>
3545
3546<VARIABLELIST>
3547  <VARLISTENTRY>
3548    <TERM>Function:     </TERM>
3549    <LISTITEM>
3550      <programlisting>void cyg_drv_interrupt_mask_intunsafe(cyg_vector_t vector )</programlisting>
3551    </LISTITEM>
3552  </VARLISTENTRY>
3553  <VARLISTENTRY>
3554    <TERM>Arguments:</TERM>
3555    <LISTITEM>
3556      <PARA><parameter>vector</parameter> - vector to mask</PARA>
3557    </LISTITEM>
3558  </VARLISTENTRY>
3559  <VARLISTENTRY>
3560    <TERM>Result:       </TERM>
3561    <LISTITEM>
3562      <PARA>None </PARA>
3563    </LISTITEM>
3564  </VARLISTENTRY>
3565  <VARLISTENTRY>
3566    <TERM>Level:        </TERM>
3567    <LISTITEM>
3568      <PARA>ISR</PARA>
3569    </LISTITEM>
3570  </VARLISTENTRY>
3571  <VARLISTENTRY>
3572    <TERM>Description:  </TERM>
3573    <LISTITEM>
3574      <PARA>Program the interrupt controller to stop delivery of
3575      interrupts on the given vector. On architectures which implement
3576      interrupt priority levels this may also disable all lower
3577      priority interrupts. This version differs from
3578      <function>cyg_drv_interrupt_mask()</function> in not being
3579      interrupt safe. So in situations where, for example, interrupts
3580      are already known to be disabled, this may be called to avoid
3581      the extra overhead.</PARA>
3582    </LISTITEM>
3583  </VARLISTENTRY>
3584</VARIABLELIST>
3585</SECTION>
3586
3587<!-- }}} -->
3588<!-- {{{ cyg_drv_interrupt_unmask -->
3589
3590<SECTION>
3591<TITLE><!-- <index></index> -->cyg_drv_interrupt_unmask</TITLE>
3592
3593<VARIABLELIST>
3594  <VARLISTENTRY>
3595    <TERM>Function:     </TERM>
3596    <LISTITEM>
3597      <programlisting>void cyg_drv_interrupt_unmask(cyg_vector_t vector )</programlisting>
3598    </LISTITEM>
3599  </VARLISTENTRY>
3600  <VARLISTENTRY>
3601    <TERM>Arguments:</TERM>
3602    <LISTITEM>
3603      <PARA><parameter>vector</parameter> - vector to unmask</PARA>
3604    </LISTITEM>
3605  </VARLISTENTRY>
3606  <VARLISTENTRY>
3607    <TERM>Result:       </TERM>
3608    <LISTITEM>
3609      <PARA>None </PARA>
3610    </LISTITEM>
3611  </VARLISTENTRY>
3612  <VARLISTENTRY>
3613    <TERM>Level:        </TERM>
3614    <LISTITEM>
3615      <PARA>ISR</PARA>
3616    </LISTITEM>
3617  </VARLISTENTRY>
3618  <VARLISTENTRY>
3619    <TERM>Description:  </TERM>
3620    <LISTITEM>
3621      <PARA>Program the interrupt controller to re-allow delivery of
3622      interrupts on the given <parameter>vector</parameter>. </PARA>
3623    </LISTITEM>
3624  </VARLISTENTRY>
3625</VARIABLELIST>
3626</SECTION>
3627
3628<!-- }}} -->
3629<!-- {{{ cyg_drv_interrupt_unmask_intunsafe -->
3630
3631<SECTION>
3632<TITLE><!-- <index></index> -->cyg_drv_interrupt_unmask_intunsafe</TITLE>
3633
3634<VARIABLELIST>
3635  <VARLISTENTRY>
3636    <TERM>Function:     </TERM>
3637    <LISTITEM>
3638      <programlisting>void cyg_drv_interrupt_unmask_intunsafe(cyg_vector_t vector )</programlisting>
3639    </LISTITEM>
3640  </VARLISTENTRY>
3641  <VARLISTENTRY>
3642    <TERM>Arguments:</TERM>
3643    <LISTITEM>
3644      <PARA><parameter>vector</parameter> - vector to unmask</PARA>
3645    </LISTITEM>
3646  </VARLISTENTRY>
3647  <VARLISTENTRY>
3648    <TERM>Result:       </TERM>
3649    <LISTITEM>
3650      <PARA>None </PARA>
3651    </LISTITEM>
3652  </VARLISTENTRY>
3653  <VARLISTENTRY>
3654    <TERM>Level:        </TERM>
3655    <LISTITEM>
3656      <PARA>ISR</PARA>
3657    </LISTITEM>
3658  </VARLISTENTRY>
3659  <VARLISTENTRY>
3660    <TERM>Description:  </TERM>
3661    <LISTITEM>
3662      <PARA>Program the interrupt controller to re-allow delivery of
3663      interrupts on the given <parameter>vector</parameter>. This
3664      version differs from
3665      <function>cyg_drv_interrupt_unmask()</function> in not being
3666      interrupt safe.</PARA>
3667    </LISTITEM>
3668  </VARLISTENTRY>
3669</VARIABLELIST>
3670</SECTION>
3671
3672<!-- }}} -->
3673<!-- {{{ cyg_drv_interrupt_acknowledge -->
3674
3675<SECTION>
3676<TITLE><!-- <index></index> -->cyg_drv_interrupt_acknowledge</TITLE>
3677
3678<VARIABLELIST>
3679  <VARLISTENTRY>
3680    <TERM>Function:     </TERM>
3681    <LISTITEM>
3682      <programlisting>void cyg_drv_interrupt_acknowledge( cyg_vector_t vector )</programlisting>
3683    </LISTITEM>
3684  </VARLISTENTRY>
3685  <VARLISTENTRY>
3686    <TERM>Arguments:</TERM>
3687    <LISTITEM>
3688      <PARA><parameter>vector</parameter> - vector to acknowledge</PARA>
3689    </LISTITEM>
3690  </VARLISTENTRY>
3691  <VARLISTENTRY>
3692    <TERM>Result:       </TERM>
3693    <LISTITEM>
3694      <PARA>None </PARA>
3695    </LISTITEM>
3696  </VARLISTENTRY>
3697  <VARLISTENTRY>
3698    <TERM>Level:        </TERM>
3699    <LISTITEM>
3700      <PARA>ISR</PARA>
3701    </LISTITEM>
3702  </VARLISTENTRY>
3703  <VARLISTENTRY>
3704    <TERM>Description:  </TERM>
3705    <LISTITEM>
3706      <PARA>Perform any processing required at the interrupt
3707      controller and in the CPU to cancel the current interrupt
3708      request on the <parameter>vector</parameter>. An ISR may also
3709      need to program the hardware of the device to prevent an
3710      immediate re-triggering of the interrupt. </PARA>
3711    </LISTITEM>
3712  </VARLISTENTRY>
3713</VARIABLELIST>
3714</SECTION>
3715
3716<!-- }}} -->
3717<!-- {{{ cyg_drv_interrupt_configure -->
3718
3719<SECTION>
3720<TITLE><!-- <index></index> -->cyg_drv_interrupt_configure</TITLE>
3721
3722<VARIABLELIST>
3723  <VARLISTENTRY>
3724    <TERM>Function:     </TERM>
3725    <LISTITEM>
3726      <PROGRAMLISTING>
3727void cyg_drv_interrupt_configure( cyg_vector_t vector,
3728                                  cyg_bool_t level,
3729                                  cyg_bool_t up
3730                                )
3731</PROGRAMLISTING>
3732    </LISTITEM>
3733  </VARLISTENTRY>
3734  <VARLISTENTRY>
3735    <TERM>Arguments:</TERM>
3736    <LISTITEM>
3737      <PARA><parameter>vector</parameter> - vector to configure</PARA>
3738      <PARA><parameter>level</parameter> - level or edge triggered</PARA>
3739      <PARA><parameter>up</parameter> - rising/falling edge, high/low level</PARA>
3740    </LISTITEM>
3741  </VARLISTENTRY>
3742  <VARLISTENTRY>
3743    <TERM>Result:       </TERM>
3744    <LISTITEM>
3745      <PARA>None</PARA>
3746    </LISTITEM>
3747  </VARLISTENTRY>
3748  <VARLISTENTRY>
3749    <TERM>Level:        </TERM>
3750    <LISTITEM>
3751      <PARA>ISR</PARA>
3752    </LISTITEM>
3753  </VARLISTENTRY>
3754  <VARLISTENTRY>
3755    <TERM>Description:  </TERM>
3756    <LISTITEM>
3757      <PARA>Program the interrupt controller with the characteristics
3758      of the interrupt source. The <parameter>level</parameter>
3759      argument chooses between level- or edge-triggered
3760      interrupts. The <parameter>up</parameter> argument chooses
3761      between high and low level for level triggered interrupts or
3762      rising and falling edges for edge triggered interrupts. This
3763      function only works with interrupt controllers that can control
3764      these parameters. </PARA>
3765    </LISTITEM>
3766  </VARLISTENTRY>
3767</VARIABLELIST>
3768
3769</SECTION>
3770
3771<!-- }}} -->
3772<!-- {{{ cyg_drv_interrupt_level -->
3773
3774<SECTION>
3775<TITLE><!-- <index></index> -->cyg_drv_interrupt_level</TITLE>
3776
3777<VARIABLELIST>
3778  <VARLISTENTRY>
3779    <TERM>Function:     </TERM>
3780    <LISTITEM>
3781<PROGRAMLISTING>
3782void cyg_drv_interrupt_level( cyg_vector_t vector,
3783                              cyg_priority_t level
3784                            )
3785</PROGRAMLISTING>
3786    </LISTITEM>
3787  </VARLISTENTRY>
3788  <VARLISTENTRY>
3789    <TERM>Arguments:</TERM>
3790    <LISTITEM>
3791      <PARA><parameter>vector</parameter> - vector to configure</PARA>
3792      <PARA><parameter>level</parameter> - level to set</PARA>
3793    </LISTITEM>
3794  </VARLISTENTRY>
3795  <VARLISTENTRY>
3796    <TERM>Result:       </TERM>
3797    <LISTITEM>
3798      <PARA>None </PARA>
3799    </LISTITEM>
3800  </VARLISTENTRY>
3801  <VARLISTENTRY>
3802    <TERM>Level:        </TERM>
3803    <LISTITEM>
3804      <PARA>ISR</PARA>
3805    </LISTITEM>
3806  </VARLISTENTRY>
3807  <VARLISTENTRY>
3808    <TERM>Description:  </TERM>
3809    <LISTITEM>
3810      <PARA>Program the interrupt controller to deliver the given
3811       interrupt at the supplied priority level. This function only
3812       works with interrupt controllers that can control this
3813       parameter.</PARA>
3814    </LISTITEM>
3815  </VARLISTENTRY>
3816</VARIABLELIST>
3817
3818</SECTION>
3819
3820<!-- }}} -->
3821<!-- {{{ cyg_drv_interrupt_set_cpu -->
3822
3823<SECTION>
3824<TITLE><!-- <index></index> -->cyg_drv_interrupt_set_cpu</TITLE>
3825
3826<VARIABLELIST>
3827  <VARLISTENTRY>
3828    <TERM>Function:</TERM>
3829    <LISTITEM>
3830<PROGRAMLISTING>
3831void cyg_drv_interrupt_set_cpu( cyg_vector_t vector,
3832                                cyg_cpu_t cpu
3833                              )
3834</PROGRAMLISTING>
3835    </LISTITEM>
3836  </VARLISTENTRY>
3837  <VARLISTENTRY>
3838    <TERM>Arguments:</TERM>
3839    <LISTITEM>
3840      <PARA><parameter>vector</parameter> - interrupt vector to route</PARA>
3841      <PARA><parameter>cpu</parameter> - destination CPU</PARA>
3842    </LISTITEM>
3843  </VARLISTENTRY>
3844  <VARLISTENTRY>
3845    <TERM>Result:</TERM>
3846    <LISTITEM>
3847      <PARA>None</PARA>
3848    </LISTITEM>
3849  </VARLISTENTRY>
3850  <VARLISTENTRY>
3851    <TERM>Level:</TERM>
3852    <LISTITEM>
3853      <PARA>ISR</PARA>
3854    </LISTITEM>
3855  </VARLISTENTRY>
3856  <VARLISTENTRY>
3857    <TERM>Description:  </TERM>
3858    <LISTITEM>
3859      <PARA>
3860      This function causes all interrupts on the given vector to be
3861      routed to the specified CPU. Subsequently, all such interrupts
3862      will be handled by that CPU. This only works if the underlying
3863      hardware is capable of performing this kind of routing. This
3864      function does nothing on a single CPU system.
3865      </PARA>
3866    </LISTITEM>
3867  </VARLISTENTRY>
3868</VARIABLELIST>
3869
3870</SECTION>
3871
3872<!-- }}} -->
3873<!-- {{{ cyg_drv_interrupt_get_cpu -->
3874
3875<SECTION>
3876<TITLE><!-- <index></index> -->cyg_drv_interrupt_get_cpu</TITLE>
3877
3878<VARIABLELIST>
3879  <VARLISTENTRY>
3880    <TERM>Function:</TERM>
3881    <LISTITEM>
3882<PROGRAMLISTING>
3883cyg_cpu_t cyg_drv_interrupt_set_cpu( cyg_vector_t vector )
3884</PROGRAMLISTING>
3885    </LISTITEM>
3886  </VARLISTENTRY>
3887  <VARLISTENTRY>
3888    <TERM>Arguments:</TERM>
3889    <LISTITEM>
3890      <PARA><parameter>vector</parameter> - interrupt vector to query</PARA>
3891    </LISTITEM>
3892  </VARLISTENTRY>
3893  <VARLISTENTRY>
3894    <TERM>Result:</TERM>
3895    <LISTITEM>
3896      <PARA>The CPU to which this vector is routed</PARA>
3897    </LISTITEM>
3898  </VARLISTENTRY>
3899  <VARLISTENTRY>
3900    <TERM>Level:</TERM>
3901    <LISTITEM>
3902      <PARA>ISR</PARA>
3903    </LISTITEM>
3904  </VARLISTENTRY>
3905  <VARLISTENTRY>
3906    <TERM>Description:  </TERM>
3907    <LISTITEM>
3908      <PARA>
3909      In multi-processor systems this function returns the id of the
3910      CPU to which interrupts on the given vector are current being
3911      delivered. In single CPU systems this function returns zero.
3912      </PARA>
3913    </LISTITEM>
3914  </VARLISTENTRY>
3915</VARIABLELIST>
3916
3917</SECTION>
3918
3919<!-- }}} -->
3920<!-- {{{ cyg_ISR_t -->
3921
3922<SECTION>
3923<TITLE><!-- <index></index> -->cyg_ISR_t</TITLE>
3924
3925<VARIABLELIST>
3926  <VARLISTENTRY>
3927    <TERM>Type:         </TERM>
3928    <LISTITEM>
3929<PROGRAMLISTING>
3930typedef cyg_uint32 cyg_ISR_t( cyg_vector_t vector,
3931                              cyg_addrword_t data
3932                            )
3933</PROGRAMLISTING>
3934    </LISTITEM>
3935  </VARLISTENTRY>
3936  <VARLISTENTRY>
3937    <TERM>Fields:</TERM>
3938    <LISTITEM>
3939      <PARA><parameter>vector</parameter> - vector being delivered</PARA>
3940      <PARA><parameter>data</parameter> - data value supplied by client</PARA>
3941    </LISTITEM>
3942  </VARLISTENTRY>
3943  <VARLISTENTRY>
3944    <TERM>Result:       </TERM>
3945    <LISTITEM>
3946      <PARA>Bit mask indicating whether interrupt was handled and
3947      whether the DSR should be called. </PARA>
3948    </LISTITEM>
3949  </VARLISTENTRY>
3950  <VARLISTENTRY>
3951    <TERM>Description:  </TERM>
3952    <LISTITEM>
3953      <PARA>Interrupt Service Routine definition. A pointer to a
3954      function with this prototype is passed to
3955      <FUNCTION>cyg_interrupt_create()</FUNCTION> when an interrupt
3956      object is created. When an interrupt is delivered the function
3957      will be called with the vector number and the data value that
3958      was passed to <FUNCTION>cyg_interrupt_create()</FUNCTION>.
3959      </PARA>
3960      <PARA>The return value is a bit mask containing one or both of the
3961      following bits: </PARA>
3962      <variablelist>
3963        <VARLISTENTRY>
3964          <TERM>CYG_ISR_HANDLED         </TERM>
3965          <LISTITEM>
3966            <PARA>indicates that the interrupt was handled by this
3967            ISR. It is a configuration option whether this will
3968            prevent further ISR being run. </PARA>
3969          </LISTITEM>
3970        </VARLISTENTRY>
3971        <VARLISTENTRY>
3972          <TERM>CYG_ISR_CALL_DSR        </TERM>
3973          <LISTITEM>
3974            <PARA>causes the DSR that was passed to
3975            <FUNCTION>cyg_interrupt_create()</FUNCTION> to be
3976            scheduled to be called.</PARA>
3977          </LISTITEM>
3978        </VARLISTENTRY>
3979      </variablelist>
3980    </LISTITEM>
3981  </VARLISTENTRY>
3982</VARIABLELIST>
3983
3984</SECTION>
3985
3986<!-- }}} -->
3987<!-- {{{ cyg_DSR_t -->
3988
3989<SECTION>
3990<TITLE><!-- <index></index> -->cyg_DSR_t</TITLE>
3991
3992<VARIABLELIST>
3993  <VARLISTENTRY>
3994    <TERM>Type:         </TERM>
3995    <LISTITEM>
3996<PROGRAMLISTING>
3997typedef void cyg_DSR_t( cyg_vector_t vector,
3998                        cyg_ucount32 count,
3999                        cyg_addrword_t data
4000                      )
4001</PROGRAMLISTING>
4002    </LISTITEM>
4003  </VARLISTENTRY>
4004  <VARLISTENTRY>
4005    <TERM>Fields:</TERM>
4006    <LISTITEM>
4007      <PARA><parameter>vector</parameter> - vector being delivered</PARA>
4008      <PARA><parameter>count</parameter> - number of times DSR has been scheduled</PARA>
4009      <PARA><parameter>data</parameter> - data value supplied by client</PARA>
4010    </LISTITEM>
4011  </VARLISTENTRY>
4012  <VARLISTENTRY>
4013    <TERM>Result:       </TERM>
4014    <LISTITEM>
4015      <PARA>None</PARA>
4016    </LISTITEM>
4017  </VARLISTENTRY>
4018  <VARLISTENTRY>
4019    <TERM>Description:  </TERM>
4020    <LISTITEM>
4021      <PARA>Deferred Service Routine prototype. A pointer to a
4022      function with this prototype is passed to
4023      <FUNCTION>cyg_interrupt_create()</FUNCTION> when an interrupt
4024      object is created. When the ISR requests the scheduling of its
4025      DSR, this function will be called at some later point. In
4026      addition to the <parameter>vector</parameter> and
4027      <parameter>data</parameter> arguments, which will be the same as
4028      those passed to the ISR, this routine is also passed a
4029      <parameter>count</parameter> of the number of times the ISR has
4030      requested that this DSR be scheduled.  This counter is zeroed
4031      each time the DSR actually runs, so it indicates how many
4032      interrupts have occurred since it last ran.</PARA>
4033    </LISTITEM>
4034  </VARLISTENTRY>
4035</VARIABLELIST>
4036
4037</SECTION>
4038
4039<!-- }}} -->
4040
4041</SECTION>
4042
4043<!-- }}} -->
4044
4045</CHAPTER>
4046
4047<!-- }}} -->
4048
4049
4050</PART>
Note: See TracBrowser for help on using the repository browser.