]> rtime.felk.cvut.cz Git - mf6xx.git/commitdiff
rtlws: Minor fixes.
authorRostislav Lisovy <lisovy@gmail.com>
Wed, 14 Sep 2011 16:04:09 +0000 (18:04 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Wed, 14 Sep 2011 16:04:09 +0000 (18:04 +0200)
doc/rtlws_article/paper.tex

index 9f3a63ebd4844e99045c9e7bc22af58881f5335e..11ac8d59b05231e674a3bbeccd19de9ee792b095 100755 (executable)
@@ -108,7 +108,7 @@ lisovy@gmail.com\\
 %% ABSTRACT (REQUIRED)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \begin{abstract}
-The article describes implementation of UIO and Comedi drivers for Humusoft MF624 and MF614 cards. Basic functions (D/A, A/D converters, digital inputs/outputs) of Humusoft MF624 card were implemented into the Qemu emulator as well which enables to experiment with drivers implementation without physical access to the cards and risk of data lost when drivers are developed and tested on same primary Linux kernel instance. %The article can help newcomers in the area to gain knowledge required to implement support for other similar cards and these cards hardware emulation. The matching real and virtual setup can be used in operating system courses for practical introduction to simple drivers implementation and helps with understanding internal computation world with real world computers interfacing.
+The article describes implementation of UIO and Comedi drivers for Humusoft MF624 and MF614 cards. Basic functions (D/A, A/D converters, digital inputs/outputs) of Humusoft MF624 card were implemented into the Qemu emulator as well which enables to experiment with drivers implementation without physical access to the cards and risk of data lost when drivers are developed and tested on same primary Linux kernel instance. The article can help newcomers in the area to gain knowledge required to implement support for other similar cards and these cards hardware emulation. The matching real and virtual setup can be used in operating system courses for practical introduction to simple drivers implementation and helps with understanding internal computation world with real world computers interfacing.
 \end{abstract}
 
 \vspace{10mm}
@@ -119,7 +119,7 @@ The article describes implementation of UIO and Comedi drivers for Humusoft MF62
 %% SECTION (REQUIRED)
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Introduction}
-When teaching development of Linux drivers one of the approaches is to explain kernel API and programming paradigms by creating driver which doesn't require some special hardware -- e.g. character driver which returns upper case ASCII text when receiving lower case. Although this approach can be useful, the issues associated with dealing with hardware should be practices as well.
+When teaching development of Linux drivers one of the approaches is to explain kernel API and programming paradigms by creating driver which doesn't require some special hardware -- e.g. character driver which returns upper case ASCII text when receiving lower case. Although this approach can be useful, the issues associated with dealing with hardware should be practised as well.
 
 The approach we took in this work eliminates the need of physical access to hardware whereas it provides full feature set of PCI device in form of virtual hardware. This was possible by implementing virtual PCI device into Qemu emulator.
 
@@ -168,14 +168,14 @@ In case of writing UIO driver for PCI device, initialization function of the mod
 26 | uio_register_device(&dev->dev, info);
 27 | pci_set_drvdata(dev, info);
 \end{verbatim}
-Structure \texttt{uio\_mem} is used for enabling memory-mapped I/O regions (MMIO), whereas structure \texttt{uio\_port} is used for port-mapped I/O (PMIO).
+Structure \texttt{uio\_mem} is used for enabling memory-mapped I/O regions, whereas structure \texttt{uio\_port} is used for I/O ports.
 
 \subsection*{Driver \texttt{uio\_pci\_generic}}
 When dealing with any device compliant to PCI 2.3, it is also possible to use \texttt{uio\_pci\_generic} driver in kernel instead of programming specific one. This driver makes all memory regions of the device available to user-space.
 
 Binding to the device is done by writing Vendor and Device ID into \texttt{/sys/bus/pci/drivers/ uio\_pci\_generic/new\_id} file.
 
-Interrupt handler uses Interrupt Disable bit in the PCI command register and Interrupt Status bit in the PCI status register. Because none (FIXME any?) of MF614 or MF624 are PCI 2.3 compliant it is not possible to use this driver for them.
+Interrupt handler uses Interrupt Disable bit in the PCI command register and Interrupt Status bit in the PCI status register. Because neither of MF614 or MF624 is PCI 2.3 compliant it is not possible to use this driver for them.
 
 \subsection*{Interface to user-space}
 Communication with kernel part of the UIO driver is possible through \texttt{/dev/uioX} file (where X is number of instance of driver). There are several syscalls possible to use when interfacing with this file:
