From: Ian Abbott Date: Wed, 9 May 2012 14:50:17 +0000 (+0100) Subject: doc/driverwriting.xml: Various changes. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=4a6276c257637b189e419f2da90f6f078bf3cecc;p=comedilib.git doc/driverwriting.xml: Various changes. Some DocBook mark-up changes. Also avoided absolute path-names for sources as people tend to put them in different places! Also changed instructions for submitting drivers for review. --- diff --git a/doc/driverwriting.xml b/doc/driverwriting.xml index 2ed32e6..12cfb06 100644 --- a/doc/driverwriting.xml +++ b/doc/driverwriting.xml @@ -11,13 +11,13 @@ Writing a &comedi; driver -This Section explains the most important implementations aspects of +This section explains the most important implementations aspects of the &comedi; device drivers. It tries to give the interested device driver writer an overview of the different steps required to write a new device driver. -This Section does not explain all implementation +This section does not explain all implementation details of the &comedi; software itself: &comedi; has once and for all solved lots of boring but indispensable infrastructural things, such as: timers, management of which drivers @@ -36,8 +36,8 @@ know the answers to the following questions: How does the -communication between user space -and kernel space work? +communication between user-space +and kernel-space work? @@ -74,13 +74,13 @@ manufacturers all use their own design and nomenclature.
-Communication user space-kernel space +Communication user-space — kernel-space -In user space, you interact with the functions implemented in the -/usr/src/comedilib directory. Most -of the device driver core of the Comedilib library is found in +In user-space, you interact with the functions implemented in the +Comedilib library. +Most of the device driver core of the Comedilib library is found in lib subdirectory. @@ -89,27 +89,27 @@ All user-space &comedi; commands are transmitted to kernel space through a traditional ioctl system call. -(See /usr/src/comedilib/lib/ioctl.c.) -The user space information command is encoded as +(See lib/ioctl.c in Comedilib.) +The user-space information command is encoded as a number in the ioctl call, and decoded in the -kernel space library. There, they are executed by their kernel-space +kernel-space library. There, they are executed by their kernel-space counterparts. This is done in the -/usr/src/comedi/comedi/comedi_fops.c file: the -comedi_ioctl() function processes the results of +comedi_fops.c file in the Comedi sources: the +comedi_unlocked_ioctl function processes the results of the ioctl system call, interprets its contents, -and then calls the corresponding kernel space +and then calls the corresponding kernel-space do_…_ioctl function(s). For example, a &comedi; instruction is further processed -by the do_insn_ioctl()function. (Which, in turn, -uses parse_insn() for further detailed processing.) +by the do_insn_ioctl function. (Which, in turn, +uses parse_insn for further detailed processing.) The data corresponding to instructions and commands is transmitted -with the copy_from_user() system call; -acquisition data captured by the interface card passes the kernel-user -space boundary with the help of a copy_to_user() -system call. +with the copy_from_user function; +acquisition data captured by the interface card passes the +kernel/user-space boundary with the help of a copy_to_user +function.
@@ -144,7 +144,7 @@ RTLinux/Free, and spinlocks for atomic sections. include/linux/comedilib.h: the header file for -the kernel library of &comedi;. +the kernel library of &comedi; (kcomedilib module). @@ -152,9 +152,7 @@ the kernel library of &comedi;.
From all the relevant &comedi; device driver code that is found in the -/usr/src/comedi/comedi directory -(if the &comedi; source has been installed in its -normal /usr/src/comedi location), +comedi kernel module source directory, the generic functionality is contained in two parts: @@ -180,11 +178,11 @@ interface accessible through the There are some differences in what is possible and/or needed -in kernel space and in user space, so the functionalities offered in +in kernel-space and in user-space, so the functionalities offered in kcomedilib are not an exact copy of the user-space library. For example, locking, interrupt handling, real-time execution, callback handling, etc., are only available in -kernel space. +kernel-space. Most drivers don't make use (yet) of these real-time functionalities. @@ -211,11 +209,11 @@ typedef struct comedi_async_struct comedi_async< typedef struct comedi_driver_struct comedi_driver; They can be found in -/usr/src/comedi/include/linux/comedidev.h. +include/linux/comedidev.h. Most of the fields are filled in by the &comedi; infrastructure, but there are still quite a handful that your driver must provide or use. As for the user-level &comedi;, each of the hierarchical layers has -its own data structures: channel (comedi_lrange), +its own data structures: range (comedi_lrange), subdevice, and device. @@ -227,9 +225,9 @@ different meaning: they encode the interaction with the hardware, not with the user. -However, the comedi_insn -and comedi_cmd -data structures are shared between user space and kernel space: this +However, the comedi_insn +and comedi_cmd +data structures are shared between user-space and kernel-space: this should come as no surprise, since these data structures contain all information that the user-space program must transfer to the kernel-space driver for each acquisition. @@ -239,17 +237,17 @@ In addition to these data entities that are also known at the user level (device, sub-device, channel), the device driver level provides two more data structures which the application programmer doesn't get in touch with: the data structure -comedi_driver +comedi_driver that stores the device driver information that is relevant at the operating system level, and the data structure -comedi_async that stores the +comedi_async that stores the information about all asynchronous activities (interrupts, callbacks and events).
-<function>comedi_lrange</function> +<type>comedi_lrange</type> The channel information is simple, since it contains only the signal @@ -267,7 +265,7 @@ struct comedi_lrange_struct{
-<function>comedi_subdevice</function> +<type>comedi_subdevice</type> The subdevice is the smallest &comedi; entity that can be used for @@ -317,8 +315,8 @@ struct comedi_subdevice_struct{ unsigned int state; }; -The function pointers (*insn_read) … -(*cancel) . +The function pointers insn_read … +cancel . offer (pointers to) the standardized user-visible API that every subdevice should offer; every device driver has to fill @@ -327,12 +325,12 @@ in these functions with their board-specific implementations. definition, not show up in the device driver data structures.) -The buf_change() and munge() -functions offer functionality that is not visible to the user and for +The buf_change and munge +function pointers offer functionality that is not visible to the user and for which the device driver writer must provide a board-specific implementation: -buf_change() is called when a change in the -data buffer requires handling; munge() transforms +buf_change is called when a change in the +data buffer requires handling; munge transforms different bit-representations of DAQ values, for example from unsigned to 2's complement. @@ -341,7 +339,7 @@ different bit-representations of DAQ values, for example from
-<function>comedi_device</function> +<type>comedi_device</type> @@ -386,7 +384,7 @@ struct comedi_device_struct{
-<function>comedi_async</function> +<type>comedi_async</type> @@ -433,7 +431,7 @@ struct comedi_async_struct{
-<function>comedi_driver</function> +<type>comedi_driver</type> @@ -512,7 +510,7 @@ Board-specific functionality -The /usr/src/comedi/comedi/drivers +The comedi/drivers subdirectory contains the board-specific device driver code. Each new card must get an entry in this directory. @@ -558,7 +556,7 @@ all properties of a device and its subdevices are defined, and filled in in the generic &comedi; data structures. As part of this, pointers to the low level instructions being supported by the subdevice have to be set, which define the basic functionality. In somewhat more detail, -the mydriver_attach() function must: +the mydriver_attach function must: @@ -585,15 +583,15 @@ hardware FIFO, etc.). -return 1, indicating success. If there were any errors along the way, -you should return the appropriate error number. If an error is -returned, the mydriver_detach() function is -called. The mydriver_detach() function should +return 1, indicating success. If there were any errors along the way, +you should return the appropriate (negative) error number. If an error is +returned, the mydriver_detach function is +called. The mydriver_detach function should check any resources that may have been allocated and release them as necessary. The &comedi; core frees -dev->subdevices and -dev->private, so this does not need to be done in -detach. +dev->subdevices and +dev->private, so this does not need to be done in +mydriver_detach. @@ -609,7 +607,7 @@ handling routines, and/or callback routines. Typically, you will be able to implement most of the above-mentioned functionality by cut-and-paste from already existing drivers. The -mydriver_attach() function needs most of your +mydriver_attach function needs most of your attention, because it must correctly define and allocate the (private and generic) data structures that are needed for this device. That is, each sub-device and each channel must get appropriate data fields, and @@ -618,16 +616,17 @@ an appropriate initialization. The good news, of course, is that well with almost all DAQ functionalities found on interface cards. These can be found in the header files of the -/usr/src/comedi/include/linux/ +include/linux/ directory. -Drivers for digital IOs should implement the following functions: +Drivers with digital I/O subdevices should implement the following functions, +setting the function pointers in the comedi_subdevice: -insn_bits(): drivers set this if they have a +insn_bits: drivers set this if they have a function that supports reading and writing multiple bits in a digital I/O subdevice at the same time. Most (if not all) of the drivers use this interface instead of insn_read and insn_write for DIO subdevices. @@ -636,7 +635,7 @@ this interface instead of insn_read and insn_write for DIO subdevices. -insn_config(): implements INSN_CONFIG +insn_config: implements INSN_CONFIG instructions. Currently used for configuring the direction of digital I/O lines, although will eventually be used for generic configuration of drivers that is outside the scope of the currently defined &comedi; @@ -646,27 +645,28 @@ interface. Finally, the device driver writer must implement the -read and write functions for +insn_read and insn_write functions for the analog channels on the card: -insn_read(): acquire the inputs on the board and +insn_read: acquire the inputs on the board and transfer them to the software buffer of the driver. -insn_write(): transfer data from the software +insn_write: transfer data from the software buffer to the card, and execute the appropriate output conversions. In some drivers, you want to catch interrupts, and/or want to use the -INSN_INTTRIG instruction. In this +INSN_INTTRIG +instruction. In this case, you must provide and register these callback functions. @@ -722,7 +722,7 @@ hardware interrupt routine. Another driver-supplied callback function is executed when the user -program launches an INSN_INTTRIG +program launches an INSN_INTTRIG instruction. This event handling is executed synchronously with the execution of the triggering instruction. @@ -741,14 +741,14 @@ statements such as this one: s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR It fills in the bits corresponding to particular events in the -comedi_async data structure. +comedi_async data structure. The possible event bits are: -COMEDI_CB_EOA: execute the callback at the +COMEDI_CB_EOA: execute the callback at the End-Of-Acquisition (or End-Of-Output). @@ -756,7 +756,7 @@ The possible event bits are: -COMEDI_CB_EOS: execute the callback at the +COMEDI_CB_EOS: execute the callback at the End-Of-Scan. @@ -764,7 +764,7 @@ The possible event bits are: -COMEDI_CB_OVERFLOW: execute the callback when a +COMEDI_CB_OVERFLOW: execute the callback when a buffer overflow or underflow has occurred. @@ -772,7 +772,7 @@ buffer overflow or underflow has occurred. -COMEDI_CB_ERROR: execute the callback at the +COMEDI_CB_ERROR: execute the callback at the occurrence of an (undetermined) error. @@ -819,9 +819,10 @@ and has no interrupts available. Drivers are to have absolutely no -global variables, mainly because the existence of global variables +global variables (apart from read-only, constant data, or data structures +shared by all devices), mainly because the existence of global variables immediately negates any possibility of using the driver for two -devices. The pointer dev->private should be used +devices. The pointer dev->private should be used to point to a structure containing any additional variables needed by a driver/device combination. @@ -830,9 +831,9 @@ a driver/device combination. Drivers should report errors and warnings via the -comedi_error() function. +comedi_error function. (This is not the same function as the user-space -comedi_perror() function.) +comedi_perror function.) @@ -860,14 +861,14 @@ that you call it mydriver.c -Put your new driver into comedi/drivers/mydriver.c. +Put your new driver into comedi/drivers/mydriver.c. -Edit comedi/drivers/Makefile.am and add mydriver.ko -to the module_PROGRAMS list. Also add a line +Edit comedi/drivers/Makefile.am and add mydriver.ko +to the module_PROGRAMS list. Also add a line mydriver_ko_SOURCES = mydriver.c @@ -877,10 +878,10 @@ in the alphabetically appropriate place. -Run ./autogen.sh in the top-level comedi directory. You will +Run ./autogen.sh in the top-level comedi directory. You will need to have (a recent version of) autoconf and automake -installed to successfully run autogen.sh. Afterwards, your driver will -be built along with the rest of the drivers when you 'make'. +installed to successfully run autogen.sh. Afterwards, your driver will +be built along with the rest of the drivers when you run make. @@ -888,10 +889,11 @@ be built along with the rest of the drivers when you 'make'. If you want to have your driver included in the &comedi; distribution (you definitely want to :-) ) send it to -David Schleef
ds@schleef.org
or -Frank Hess
fmhess@users.sourceforge.net
-for review and integration. Note your work must be licensed under terms -compatible with the GNU GPL to be distributed as a part of Comedi. +the &comedi; mailing list +for review and integration. See the top-level README +for details of the &comedi; mailing list.) +Note your work must be licensed under terms +compatible with the GNU GPL to be distributed as a part of &comedi;.