@@ -183,18 +183,18 @@ Communication with kernel part of the UIO driver is possible through \texttt{/de
 \item[\texttt{open()}] opens the device, returns file descriptor used for another syscalls.
 \item[\texttt{read()}] blocks until an interrupt occurs (the value read is number of interrupts seen by device).
 \item[\texttt{mmap()}] is used to map devices memory to user-space. The offset value passed to \texttt{mmap()} de\-ter\-mines the memory area of a device to map -- for \textit{n-th} area offset should be \textit{n*\texttt{sysconf( \_SC\_PAGESIZE)}}.
-\item[\texttt{irqcontrol()}] is used for enabling (called with parameter \texttt{(int) 1}) or disabling (parameter \texttt{(int) 0}) interrupts.
+\item[\texttt{irqcontrol()}] is used for enabling (called with parameter set to \texttt{(int) 1}) or disabling (\texttt{(int) 0}) interrupts.
 \end{description}
 It is possible to define your own \texttt{mmap()}, \texttt{open()}, \texttt{release()} functions as an option. When there is need to use \texttt{irqcontrol()}, it is necessary to implement this function per device.
 
-When using UIO and \texttt{mmap()} with MF624 card (which has 32 or 128 bytes long memory regions) there is an issue with the return value of this syscall -- the pointer to the memory seems to be page-size-aligned, so it was necessary to add low bits of physical address of each memory region to it. FIXME
+Information related to particular driver instance can be found in \texttt{/sys/class/uio/uioX} directory. Most of the files are read-only. The subdirectory \texttt{maps} contains information about MMIO regions mapped by the driver, subdirectory \texttt{portio} is for I/O port regions. 
 
-Another way how to gain information from some UIO driver is by reading \texttt{/sys/class/uio/uioX}. Most of the files are read-only. The subdirectory \texttt{maps} contains information about MMIO regions mapped by the driver, subdirectory \texttt{portio} is for PMIO. 
+When using UIO and \texttt{mmap()} with MF624 card (which has 32 or 128 bytes long memory regions) there is an issue with the return value of this syscall -- the pointer to the memory is page-size-aligned, so it is necessary to add low bits of physical address (page offset) of each memory region to it. Physical address can be obtained from \texttt{addr} file located in \texttt{/sys/class/uio/uioX/maps/mapX}. Region offset is equal to \texttt{addr \& (sysconf(\_SC\_PAGESIZE) - 1)}.
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Comedi driver}
-UIO driver is versatile solution available mainly for uncommon devices. In our case of using DAQ card a special subsystem in Linux kernel designated for DAQ cards drivers can be used. It is called Comedi (\textit{Linux control and measurement device interface}). It provides library functions for user- and kernel-space making development and usage of DAQ devices easier. It consists of:
+UIO driver is versatile solution available mainly for uncommon devices. In our case of using DAQ card a special subsystem in Linux kernel designated for DAQ cards drivers can be used. It is called Comedi (\textit{Linux control and measurement device interface}). It provides library functions for user- and kernel-space making development and usage of DAQ devices easier. It is build of three different parts.
 \begin{description}
 \item[Comedi] is part of Linux kernel. It consist of individual device drivers including Comedi driver providing basic set of functions used by device drivers.
 \item[Comedilib] is user-space library providing unified interface for another user-space application to devices supported by Comedi.
@@ -202,7 +202,7 @@ UIO driver is versatile solution available mainly for uncommon devices. In our c
 \end{description}
 
 \subsection*{Implementing the driver}
-Each Comedi driver should register to the list of active Comedi drivers. This is done by invoking \texttt{comedi\_driver\_register()} function. The only parameter passed to this function is pointer to \texttt{struct comedi\_driver} structure. The most important fields of this structure are:
+Each Comedi driver should be registered to the list of active Comedi drivers. This is done by invoking \texttt{comedi\_driver\_register()} function. The only parameter passed to this function is pointer to \texttt{struct comedi\_driver} structure. The most important fields of this structure are:
 \begin{verbatim}
 const char *driver_name; /* "my_driver" */
 struct module *module;   /* THIS_MODULE */
@@ -212,7 +212,7 @@ int (*detach) (struct comedi_device *);
 \end{verbatim}
 Unlike the UIO or generic PCI driver, the main \textit{initialization function} is not \texttt{probe()} (of \texttt{struct pci\_driver}) but \texttt{attach()} (of \texttt{struct comedi\_driver}) which is invoked by Comedi subsystem.
 
-The \texttt{attach()} function is responsible not only for common PCI device initialization but also for initialization of \texttt{struct comedi\_device} (which is accessible through a pointer passed to \texttt{attach()} function). Most important step is to allocate and initialize each \textit{subdevice} (in Comedis nomenclature \textit{subdevice} is one particular function of the device -- e.g. ADC, digital out, etc.) of the DAQ card. Allocation is done by Comedi function \texttt{alloc\_subdevices(struct comedi\_device *, unsigned int num\_subdev)}, each \texttt{struct comedi\_subdevice} is then accessible in array called \texttt{subdevices} which is part of \texttt{struct comedi\_device}. Example of initialization of subdevice representing ADC:
+The \texttt{attach()} function is responsible not only for common PCI device initialization but also for initialization of \texttt{struct comedi\_device} (which is accessible through a pointer passed to \texttt{attach()} function). Most important step is to allocate and initialize each \textit{subdevice} (in Comedis nomenclature \textit{subdevice} represents one particular function of the device -- e.g. ADC, digital out, etc.) of the DAQ card. Allocation is done by Comedi function \texttt{alloc\_subdevices(struct comedi\_device *dev, unsigned int num\_subdev)}, each \texttt{struct comedi\_subdevice} is then accessible in array called \texttt{subdevices} which is part of \texttt{struct comedi\_device}. Example of initialization of subdevice representing ADC:
 \begin{verbatim}
  1 | s = dev->subdevices + 0;
  2 | s->type = COMEDI_SUBD_AI;
@@ -229,13 +229,15 @@ The \texttt{attach()} function is responsible not only for common PCI device ini
 \subsection*{Interface to user-space}
 After successful compilation and loading of particular Comedi driver, there should be \texttt{/dev/comediX} (where X is number of instance of driver) file. For communication with this file Comedi library functions are used. For opening device -- \texttt{comedi\_open()}, for reading/writing ADCs/DACs -- \texttt{comedi\_data\_read()}, \texttt{comedi\_data\_write()} and for reading/writing digital inputs/outputs -- \texttt{comedi\_dio\_read()}, \texttt{comedi\_dio\_write()}.
 
-There are already applications using Comedi API\footnote{For basic list of available applications see http://www.comedi.org/applications.html} -- in some cases there is no need for implementing user-space application from scratch.
+There are already applications using Comedi API\footnote{For basic list of available applications see http://www.comedi.org/applications.html} -- thus in some cases there is no need for implementing user-space application from scratch.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Qemu virtual hardware}
 Qemu is open-source processor emulator. Unlike common virtualization solutions it is able of emulating x86, x86-64, ARM and other widespread processor architectures. For the purposes of this work it was used for implementing virtual Humusoft MF624 DAQ card. 
 
 \subsection*{Usage}
-When running any guest operating system in Qemu (with support for MF624 activated) the virtual MF624 device is available in the same way as if it was real hardware -- there are no issues with interfacing between guest operating system and virtual device. Interfacing between virtual hardware and \textit{real world} is handled by TCP/IP connection from MF624 module in Qemu to \textit{host} operating system. It is used for reading/setting output/input values (as shown in figure 2). The most fundamental way of communication through this channel is by using \texttt{telnet} application. Example of real communication:
+When running any guest operating system in Qemu (with support for MF624 activated) the virtual MF624 device is available in the same way as if it was real hardware -- there are no issues with interfacing between guest operating system and virtual device. Interfacing between virtual hardware and \textit{real world} is handled by TCP/IP connection from MF624 part in Qemu to \textit{host} operating system. It is used for reading/setting output/input values (as shown in figure 2). 
+
+The most fundamental way of communication through this channel is by using \texttt{telnet} application. Example of real communication:
 \begin{verbatim}
   $ telnet localhost 55555
   Trying ::1...
@@ -250,19 +252,19 @@ When running any guest operating system in Qemu (with support for MF624 activate
   telnet> Connection closed.
 \end{verbatim}
 
-As a much more easier way of interfacing, there is also graphical application created just for purposes of communicating with virtual MF624 card (see figure 3). It was created using Qt4 graphical toolkit.
+As a much more easier way of interfacing, there is also graphical application created just for purposes of communication with virtual MF624 card (see figure 3). It was created using Qt4 graphical toolkit.
 
 \epsin{img/qemu}{80}{fig2:qemu}{Qemu implementing virtual MF624 device}
 
 
 \subsection*{Implementation of virtual MF624}
-When creating new virtual device in Qemu, main hook into Qemu infrastructure is done by invoking \texttt{device\_init()} with parameter of pointer to initialization function with prototype of \texttt{static void (*)(void)}. For registering new PCI device, it is necessary to call \texttt{pci\_qdev\_register()} passing parameter of pointer to \texttt{PCIDeviceInfo}. The most important fields of this Qemu-specific data type are pointers to \textit{init} and \textit{exit} functions with prototype of \texttt{int (*)(PCIDevice *)}.
+When creating new virtual device in Qemu, main hook into Qemu device infrastructure is done by invoking \texttt{device\_init()} with parameter of pointer to initialization function with prototype of \texttt{static void (*)(void)}. For registering new PCI device, it is necessary to call \texttt{pci\_qdev\_register()} passing parameter of pointer to \texttt{PCIDeviceInfo}. The most important fields of this Qemu-specific data type are pointers to \textit{init} and \textit{exit} functions with prototype of \texttt{int (*)(PCIDevice *)}.
 
 The PCI device specific initialization consists of:
 \begin{itemize}
 \item Initializing configuration space of PCI device -- e.g. setting Vendor and Device IDs, device class, interrupt pin.
 \item Registration of I/O memory used by the device.
-\item Initialization of physical memory and mapping it to particular \textit{BARs} (Base Address Registers) of PCI device.
+\item Creating function (called when device gets allocated memory from virtual PCI controller FIXME) for mapping of physical memory to particular \textit{BARs} (Base Address Registers) of PCI device.
 \end{itemize}
 
 The very basic (non-compilable) example: