fp@369: %------------------------------------------------------------------------------ fp@369: % fp@369: % IgH EtherCAT Master Documentation fp@369: % fp@369: % $Id$ fp@369: % fp@1202: % vi: spell spelllang=en tw=78 fp@2421: % fp@369: %------------------------------------------------------------------------------ fp@369: fp@369: \documentclass[a4paper,12pt,BCOR6mm,bibtotoc,idxtotoc]{scrbook} fp@369: fp@369: \usepackage[latin1]{inputenc} fp@369: \usepackage[automark,headsepline]{scrpage2} fp@369: \usepackage{graphicx} fp@369: \usepackage{makeidx} fp@369: \usepackage[refpage]{nomencl} fp@369: \usepackage{listings} fp@1588: \usepackage[nofancy]{rcsinfo} fp@1085: \usepackage{SIunits} fp@1517: \usepackage{amsmath} % for \text{} fp@2297: \usepackage{longtable} fp@1275: \usepackage{hyperref} fp@1275: fp@1275: \hypersetup{pdfpagelabels,plainpages=false} fp@1275: \hypersetup{linkcolor=blue,colorlinks=true,urlcolor=blue} fp@369: fp@369: \setlength{\parskip}{0.8ex plus 0.8ex minus 0.5ex} fp@369: \setlength{\parindent}{0mm} fp@369: fp@369: \setcounter{secnumdepth}{\subsubsectionlevel} fp@369: fp@369: \DeclareFontShape{OT1}{cmtt}{bx}{n} fp@369: { fp@369: <5><6><7><8><9><10><10.95><12><14.4><17.28><20.74><24.88>cmttb10 fp@369: }{} fp@369: fp@369: \lstset{basicstyle=\ttfamily\small,numberstyle=\tiny,aboveskip=4mm, fp@2515: belowskip=2mm,escapechar=`,breaklines=true} fp@369: \renewcommand\lstlistlistingname{List of Listings} fp@369: fp@917: % Workaround for lstlistoflistings bug fp@917: \makeatletter% --> De-TeX-FAQ fp@917: \renewcommand*{\lstlistoflistings}{% fp@917: \begingroup fp@917: \if@twocolumn fp@917: \@restonecoltrue\onecolumn fp@917: \else fp@917: \@restonecolfalse fp@917: \fi fp@917: \lol@heading fp@917: \setlength{\parskip}{\z@}% fp@917: \setlength{\parindent}{\z@}% fp@917: \setlength{\parfillskip}{\z@ \@plus 1fil}% fp@917: \@starttoc{lol}% fp@917: \if@restonecol\twocolumn\fi fp@917: \endgroup fp@917: } fp@917: \makeatother% --> \makeatletter fp@917: fp@369: \renewcommand\nomname{Glossary} fp@369: fp@369: \newcommand{\IgH}{\raisebox{-0.7667ex} fp@369: {\includegraphics[height=2.2ex]{images/ighsign}}} fp@369: fp@1589: \rcsInfo $RCSId$ fp@369: fp@2515: \newcommand{\masterversion}{1.5.2} fp@1085: \newcommand{\linenum}[1]{\normalfont\textcircled{\tiny #1}} fp@487: fp@369: \makeindex fp@917: \makenomenclature fp@369: fp@1589: % Revision and date on inner footer fp@1589: \ifoot[\scriptsize\rcsInfoRevision, \rcsInfoDate] fp@1589: {\scriptsize\rcsInfoRevision, \rcsInfoDate} fp@1589: fp@369: %------------------------------------------------------------------------------ fp@369: fp@369: \begin{document} fp@369: fp@369: \pagenumbering{roman} fp@369: \pagestyle{empty} fp@369: fp@369: \begin{titlepage} fp@369: \begin{center} fp@369: \rule{\textwidth}{1.5mm} fp@369: fp@1917: {\Huge\sf\textbf{IgH \includegraphics[height=2.4ex]{images/ethercat} fp@1917: Master \masterversion}\\[1ex] fp@1917: \textbf{Documentation}} fp@369: fp@369: \vspace{1ex} fp@369: \rule{\textwidth}{1.5mm} fp@369: fp@1204: \vspace{\fill} {\Large Dipl.-Ing. (FH) Florian Pose, fp@2691: \url{fp@igh.de}\\[1ex] Ingenieurgemeinschaft \IgH} fp@369: fp@369: \vspace{\fill} fp@1588: {\Large Essen, \rcsInfoLongDate\\[1ex] fp@1588: Revision \rcsInfoRevision} fp@369: \end{center} fp@369: \end{titlepage} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1589: \pagestyle{scrplain} fp@1589: fp@369: \tableofcontents fp@369: \listoftables fp@369: \listoffigures fp@1204: %\lstlistoflistings fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@369: \newpage fp@369: \pagestyle{scrheadings} fp@369: fp@369: \section*{Conventions} fp@369: \addcontentsline{toc}{section}{Conventions} fp@369: \markleft{Conventions} fp@369: fp@369: The following typographic conventions are used: fp@369: fp@369: \begin{itemize} fp@1085: fp@1085: \item \textit{Italic face} is used for newly introduced terms and file names. fp@1085: fp@1085: \item \texttt{Typewriter face} is used for code examples and command line fp@1085: output. fp@1085: fp@1085: \item \texttt{\textbf{Bold typewriter face}} is used for user input in command fp@1085: lines. fp@1085: fp@369: \end{itemize} fp@369: fp@1085: Data values and addresses are usually specified as hexadecimal values. These fp@1085: are marked in the \textit{C} programming language style with the prefix fp@1085: \lstinline+0x+ (example: \lstinline+0x88A4+). Unless otherwise noted, address fp@1085: values are specified as byte addresses. fp@369: fp@369: Function names are always printed with parentheses, but without fp@1085: parameters. So, if a function \lstinline+ecrt_request_master()+ has fp@1085: empty parentheses, this shall not imply that it has no parameters. fp@1085: fp@1085: If shell commands have to be entered, this is marked by a dollar prompt: fp@1085: fp@1085: \begin{lstlisting} fp@1085: $ fp@369: \end{lstlisting} fp@369: fp@369: Further, if a shell command has to be entered as the superuser, the fp@1085: prompt is a mesh: fp@1085: fp@1085: \begin{lstlisting} fp@1085: # fp@369: \end{lstlisting} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@369: \chapter{The IgH EtherCAT Master} fp@369: \label{chapter:master} fp@369: \pagenumbering{arabic} fp@369: fp@1085: This chapter covers some general information about the EtherCAT master. fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@369: \section{Feature Summary} fp@369: \label{sec:summary} fp@369: \index{Master!Features} fp@369: fp@1085: The list below gives a short summary of the master features. fp@369: fp@369: \begin{itemize} fp@1085: fp@2515: \item Designed as a kernel module for Linux 2.6 / 3.x. fp@1085: fp@1086: \item Implemented according to IEC 61158-12 \cite{dlspec} \cite{alspec}. fp@1086: fp@1588: \item Comes with EtherCAT-capable native drivers for several common Ethernet fp@1588: chips, as well as a generic driver for all chips supported by the Linux fp@1588: kernel. fp@1085: fp@369: \begin{itemize} fp@1085: fp@1588: \item The native drivers operate the hardware without interrupts. fp@1588: fp@1588: \item Native drivers for additional Ethernet hardware can easily be fp@2515: implemented using the common device interface (see~\autoref{sec:ecdev}) fp@1588: provided by the master module. fp@1588: fp@1588: \item For any other hardware, the generic driver can be used. It uses the fp@1588: lower layers of the Linux network stack. fp@1085: fp@369: \end{itemize} fp@1085: fp@1085: \item The master module supports multiple EtherCAT masters running in fp@1085: parallel. fp@1085: fp@1085: \item The master code supports any Linux realtime extension through its fp@1085: independent architecture. fp@1085: fp@369: \begin{itemize} fp@1085: fp@2515: \item RTAI\nomenclature{RTAI}{Realtime Application Interface} \cite{rtai} fp@2515: (including LXRT via RTDM), ADEOS\nomenclature{ADEOS}{Adaptive Domain fp@2515: Environment for Operating Systems}, RT-Preempt \cite{rt-preempt}, Xenomai fp@2515: (including RTDM), etc. fp@1085: fp@369: \item It runs well even without realtime extensions. fp@1085: fp@369: \end{itemize} fp@1085: fp@1204: \item Common ``Application Interface'' for applications, that want to use fp@2515: EtherCAT functionality (see \autoref{chap:api}). fp@1085: fp@1085: \item \textit{Domains} are introduced, to allow grouping of process fp@1085: data transfers with different slave groups and task periods. fp@1085: fp@369: \begin{itemize} fp@1085: fp@1085: \item Handling of multiple domains with different task periods. fp@1085: fp@1085: \item Automatic calculation of process data mapping, FMMU and sync manager fp@1085: configuration within each domain. fp@1085: fp@369: \end{itemize} fp@1085: fp@1085: \item Communication through several finite state machines. fp@1085: fp@369: \begin{itemize} fp@1085: fp@1085: \item Automatic bus scanning after topology changes. fp@1085: fp@1085: \item Bus monitoring during operation. fp@1085: fp@1085: \item Automatic reconfiguration of slaves (for example after power failure) fp@1085: during operation. fp@1085: fp@369: \end{itemize} fp@1085: fp@2515: \item Distributed Clocks support (see \autoref{sec:dc}). fp@1517: fp@1517: \begin{itemize} fp@1517: fp@1517: \item Configuration of the slave's DC parameters through the application fp@1517: interface. fp@1517: fp@1517: \item Synchronization (offset and drift compensation) of the distributed fp@1517: slave clocks to the reference clock. fp@1517: fp@2515: \item Optional synchronization of the reference clock to the master clock or fp@2515: the other way round. fp@1517: fp@1517: \end{itemize} fp@1517: fp@1327: \item CANopen over EtherCAT (CoE) fp@1085: fp@369: \begin{itemize} fp@1085: fp@1327: \item SDO upload, download and information service. fp@1327: fp@1327: \item Slave configuration via SDOs. fp@1327: fp@1327: \item SDO access from userspace and from the application. fp@1085: fp@369: \end{itemize} fp@1085: fp@1327: \item Ethernet over EtherCAT (EoE) fp@1085: fp@369: \begin{itemize} fp@1085: fp@1085: \item Transparent use of EoE slaves via virtual network interfaces. fp@1085: fp@1085: \item Natively supports either a switched or a routed EoE network fp@1085: architecture. fp@1085: fp@369: \end{itemize} fp@1085: fp@1364: \item Vendor-specific over EtherCAT (VoE) fp@1364: fp@1364: \begin{itemize} fp@1364: fp@1364: \item Communication with vendor-specific mailbox protocols via the API. fp@1364: fp@1364: \end{itemize} fp@1364: fp@1364: \item File Access over EtherCAT (FoE) fp@1364: fp@1364: \begin{itemize} fp@1364: fp@1364: \item Loading and storing files via the command-line tool. fp@1364: fp@1364: \item Updating a slave's firmware can be done easily. fp@1364: fp@1364: \end{itemize} fp@1364: fp@1917: \item Servo Profile over EtherCAT (SoE) fp@1917: fp@1917: \begin{itemize} fp@1917: fp@1917: \item Implemented according to IEC 61800-7 \cite{soespec}. fp@1917: fp@1917: \item Storing IDN configurations, that are written to the slave during fp@1917: startup. fp@1917: fp@1917: \item Accessing IDNs via the command-line tool. fp@1917: fp@1917: \item Accessing IDNs at runtime via the the user-space library. fp@1917: fp@1917: \end{itemize} fp@1917: fp@2515: \item Userspace command-line-tool ``ethercat'' (see \autoref{sec:tool}) fp@1085: fp@369: \begin{itemize} fp@1085: fp@1364: \item Detailed information about master, slaves, domains and bus fp@1364: configuration. fp@1085: \item Setting the master's debug level. fp@1364: \item Reading/Writing alias addresses. fp@1364: \item Listing slave configurations. fp@1364: \item Viewing process data. fp@1364: \item SDO download/upload; listing SDO dictionaries. fp@1364: \item Loading and storing files via FoE. fp@1917: \item SoE IDN access. fp@1364: \item Access to slave registers. fp@1364: \item Slave SII (EEPROM) access. fp@1364: \item Controlling application-layer states. fp@1517: \item Generation of slave description XML and C-code from existing slaves. fp@1085: fp@369: \end{itemize} fp@1085: fp@369: \item Seamless system integration though LSB\nomenclature{LSB}{Linux fp@369: Standard Base} compliance. fp@1085: fp@369: \begin{itemize} fp@1085: fp@1095: \item Master and network device configuration via sysconfig files. fp@1085: fp@1085: \item Init script for master control. fp@1085: fp@2515: \item Service file for systemd. fp@2515: fp@369: \end{itemize} fp@1085: fp@369: \item Virtual read-only network interface for monitoring and debugging fp@369: purposes. fp@1085: fp@369: \end{itemize} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@369: \section{License} fp@369: \label{sec:license} fp@369: fp@1275: The master code is released under the terms and conditions of the GNU General fp@1275: Public License (GPL \cite{gpl})\index{GPL}, version 2. Other developers, that fp@1275: want to use EtherCAT with Linux systems, are invited to use the master code or fp@1275: even participate on development. fp@1275: fp@1275: To allow static linking of userspace application against the master's fp@2515: application interface (see \autoref{chap:api}), the userspace library (see fp@2515: \autoref{sec:userlib}) is licensed under the terms and conditions of the GNU fp@1275: Lesser General Public License (LGPL \cite{lgpl})\index{LGPL}, version 2.1. fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1085: \chapter{Architecture} fp@1299: \label{chap:arch} fp@369: \index{Master!Architecture} fp@369: fp@2515: The EtherCAT master is integrated into the Linux kernel. This was an early fp@2515: design decision, which has been made for several reasons: fp@369: fp@369: \begin{itemize} fp@1085: fp@1306: \item Kernel code has significantly better realtime characteristics, i.\,e.\ fp@1306: less latency than userspace code. It was foreseeable, that a fieldbus master fp@1306: has a lot of cyclic work to do. Cyclic work is usually triggered by timer fp@1306: interrupts inside the kernel. The execution delay of a function that processes fp@1306: timer interrupts is less, when it resides in kernelspace, because there is no fp@1306: need of time-consuming context switches to a userspace process. fp@1085: fp@369: \item It was also foreseeable, that the master code has to directly fp@1085: communicate with the Ethernet hardware. This has to be done in the kernel fp@1085: anyway (through network device drivers), which is one more reason for the fp@1275: master code being in kernelspace. fp@1085: fp@369: \end{itemize} fp@369: fp@2515: \autoref{fig:arch} gives a general overview of the master architecture. fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@1588: \includegraphics[width=\textwidth]{images/architecture} fp@1291: \caption{Master Architecture} fp@1085: \label{fig:arch} fp@369: \end{figure} fp@369: fp@1291: The components of the master environment are described below: fp@1291: fp@1291: \begin{description} fp@1291: fp@1291: \item[Master Module]\index{Master Module} Kernel module containing one or more fp@2515: EtherCAT master instances (see \autoref{sec:mastermod}), the ``Device fp@2515: Interface'' (see \autoref{sec:ecdev}) and the ``Application Interface'' (see fp@2515: \autoref{chap:api}). fp@1291: fp@1291: \item[Device Modules]\index{Device modules} EtherCAT-capable Ethernet device fp@1291: driver modules\index{Device modules}, that offer their devices to the EtherCAT fp@2515: master via the device interface (see \autoref{sec:ecdev}). These modified fp@1291: network drivers can handle network devices used for EtherCAT operation and fp@1291: ``normal'' Ethernet devices in parallel. A master can accept a certain device fp@1291: and then is able to send and receive EtherCAT frames. Ethernet devices fp@1291: declined by the master module are connected to the kernel's network stack as fp@1291: usual. fp@1291: fp@1291: \item[Application]\index{Application} A program that uses the EtherCAT master fp@1291: (usually for cyclic exchange of process data with EtherCAT slaves). These fp@1291: programs are not part of the EtherCAT master code\footnote{Although there are fp@1291: some examples provided in the \textit{examples/} directory.}, but have to be fp@2515: generated or written by the user. An application can request a master through fp@2515: the application interface (see \autoref{chap:api}). If this succeeds, it has fp@2515: the control over the master: It can provide a bus configuration and exchange fp@2515: process data. Applications can be kernel modules (that use the kernel fp@2515: application interface directly) or userspace programs, that use the fp@2515: application interface via the EtherCAT library (see \autoref{sec:userlib}), or fp@2515: the RTDM library (see~\autoref{sec:rtdm}). fp@1291: fp@1291: \end{description} fp@1085: fp@1085: %------------------------------------------------------------------------------ fp@1085: fp@1306: \section{Master Module} fp@1306: \label{sec:mastermod} fp@1306: \index{Master module} fp@1306: fp@1306: The EtherCAT master kernel module \textit{ec\_master} can contain multiple fp@2515: master instances. Each master waits for certain Ethernet device(s) identified fp@2515: by its MAC address(es)\index{MAC address}. These addresses have to be fp@2515: specified on module loading via the \textit{main\_devices} (and optional: fp@2515: \textit{backup\_devices}) module parameter. The number of master instances to fp@2515: initialize is taken from the number of MAC addresses given. fp@1306: fp@1306: The below command loads the master module with a single master instance that fp@2515: waits for one Ethernet device with the MAC address fp@1306: \lstinline+00:0E:0C:DA:A2:20+. The master will be accessible via index $0$. fp@1306: fp@1306: \begin{lstlisting} fp@1306: # `\textbf{modprobe ec\_master main\_devices=00:0E:0C:DA:A2:20}` fp@1306: \end{lstlisting} fp@1306: fp@1306: MAC addresses for multiple masters have to be separated by commas: fp@1306: fp@1306: \begin{lstlisting} fp@1306: # `\textbf{modprobe ec\_master main\_devices=00:0E:0C:DA:A2:20,00:e0:81:71:d5:1c}` fp@1306: \end{lstlisting} fp@1306: fp@1306: The two masters can be addressed by their indices 0 and 1 respectively (see fp@2515: \autoref{fig:masters}). The master index is needed for the fp@1306: \lstinline+ecrt_master_request()+ function of the application interface (see fp@2515: \autoref{chap:api}) and the \lstinline+--master+ option of the fp@2515: \textit{ethercat} command-line tool (see \autoref{sec:tool}), which defaults fp@1306: to $0$. fp@1306: fp@1306: \begin{figure}[htbp] fp@1306: \centering fp@1306: \includegraphics[width=.5\textwidth]{images/masters} fp@1306: \caption{Multiple masters in one module} fp@1306: \label{fig:masters} fp@1306: \end{figure} fp@1306: fp@1399: \paragraph{Debug Level} The master module also has a parameter fp@1399: \textit{debug\_level} to set the initial debug level for all masters (see fp@2515: also~\autoref{sec:ethercat-debug}). fp@1399: fp@1306: \paragraph{Init Script} fp@1306: \index{Init script} fp@1306: fp@1306: In most cases it is not necessary to load the master module and the Ethernet fp@1306: driver modules manually. There is an init script available, so the master can fp@2515: be started as a service (see \autoref{sec:system}). For systems that are fp@2515: managed by systemd \cite{systemd}, there is also a service file available. fp@1306: fp@1306: \paragraph{Syslog} fp@1306: fp@1306: The master module outputs information about its state and events to the kernel fp@2515: ring buffer. These also end up in the system logs. The above module loading fp@1306: command should result in the messages below: fp@1306: fp@1306: \begin{lstlisting} fp@1306: # `\textbf{dmesg | tail -2}` fp@1306: EtherCAT: Master driver `\masterversion` fp@1306: EtherCAT: 2 masters waiting for devices. fp@1306: fp@1306: # `\textbf{tail -2 /var/log/messages}` fp@1306: Jul 4 10:22:45 ethercat kernel: EtherCAT: Master driver `\masterversion` fp@1306: Jul 4 10:22:45 ethercat kernel: EtherCAT: 2 masters waiting fp@1306: for devices. fp@1306: \end{lstlisting} fp@1306: fp@2515: Master output is prefixed with \lstinline+EtherCAT+ which makes searching the fp@2515: logs easier. fp@1306: fp@1306: %------------------------------------------------------------------------------ fp@1306: fp@1306: \section{Master Phases} fp@1085: \index{Master phases} fp@1085: fp@1306: Every EtherCAT master provided by the master module (see fp@2515: \autoref{sec:mastermod}) runs through several phases (see fp@2515: \autoref{fig:phases}): fp@1085: fp@1085: \begin{figure}[htbp] fp@1085: \centering fp@1085: \includegraphics[width=.9\textwidth]{images/phases} fp@1085: \caption{Master phases and transitions} fp@1085: \label{fig:phases} fp@1085: \end{figure} fp@1291: fp@1085: \begin{description} fp@1085: fp@1085: \item[Orphaned phase]\index{Orphaned phase} This mode takes effect, when the fp@2515: master still waits for its Ethernet device(s) to connect. No bus communication fp@2515: is possible until then. fp@1086: fp@1086: \item[Idle phase]\index{Idle phase} takes effect when the master has accepted fp@2515: all required Ethernet devices, but is not requested by any application yet. fp@2515: The master runs its state machine (see \autoref{sec:fsm-master}), that fp@2515: automatically scans the bus for slaves and executes pending operations from fp@2515: the userspace interface (for example SDO access). The command-line tool can be fp@2515: used to access the bus, but there is no process data exchange because of the fp@2515: missing bus configuration. fp@1085: fp@1085: \item[Operation phase]\index{Operation phase} The master is requested by an fp@1085: application that can provide a bus configuration and exchange process data. fp@1085: fp@1085: \end{description} fp@1085: fp@1085: %------------------------------------------------------------------------------ fp@1085: fp@1293: \section{Process Data} fp@369: \label{sec:processdata} fp@369: fp@1293: This section shall introduce a few terms and ideas how the master handles fp@1293: process data. fp@1085: fp@369: \paragraph{Process Data Image} fp@369: \index{Process data} fp@369: fp@1293: Slaves offer their inputs and outputs by presenting the master so-called fp@1327: ``Process Data Objects'' (PDOs\index{PDO}). The available PDOs can be either fp@2515: determined by reading out the slave's TxPDO and RxPDO SII categories from the fp@1327: E$^2$PROM (in case of fixed PDOs) or by reading out the appropriate CoE fp@2515: objects (see \autoref{sec:coe}), if available. The application can register fp@1327: the PDOs' entries for exchange during cyclic operation. The sum of all fp@1327: registered PDO entries defines the ``process data image'', which is exchanged fp@1293: via datagrams with ``logical'' memory access (like LWR, LRD or LRW) introduced fp@1293: in~\cite[sec.~5.4]{dlspec}. fp@369: fp@369: \paragraph{Process Data Domains} fp@369: \index{Domain} fp@369: fp@1085: The process data image can be easily managed by creating so-called fp@1327: ``domains'', which allow grouped PDO exchange. They also take care of managing fp@1327: the datagram structures needed to exchange the PDOs. Domains are mandatory for fp@1293: process data exchange, so there has to be at least one. They were introduced fp@1293: for the following reasons: fp@369: fp@369: \begin{itemize} fp@1293: fp@1293: \item The maximum size of a datagram is limited due to the limited size of an fp@1293: Ethernet frame: The maximum data size is the Ethernet data field size minus fp@1293: the EtherCAT frame header, EtherCAT datagram header and EtherCAT datagram fp@1293: footer: $1500 - 2 - 12 - 2 = 1484$ octets. If the size of the process data fp@1293: image exceeds this limit, multiple frames have to be sent, and the image has fp@1293: to be partitioned for the use of multiple datagrams. A domain manages this fp@1293: automatically. fp@1293: fp@1327: \item Not every PDO has to be exchanged with the same frequency: The values of fp@1327: PDOs can vary slowly over time (for example temperature values), so exchanging fp@1293: them with a high frequency would just waste bus bandwidth. For this reason, fp@1327: multiple domains can be created, to group different PDOs and so allow separate fp@1293: exchange. fp@1293: fp@369: \end{itemize} fp@369: fp@1293: There is no upper limit for the number of domains, but each domain occupies fp@1293: one FMMU in each slave involved, so the maximum number of domains is de facto fp@1293: limited by the slaves. fp@369: fp@369: \paragraph{FMMU Configuration} fp@369: \index{FMMU!Configuration} fp@369: fp@1327: An application can register PDO entries for exchange. Every PDO entry and its fp@1327: parent PDO is part of a memory area in the slave's physical memory, that is fp@1293: protected by a sync manager \cite[sec.~6.7]{dlspec} for synchronized access. fp@1293: In order to make a sync manager react on a datagram accessing its memory, it fp@1293: is necessary to access the last byte covered by the sync manager. Otherwise fp@1293: the sync manager will not react on the datagram and no data will be exchanged. fp@1293: That is why the whole synchronized memory area has to be included into the fp@1327: process data image: For example, if a certain PDO entry of a slave is fp@1293: registered for exchange with a certain domain, one FMMU will be configured to fp@1327: map the complete sync-manager-protected memory, the PDO entry resides in. If a fp@1327: second PDO entry of the same slave is registered for process data exchange fp@1293: within the same domain, and it resides in the same sync-manager-protected fp@1293: memory as the first one, the FMMU configuration is not altered, because the fp@1293: desired memory is already part of the domain's process data image. If the fp@1327: second PDO entry would belong to another sync-manager-protected area, this fp@1293: complete area would also be included into the domains process data image. fp@1293: fp@2515: \autoref{fig:fmmus} gives an overview, how FMMUs are configured to map fp@1293: physical memory to logical process data images. fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@369: \includegraphics[width=\textwidth]{images/fmmus} fp@1293: \caption{FMMU Configuration} fp@369: \label{fig:fmmus} fp@369: \end{figure} fp@369: fp@1085: %------------------------------------------------------------------------------ fp@1085: fp@1085: \chapter{Application Interface} fp@1289: \label{chap:api} fp@1085: \index{Application interface} fp@1085: fp@1297: % TODO fp@1297: % fp@1297: % Interface version fp@1297: % Master Requesting and Releasing fp@1297: % Master Locking fp@1327: % Configuring PDO assignment and mapping fp@1297: % Domains (memory) fp@1327: % PDO entry registration fp@1327: % SDO configuration fp@1327: % SDO access fp@1917: % IDN configurations fp@1917: % IDN access fp@1202: fp@1094: The application interface provides functions and data structures for fp@1292: applications to access an EtherCAT master. The complete documentation of the fp@1292: interface is included as Doxygen~\cite{doxygen} comments in the header file fp@1292: \textit{include/ecrt.h}. It can either be read directly from the file fp@1293: comments, or as a more comfortable HTML documentation. The HTML generation is fp@2515: described in \autoref{sec:gendoc}. fp@1094: fp@1094: The following sections cover a general description of the application fp@1094: interface. fp@1094: fp@1094: Every application should use the master in two steps: fp@1094: fp@1094: \begin{description} fp@1094: fp@1094: \item[Configuration] The master is requested and the configuration is applied. fp@1327: For example, domains are created, slaves are configured and PDO entries are fp@2515: registered (see \autoref{sec:masterconfig}). fp@1293: fp@1293: \item[Operation] Cyclic code is run and process data are exchanged (see fp@2515: \autoref{sec:cyclic}). fp@1094: fp@1094: \end{description} fp@1094: fp@1293: \paragraph{Example Applications}\index{Example Applications} There are a few fp@1204: example applications in the \textit{examples/} subdirectory of the master fp@1204: code. They are documented in the source code. fp@1204: fp@1094: %------------------------------------------------------------------------------ fp@1094: fp@1094: \section{Master Configuration} fp@1094: \label{sec:masterconfig} fp@1094: fp@1293: The bus configuration is supplied via the application interface. fp@2515: \autoref{fig:app-config} gives an overview of the objects, that can be fp@1293: configured by the application. fp@1094: fp@1094: \begin{figure}[htbp] fp@1094: \centering fp@1094: \includegraphics[width=.8\textwidth]{images/app-config} fp@1203: \caption{Master Configuration} fp@1094: \label{fig:app-config} fp@1094: \end{figure} fp@1094: fp@1293: \subsection{Slave Configuration} fp@1293: fp@1293: The application has to tell the master about the expected bus topology. This fp@1293: can be done by creating ``slave configurations''. A slave configuration can be fp@1293: seen as an expected slave. When a slave configuration is created, the fp@1293: application provides the bus position (see below), vendor id and product code. fp@1293: fp@1293: When the bus configuration is applied, the master checks, if there is a slave fp@1293: with the given vendor id and product code at the given position. If this is fp@1293: the case, the slave configuration is ``attached'' to the real slave on the bus fp@1293: and the slave is configured according to the settings provided by the fp@1293: application. The state of a slave configuration can either be queried via the fp@1293: application interface or via the command-line tool (see fp@2515: \autoref{sec:ethercat-config}). fp@1293: fp@1293: \paragraph{Slave Position} The slave position has to be specified as a tuple fp@1306: of ``alias'' and ``position''. This allows addressing slaves either via an fp@1293: absolute bus position, or a stored identifier called ``alias'', or a mixture fp@1293: of both. The alias is a 16-bit value stored in the slave's E$^2$PROM. It can fp@2515: be modified via the command-line tool (see \autoref{sec:ethercat-alias}). fp@2515: \autoref{tab:slaveposition} shows, how the values are interpreted. fp@1293: fp@1293: \begin{table}[htbp] fp@1293: \centering fp@1293: \caption{Specifying a Slave Position} fp@1293: \label{tab:slaveposition} fp@1293: \vspace{2mm} fp@1293: \begin{tabular}{c|c|p{70mm}} fp@1293: Alias & Position & Interpretation\\ fp@1293: \hline fp@1293: fp@1293: \lstinline+0+ & \lstinline+0+ -- \lstinline+65535+ & fp@1293: fp@1293: Position addressing. The position parameter is interpreted as the absolute fp@1293: ring position in the bus.\\ \hline fp@1293: fp@1293: \lstinline+1+ -- \lstinline+65535+ & \lstinline+0+ -- \lstinline+65535+ & fp@1293: fp@1293: Alias addressing. The position parameter is interpreted as relative fp@1293: position after the first slave with the given alias address. \\ \hline fp@1293: fp@1293: \end{tabular} fp@1293: \end{table} fp@1293: fp@2515: \autoref{fig:attach} shows an example of how slave configurations are fp@1293: attached. Some of the configurations were attached, while others remain fp@1293: detached. The below lists gives the reasons beginning with the top slave fp@1293: configuration. fp@1293: fp@1293: \begin{figure}[htbp] fp@1293: \centering fp@1293: \includegraphics[width=.7\textwidth]{images/attach} fp@1293: \caption{Slave Configuration Attachment} fp@1293: \label{fig:attach} fp@1293: \end{figure} fp@1293: fp@1293: \begin{enumerate} fp@1293: fp@1293: \item A zero alias means to use simple position addressing. Slave 1 exists and fp@1293: vendor id and product code match the expected values. fp@1293: fp@1293: \item Although the slave with position 0 is found, the product code does not fp@1293: match, so the configuration is not attached. fp@1293: fp@1293: \item The alias is non-zero, so alias addressing is used. Slave 2 is the first fp@1293: slave with alias \lstinline+0x2000+. Because the position value is zero, the fp@1293: same slave is used. fp@1293: fp@1293: \item There is no slave with the given alias, so the configuration can not be fp@1293: attached. fp@1293: fp@1293: \item Slave 2 is again the first slave with the alias \lstinline+0x2000+, but fp@1293: position is now 1, so slave 3 is attached. fp@1293: fp@1293: \end{enumerate} fp@1293: fp@2691: f the master sources are configured with \lstinline+--enable-wildcards+, then fp@2515: \lstinline+0xffffffff+ matches every vendor ID and/or product code. fp@2515: fp@1094: %------------------------------------------------------------------------------ fp@1094: fp@1094: \section{Cyclic Operation} fp@1094: \label{sec:cyclic} fp@1094: fp@1293: fp@1293: To enter cyclic operation mode, the master has to be ``activated'' to fp@1293: calculate the process data image and apply the bus configuration for the first fp@1293: time. After activation, the application is in charge to send and receive fp@2515: frames. The configuration can not be changed after activation. fp@1293: fp@1297: % TODO fp@1297: % fp@1297: % PDO endianess fp@1297: % Datagram injection fp@1094: fp@1094: %------------------------------------------------------------------------------ fp@1094: fp@1298: \section{VoE Handlers} fp@1298: \label{sec:api-voe} fp@1298: fp@1298: During the configuration phase, the application can create handlers for the fp@2515: VoE mailbox protocol described in \autoref{sec:voe}. One VoE handler always fp@1298: belongs to a certain slave configuration, so the creation function is a method fp@1298: of the slave configuration. fp@1298: fp@1298: A VoE handler manages the VoE data and the datagram used to transmit and fp@1298: receive VoE messages. Is contains the state machine necessary to transfer VoE fp@1298: messages. fp@1298: fp@1298: The VoE state machine can only process one operation at a time. As a result, fp@1298: either a read or write operation may be issued at a time\footnote{If fp@1298: simultaneous sending and receiving is desired, two VoE handlers can be created fp@1298: for the slave configuration.}. After the operation is initiated, the handler fp@1298: must be executed cyclically until it is finished. After that, the results of fp@1298: the operation can be retrieved. fp@1298: fp@1298: A VoE handler has an own datagram structure, that is marked for exchange after fp@1298: each execution step. So the application can decide, how many handlers to fp@1298: execute before sending the corresponding EtherCAT frame(s). fp@1298: fp@1298: For more information about the use of VoE handlers see the documentation of fp@1298: the application interface functions and the example applications provided in fp@1298: the \textit{examples/} directory. fp@1298: fp@1298: %------------------------------------------------------------------------------ fp@1298: fp@1294: \section{Concurrent Master Access} fp@1085: \label{sec:concurr} fp@1085: \index{Concurrency} fp@1085: fp@1085: In some cases, one master is used by several instances, for example when an fp@1289: application does cyclic process data exchange, and there are EoE-capable fp@1289: slaves that require to exchange Ethernet data with the kernel (see fp@2515: \autoref{sec:eoe}). For this reason, the master is a shared resource, and fp@1289: access to it has to be sequentialized. This is usually done by locking with fp@1085: semaphores, or other methods to protect critical sections. fp@1085: fp@1085: The master itself can not provide locking mechanisms, because it has no chance fp@1291: to know the appropriate kind of lock. For example if the application is in fp@1291: kernelspace and uses RTAI functionality, ordinary kernel semaphores would not fp@1291: be sufficient. For that, an important design decision was made: The fp@1291: application that reserved a master must have the total control, therefore it fp@1291: has to take responsibility for providing the appropriate locking mechanisms. fp@1517: If another instance wants to access the master, it has to request the bus fp@1517: access via callbacks, that have to be provided by the application. Moreover fp@1517: the application can deny access to the master if it considers it to be awkward fp@1517: at the moment. fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@1085: \includegraphics[width=.6\textwidth]{images/master-locks} fp@1295: \caption{Concurrent Master Access} fp@1085: \label{fig:locks} fp@369: \end{figure} fp@369: fp@2515: \autoref{fig:locks} exemplary shows, how two processes share one master: fp@1204: The application's cyclic task uses the master for process data exchange, while fp@1204: the master-internal EoE process uses it to communicate with EoE-capable fp@1517: slaves. Both have to access the bus from time to time, but the EoE process fp@1517: does this by ``asking'' the application to do the bus access for it. In this fp@1517: way, the application can use the appropriate locking mechanism to avoid fp@1517: accessing the bus at the same time. See the application interface fp@2515: documentation (\autoref{chap:api}) for how to use these callbacks. fp@1517: fp@1517: %------------------------------------------------------------------------------ fp@1517: fp@1517: \section{Distributed Clocks} fp@1517: \label{sec:dc} fp@1517: \index{Distributed Clocks} fp@1517: fp@1517: From version 1.5, the master supports EtherCAT's ``Distributed Clocks'' fp@1517: feature. It is possible to synchronize the slave clocks on the bus to the fp@1517: ``reference clock'' (which is the local clock of the first slave with DC fp@1517: support) and to synchronize the reference clock to the ``master clock'' (which fp@1517: is the local clock of the master). All other clocks on the bus (after the fp@2515: reference clock) are considered as ``slave clocks'' (see \autoref{fig:dc}). fp@1517: fp@1517: \begin{figure}[htbp] fp@1517: \centering fp@1517: \includegraphics[width=.8\textwidth]{images/dc} fp@1517: \caption{Distributed Clocks} fp@1517: \label{fig:dc} fp@1517: \end{figure} fp@1517: fp@1517: \paragraph{Local Clocks} Any EtherCAT slave that supports DC has a local clock fp@1517: register with nanosecond resolution. If the slave is powered, the clock starts fp@1517: from zero, meaning that when slaves are powered on at different times, their fp@1517: clocks will have different values. These ``offsets'' have to be compensated by fp@1517: the distributed clocks mechanism. On the other hand, the clocks do not run fp@1517: exactly with the same speed, since the used quarts units have a natural fp@1517: frequency deviation. This deviation is usually very small, but over longer fp@1517: periods, the error would accumulate and the difference between local clocks fp@1517: would grow. This clock ``drift'' has also to be compensated by the DC fp@1517: mechanism. fp@1517: fp@1517: \paragraph{Application Time} The common time base for the bus has to be fp@1517: provided by the application. This application time $t_\text{app}$ is used fp@1517: fp@1517: \begin{enumerate} fp@1517: \item to configure the slaves' clock offsets (see below), fp@1517: \item to program the slave's start times for sync pulse generation (see fp@1517: below). fp@1517: \item to synchronize the reference clock to the master clock (optional). fp@1517: \end{enumerate} fp@1517: fp@1517: \paragraph{Offset Compensation} For the offset compensation, each slave fp@1517: provides a ``System Time Offset'' register $t_\text{off}$, that is added to fp@1517: the internal clock value $t_\text{int}$ to get the ``System Time'' fp@1517: $t_\text{sys}$: fp@1517: fp@1517: \begin{eqnarray} fp@1517: t_\text{sys} & = & t_\text{int} + t_\text{off} \\ fp@1517: \Rightarrow t_\text{int} & = & t_\text{sys} - t_\text{off} \nonumber fp@1517: \end{eqnarray} fp@1517: fp@1517: The master reads the values of both registers to calculate a new system time fp@1517: offset in a way, that the resulting system time shall match the master's fp@1517: application time $t_\text{app}$: fp@1517: fp@1517: \begin{eqnarray} fp@1517: t_\text{sys} & \stackrel{!}{=} & t_\text{app} \\ fp@1517: \Rightarrow t_\text{int} + t_\text{off} & \stackrel{!}{=} & t_\text{app} \nonumber \\ fp@1517: \Rightarrow t_\text{off} & = & t_\text{app} - t_\text{int} \nonumber \\ fp@1517: \Rightarrow t_\text{off} & = & t_\text{app} - (t_\text{sys} - t_\text{off}) \nonumber \\ fp@1517: \Rightarrow t_\text{off} & = & t_\text{app} - t_\text{sys} + t_\text{off} fp@1517: \end{eqnarray} fp@1517: fp@1517: The small time offset error resulting from the different times of reading and fp@1517: writing the registers will be compensated by the drift compensation. fp@1517: fp@1517: \paragraph{Drift Compensation} The drift compensation is possible due to a fp@1517: special mechanism in each DC-capable slave: A write operation to the ``System fp@1517: time'' register will cause the internal time control loop to compare the fp@1517: written time (minus the programmed transmission delay, see below) to the fp@1517: current system time. The calculated time error will be used as an input to the fp@1517: time controller, that will tune the local clock speed to be a little faster or fp@1517: slower\footnote{The local slave clock will be incremented either with fp@1517: \unit{9}{\nano\second}, \unit{10}{\nano\second} or \unit{11}{\nano\second} fp@1517: every \unit{10}{\nano\second}.}, according to the sign of the error. fp@1517: fp@1517: \paragraph{Transmission Delays} The Ethernet frame needs a small amount of fp@1517: time to get from slave to slave. The resulting transmission delay times fp@1517: accumulate on the bus and can reach microsecond magnitude and thus have to be fp@1517: considered during the drift compensation. EtherCAT slaves supporting DC fp@1517: provide a mechanism to measure the transmission delays: For each of the four fp@1517: slave ports there is a receive time register. A write operation to the receive fp@1517: time register of port 0 starts the measuring and the current system time is fp@1517: latched and stored in a receive time register once the frame is received on fp@1517: the corresponding port. The master can read out the relative receive times, fp@1517: then calculate time delays between the slaves (using its knowledge of the bus fp@1517: topology), and finally calculate the time delays from the reference clock to fp@1517: each slave. These values are programmed into the slaves' transmission delay fp@2421: registers. In this way, the drift compensation can reach nanosecond synchrony. fp@1517: fp@1517: \paragraph{Checking Synchrony} DC-capable slaves provide the 32-bit ``System fp@1517: time difference'' register at address \lstinline+0x092c+, where the system fp@1517: time difference of the last drift compensation is stored in nanosecond fp@1517: resolution and in sign-and-magnitude coding\footnote{This allows fp@1517: broadcast-reading all system time difference registers on the bus to get an fp@1517: upper approximation}. To check for bus synchrony, the system time difference fp@1517: registers can also be cyclically read via the command-line-tool (see fp@2515: \autoref{sec:regaccess}): fp@1517: fp@1517: \begin{lstlisting} fp@1917: $ `\textbf{watch -n0 "ethercat reg\_read -p4 -tsm32 0x92c"}` fp@1517: \end{lstlisting} fp@1517: fp@1517: \paragraph{Sync Signals} Synchronous clocks are only the prerequisite for fp@1517: synchronous events on the bus. Each slave with DC support provides two ``sync fp@1517: signals'', that can be programmed to create events, that will for example fp@1517: cause the slave application to latch its inputs on a certain time. A sync fp@1517: event can either be generated once or cyclically, depending on what makes fp@1517: sense for the slave application. Programming the sync signals is a matter of fp@1517: setting the so-called ``AssignActivate'' word and the sync signals' cycle- and fp@1517: shift times. The AssignActivate word is slave-specific and has to be taken fp@1517: from the XML slave description (\lstinline+Device+ $\rightarrow$ fp@1517: \lstinline+Dc+), where also typical sync signal configurations ``OpModes'' can fp@1517: be found. fp@1085: fp@1085: %------------------------------------------------------------------------------ fp@1085: fp@1202: \chapter{Ethernet Devices} fp@1085: \label{sec:devices} fp@1085: fp@1203: The EtherCAT protocol is based on the Ethernet standard, so a master relies on fp@1203: standard Ethernet hardware to communicate with the bus. fp@1085: fp@1085: The term \textit{device} is used as a synonym for Ethernet network interface fp@1588: hardware. fp@1588: fp@1588: \paragraph{Native Ethernet Device Drivers} There are native device driver fp@2515: modules (see \autoref{sec:native-drivers}) that handle Ethernet hardware, fp@1588: which a master can use to connect to an EtherCAT bus. They offer their fp@1588: Ethernet hardware to the master module via the device interface (see fp@2515: \autoref{sec:ecdev}) and must be capable to prepare Ethernet devices either fp@1588: for EtherCAT (realtime) operation or for ``normal'' operation using the fp@1588: kernel's network stack. The advantage of this approach is that the master can fp@1588: operate nearly directly on the hardware, which allows a high performance. The fp@1588: disadvantage is, that there has to be an EtherCAT-capable version of the fp@1588: original Ethernet driver. fp@1588: fp@1588: \paragraph{Generic Ethernet Device Driver} From master version 1.5, there is a fp@2515: generic Ethernet device driver module (see \autoref{sec:generic-driver}), fp@1588: that uses the lower layers of the network stack to connect to the hardware. fp@1588: The advantage is, that arbitrary Ethernet hardware can be used for EtherCAT fp@1588: operation, independently of the actual hardware driver (so all Linux Ethernet fp@1588: drivers are supported without modifications). The disadvantage is, that this fp@1588: approach does not support realtime extensions like RTAI, because the Linux fp@1588: network stack is addressed. Moreover the performance is a little worse than fp@1588: the native approach, because the Ethernet frame data have to traverse the fp@1588: network stack. fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1085: \section{Network Driver Basics} fp@369: \label{sec:networkdrivers} fp@369: \index{Network drivers} fp@369: fp@369: EtherCAT relies on Ethernet hardware and the master needs a physical fp@369: Ethernet device to communicate with the bus. Therefore it is necessary fp@369: to understand how Linux handles network devices and their drivers, fp@369: respectively. fp@369: fp@1588: \paragraph{Tasks of a Network Driver} Network device drivers usually handle fp@1588: the lower two layers of the OSI model, that is the physical layer and the fp@1588: data-link layer. A network device itself natively handles the physical layer fp@1588: issues: It represents the hardware to connect to the medium and to send and fp@1588: receive data in the way, the physical layer protocol describes. The network fp@1588: device driver is responsible for getting data from the kernel's networking fp@1588: stack and forwarding it to the hardware, that does the physical transmission. fp@1588: If data is received by the hardware respectively, the driver is notified fp@1588: (usually by means of an interrupt) and has to read the data from the hardware fp@1588: memory and forward it to the network stack. There are a few more tasks, a fp@1588: network device driver has to handle, including queue control, statistics and fp@1588: device dependent features. fp@1588: fp@1588: \paragraph{Driver Startup} Usually, a driver searches for compatible devices fp@1588: on module loading. For PCI drivers, this is done by scanning the PCI bus and fp@1588: checking for known device IDs. If a device is found, data structures are fp@1588: allocated and the device is taken into operation. fp@1588: fp@1588: \paragraph{Interrupt Operation}\index{Interrupt} A network device usually fp@1588: provides a hardware interrupt that is used to notify the driver of received fp@1588: frames and success of transmission, or errors, respectively. The driver has to fp@1588: register an interrupt service routine fp@1588: (ISR\index{ISR}\nomenclature{ISR}{Interrupt Service Routine}), that is fp@1588: executed each time, the hardware signals such an event. If the interrupt was fp@1588: thrown by the own device (multiple devices can share one hardware interrupt), fp@1588: the reason for the interrupt has to be determined by reading the device's fp@1588: interrupt register. For example, if the flag for received frames is set, frame fp@1588: data has to be copied from hardware to kernel memory and passed to the network fp@1588: stack. fp@1588: fp@1588: \paragraph{The \lstinline+net_device+ Structure}\index{net\_device} The driver fp@1588: registers a \lstinline+net_device+ structure for each device to communicate fp@1588: with the network stack and to create a ``network interface''. In case of an fp@1588: Ethernet driver, this interface appears as \textit{ethX}, where X is a number fp@1588: assigned by the kernel on registration. The \lstinline+net_device+ structure fp@1588: receives events (either from userspace or from the network stack) via several fp@1588: callbacks, which have to be set before registration. Not every callback is fp@1588: mandatory, but for reasonable operation the ones below are needed in any case: fp@1202: fp@1202: \newsavebox\boxopen fp@1202: \sbox\boxopen{\lstinline+open()+} fp@1202: \newsavebox\boxstop fp@1202: \sbox\boxstop{\lstinline+stop()+} fp@1202: \newsavebox\boxxmit fp@1202: \sbox\boxxmit{\lstinline+hard_start_xmit()+} fp@1202: \newsavebox\boxstats fp@1202: \sbox\boxstats{\lstinline+get_stats()+} fp@369: fp@369: \begin{description} fp@1095: fp@1202: \item[\usebox\boxopen] This function is called when network communication has fp@1275: to be started, for example after a command \lstinline+ip link set ethX up+ fp@1275: from userspace. Frame reception has to be enabled by the driver. fp@1202: fp@1297: \item[\usebox\boxstop] The purpose of this callback is to ``close'' the fp@1306: device, i.\,e.\ make the hardware stop receiving frames. fp@1202: fp@1202: \item[\usebox\boxxmit] This function is called for each frame that has to be fp@1202: transmitted. The network stack passes the frame as a pointer to an fp@1202: \lstinline+sk_buff+ structure (``socket buffer''\index{Socket buffer}, see fp@1095: below), which has to be freed after sending. fp@1095: fp@1202: \item[\usebox\boxstats] This call has to return a pointer to the device's fp@1202: \lstinline+net_device_stats+ structure, which permanently has to be filled with fp@1095: frame statistics. This means, that every time a frame is received, sent, or an fp@1095: error happened, the appropriate counter in this structure has to be increased. fp@1095: fp@1095: \end{description} fp@1095: fp@1095: The actual registration is done with the \lstinline+register_netdev()+ call, fp@1095: unregistering is done with \lstinline+unregister_netdev()+. fp@369: fp@1588: \paragraph{The \lstinline+netif+ Interface}\index{netif} All other fp@1588: communication in the direction interface $\to$ network stack is done via the fp@1588: \lstinline+netif_*()+ calls. For example, on successful device opening, the fp@1588: network stack has to be notified, that it can now pass frames to the fp@1202: interface. This is done by calling \lstinline+netif_start_queue()+. After this fp@1202: call, the \lstinline+hard_start_xmit()+ callback can be called by the network fp@1588: stack. Furthermore a network driver usually manages a frame transmission fp@1588: queue. If this gets filled up, the network stack has to be told to stop fp@1588: passing further frames for a while. This happens with a call to fp@1202: \lstinline+netif_stop_queue()+. If some frames have been sent, and there is fp@1095: enough space again to queue new frames, this can be notified with fp@1095: \lstinline+netif_wake_queue()+. Another important call is fp@1095: \lstinline+netif_receive_skb()+\footnote{This function is part of the NAPI fp@1095: (``New API''), that replaces the kernel 2.4 technique for interfacing to the fp@1095: network stack (with \lstinline+netif_rx()+). NAPI is a technique to improve fp@1095: network performance on Linux. Read more in fp@1095: \url{http://www.cyberus.ca/~hadi/usenix-paper.tgz}.}: It passes a frame to the fp@1095: network stack, that was just received by the device. Frame data has to be fp@1202: included in a so-called ``socket buffer'' for that (see below). fp@369: fp@1588: \paragraph{Socket Buffers}\index{Socket buffer} Socket buffers are the basic fp@1588: data type for the whole network stack. They serve as containers for network fp@1588: data and are able to quickly add data headers and footers, or strip them off fp@1588: again. Therefore a socket buffer consists of an allocated buffer and several fp@1588: pointers that mark beginning of the buffer (\lstinline+head+), beginning of fp@1588: data (\lstinline+data+), end of data (\lstinline+tail+) and end of buffer fp@1588: (\lstinline+end+). In addition, a socket buffer holds network header fp@1588: information and (in case of received data) a pointer to the fp@1588: \lstinline+net_device+, it was received on. There exist functions that create fp@1588: a socket buffer (\lstinline+dev_alloc_skb()+), add data either from front fp@1588: (\lstinline+skb_push()+) or back (\lstinline+skb_put()+), remove data from fp@1588: front (\lstinline+skb_pull()+) or back (\lstinline+skb_trim()+), or delete the fp@1588: buffer (\lstinline+kfree_skb()+). A socket buffer is passed from layer to fp@1588: layer, and is freed by the layer that uses it the last time. In case of fp@1588: sending, freeing has to be done by the network driver. fp@1588: fp@1588: %------------------------------------------------------------------------------ fp@1588: fp@1588: \section{Native EtherCAT Device Drivers} fp@1588: \label{sec:native-drivers} fp@1588: fp@1588: There are a few requirements, that applies to Ethernet hardware when used with fp@1588: a native Ethernet driver with EtherCAT functionality. fp@1588: fp@1588: \paragraph{Dedicated Hardware} For performance and realtime purposes, the fp@1588: EtherCAT master needs direct and exclusive access to the Ethernet hardware. fp@1588: This implies that the network device must not be connected to the kernel's fp@1588: network stack as usual, because the kernel would try to use it as an ordinary fp@1588: Ethernet device. fp@1588: fp@1588: \paragraph{Interrupt-less Operation}\index{Interrupt} EtherCAT frames travel fp@1588: through the logical EtherCAT ring and are then sent back to the master. fp@1588: Communication is highly deterministic: A frame is sent and will be received fp@1588: again after a constant time, so there is no need to notify the driver about fp@1588: frame reception: The master can instead query the hardware for received fp@1588: frames, if it expects them to be already received. fp@1095: fp@2515: \autoref{fig:interrupt} shows two workflows for cyclic frame transmission fp@1095: and reception with and without interrupts. fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@1202: \includegraphics[width=.9\textwidth]{images/interrupt} fp@369: \caption{Interrupt Operation versus Interrupt-less Operation} fp@369: \label{fig:interrupt} fp@369: \end{figure} fp@369: fp@1095: In the left workflow ``Interrupt Operation'', the data from the last cycle is fp@1095: first processed and a new frame is assembled with new datagrams, which is then fp@1095: sent. The cyclic work is done for now. Later, when the frame is received fp@1095: again by the hardware, an interrupt is triggered and the ISR is executed. The fp@1095: ISR will fetch the frame data from the hardware and initiate the frame fp@1095: dissection: The datagrams will be processed, so that the data is ready for fp@1095: processing in the next cycle. fp@1095: fp@1095: In the right workflow ``Interrupt-less Operation'', there is no hardware fp@1095: interrupt enabled. Instead, the hardware will be polled by the master by fp@1095: executing the ISR. If the frame has been received in the meantime, it will be fp@1095: dissected. The situation is now the same as at the beginning of the left fp@1095: workflow: The received data is processed and a new frame is assembled and fp@1095: sent. There is nothing to do for the rest of the cycle. fp@1095: fp@1202: The interrupt-less operation is desirable, because hardware interrupts are not fp@1202: conducive in improving the driver's realtime behaviour: Their indeterministic fp@1202: incidences contribute to increasing the jitter. Besides, if a realtime fp@1202: extension (like RTAI) is used, some additional effort would have to be made to fp@1202: prioritize interrupts. fp@369: fp@1588: \paragraph{Ethernet and EtherCAT Devices} Another issue lies in the way Linux fp@1588: handles devices of the same type. For example, a fp@1588: PCI\nomenclature{PCI}{Peripheral Component Interconnect, Computer Bus} driver fp@1588: scans the PCI bus for devices it can handle. Then it registers itself as the fp@1588: responsible driver for all of the devices found. The problem is, that an fp@1588: unmodified driver can not be told to ignore a device because it will be used fp@1588: for EtherCAT later. There must be a way to handle multiple devices of the same fp@1588: type, where one is reserved for EtherCAT, while the other is treated as an fp@1588: ordinary Ethernet device. fp@369: fp@1095: For all this reasons, the author decided that the only acceptable solution is fp@1095: to modify standard Ethernet drivers in a way that they keep their normal fp@1095: functionality, but gain the ability to treat one or more of the devices as fp@1095: EtherCAT-capable. fp@369: fp@369: Below are the advantages of this solution: fp@369: fp@369: \begin{itemize} fp@369: \item No need to tell the standard drivers to ignore certain devices. fp@369: \item One networking driver for EtherCAT and non-EtherCAT devices. fp@369: \item No need to implement a network driver from scratch and running fp@369: into issues, the former developers already solved. fp@369: \end{itemize} fp@369: fp@369: The chosen approach has the following disadvantages: fp@369: fp@369: \begin{itemize} fp@369: \item The modified driver gets more complicated, as it must handle fp@369: EtherCAT and non-EtherCAT devices. fp@369: \item Many additional case differentiations in the driver code. fp@1085: \item Changes and bug fixes on the standard drivers have to be ported fp@369: to the Ether\-CAT-capable versions from time to time. fp@369: \end{itemize} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1588: \section{Generic EtherCAT Device Driver} fp@1588: \label{sec:generic-driver} fp@1588: fp@1588: Since there are approaches to enable the complete Linux kernel for realtime fp@1588: operation \cite{rt-preempt}, it is possible to operate without native fp@1588: implementations of EtherCAT-capable Ethernet device drivers and use the Linux fp@2515: network stack instead. \autoref{fig:arch} shows the ``Generic Ethernet Driver fp@1588: Module'', that connects to local Ethernet devices via the network stack. The fp@1588: kernel module is named \lstinline+ec_generic+ and can be loaded after the fp@1588: master module like a native EtherCAT-capable Ethernet driver. fp@1588: fp@1588: The generic device driver scans the network stack for interfaces, that have fp@1588: been registered by Ethernet device drivers. It offers all possible devices to fp@1588: the EtherCAT master. If the master accepts a device, the generic driver fp@1588: creates a packet socket (see \lstinline+man 7 packet+) with fp@1588: \lstinline+socket_type+ set to \lstinline+SOCK_RAW+, bound to that device. All fp@2515: functions of the device interface (see \autoref{sec:ecdev}) will then operate fp@1588: on that socket. fp@1588: fp@1588: Below are the advantages of this solution: fp@1588: fp@1588: \begin{itemize} fp@1588: \item Any Ethernet hardware, that is covered by a Linux Ethernet driver can be fp@1588: used for EtherCAT. fp@1588: \item No modifications have to be made to the actual Ethernet drivers. fp@1588: \end{itemize} fp@1588: fp@1588: The generic approach has the following disadvantages: fp@1588: fp@1588: \begin{itemize} fp@1588: \item The performance is a little worse than the native approach, because the fp@1588: frame data have to traverse the lower layers of the network stack. fp@1588: \item It is not possible to use in-kernel realtime extensions like RTAI with fp@1588: the generic driver, because the network stack code uses dynamic memory fp@1588: allocations and other things, that could cause the system to freeze in fp@1588: realtime context. fp@1588: \end{itemize} fp@1588: fp@2535: \paragraph{Device Activation} In order to send and receive frames through a fp@2535: socket, the Ethernet device linked to that socket has to be activated, fp@2535: otherwise all frames will be rejected. Activation has to take place before the fp@2535: master module is loaded and can happen in several ways: fp@2535: fp@2535: \begin{itemize} fp@2535: fp@2535: \item Ad-hoc, using the command \lstinline+ip link set dev ethX up+ (or the fp@2535: older \lstinline+ifconfig ethX up+), fp@2535: fp@2535: \item Configured, depending on the distribution, for example using fp@2535: \lstinline+ifcfg+ files (\lstinline+/etc/sysconfig/network/ifcfg-ethX+) in fp@2535: openSUSE and others. This is the better choice, if the EtherCAT master shall fp@2535: start at system boot time. Since the Ethernet device shall only be activated, fp@2535: but no IP address etc.\ shall be assigned, it is enough to use fp@2535: \lstinline+STARTMODE=auto+ as configuration. fp@2535: fp@2535: \end{itemize} fp@2535: fp@1588: %------------------------------------------------------------------------------ fp@1588: fp@1588: \section{Providing Ethernet Devices} fp@1588: \label{sec:providing-devices} fp@1588: fp@1588: After loading the master module, additional module(s) have to be loaded to fp@2515: offer devices to the master(s) (see \autoref{sec:ecdev}). The master module fp@1588: knows the devices to choose from the module parameters (see fp@2515: \autoref{sec:mastermod}). If the init script is used to start the master, the fp@1588: drivers and devices to use can be specified in the sysconfig file (see fp@2515: \autoref{sec:sysconfig}). fp@1588: fp@1588: Modules offering Ethernet devices can be fp@1588: fp@1588: \begin{itemize} fp@1588: \item native EtherCAT-capable network driver modules (see fp@2515: \autoref{sec:native-drivers}) or fp@1588: \item the generic EtherCAT device driver module (see fp@2515: \autoref{sec:generic-driver}). fp@1588: \end{itemize} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@2515: \section{Redundancy} fp@2515: \label{sec:redundancy} fp@2515: \index{Redundancy} fp@2515: fp@2515: Redundant bus operation means, that there is more than one Ethernet connection fp@2515: from the master to the slaves. Process data exchange datagrams are sent out on fp@2515: every master link, so that the exchange is still complete, even if the bus is fp@2515: disconnected somewhere in between. fp@2515: fp@2515: Prerequisite for fully redundant bus operation is, that every slave can be fp@2515: reached by at least one master link. In this case a single connection failure fp@2515: (i.\,e.~cable break) will never lead to incomplete process data. Double-faults fp@2515: can not be handled with two Ethernet devices. fp@2515: fp@2515: Redundancy is configured with the \lstinline+--with-devices+ switch at fp@2515: configure time (see \autoref{sec:installation}) and using the fp@2515: \lstinline+backup_devices+ parameter of the \lstinline+ec_master+ kernel fp@2515: module (see \autoref{sec:mastermod}) or the appropriate variable fp@2515: \lstinline+MASTERx_BACKUP+ in the (sys-)config file (see fp@2515: \autoref{sec:sysconfig}). fp@2515: fp@2515: Bus scanning is done after a topology change on any Ethernet link. The fp@2515: application interface (see \autoref{chap:api}) and the command-line tool (see fp@2515: \autoref{sec:tool}) both have methods to query the status of the redundant fp@2515: operation. fp@2515: fp@2515: %------------------------------------------------------------------------------ fp@2515: fp@1203: \section{EtherCAT Device Interface} fp@369: \label{sec:ecdev} fp@369: \index{Device interface} fp@369: fp@369: An anticipation to the section about the master module fp@2515: (\autoref{sec:mastermod}) has to be made in order to understand the way, a fp@1289: network device driver module can connect a device to a specific EtherCAT fp@1289: master. fp@369: fp@1202: The master module provides a ``device interface'' for network device drivers. fp@1202: To use this interface, a network device driver module must include the header fp@1202: \textit{devices/ecdev.h}\nomenclature{ecdev}{EtherCAT Device}, coming with the fp@1202: EtherCAT master code. This header offers a function interface for EtherCAT fp@1202: devices. All functions of the device interface are named with the prefix fp@1202: \lstinline+ecdev+. fp@1202: fp@1289: The documentation of the device interface can be found in the header file or fp@1289: in the appropriate module of the interface documentation (see fp@2515: \autoref{sec:gendoc} for generation instructions). fp@1202: fp@1296: % TODO general description of the device interface fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1588: \section{Patching Native Network Drivers} fp@369: \label{sec:patching} fp@369: \index{Network drivers} fp@369: fp@1202: This section will describe, how to make a standard Ethernet driver fp@1588: EtherCAT-capable, using the native approach (see fp@2515: \autoref{sec:native-drivers}). Unfortunately, there is no standard procedure fp@1588: to enable an Ethernet driver for use with the EtherCAT master, but there are a fp@1588: few common techniques. fp@369: fp@369: \begin{enumerate} fp@1202: fp@1202: \item A first simple rule is, that \lstinline+netif_*()+ calls must be avoided fp@1202: for all EtherCAT devices. As mentioned before, EtherCAT devices have no fp@1202: connection to the network stack, and therefore must not call its interface fp@1202: functions. fp@1202: fp@1202: \item Another important thing is, that EtherCAT devices should be operated fp@1202: without interrupts. So any calls of registering interrupt handlers and enabling fp@1202: interrupts at hardware level must be avoided, too. fp@1202: fp@1202: \item The master does not use a new socket buffer for each send operation: fp@1202: Instead there is a fix one allocated on master initialization. This socket fp@1202: buffer is filled with an EtherCAT frame with every send operation and passed to fp@1202: the \lstinline+hard_start_xmit()+ callback. For that it is necessary, that the fp@1202: socket buffer is not be freed by the network driver as usual. fp@1202: fp@369: \end{enumerate} fp@369: fp@1202: An Ethernet driver usually handles several Ethernet devices, each described by fp@1202: a \lstinline+net_device+ structure with a \lstinline+priv_data+ field to fp@1202: attach driver-dependent data to the structure. To distinguish between normal fp@1202: Ethernet devices and the ones used by EtherCAT masters, the private data fp@1202: structure used by the driver could be extended by a pointer, that points to an fp@1202: \lstinline+ec_device_t+ object returned by \lstinline+ecdev_offer()+ (see fp@2515: \autoref{sec:ecdev}) if the device is used by a master and otherwise is zero. fp@1202: fp@1202: The RealTek RTL-8139 Fast Ethernet driver is a ``simple'' Ethernet driver and fp@1202: can be taken as an example to patch new drivers. The interesting sections can fp@1202: be found by searching the string ``ecdev" in the file fp@1202: \textit{devices/8139too-2.6.24-ethercat.c}. fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1085: \chapter{State Machines} fp@369: \label{sec:fsm} fp@369: \index{FSM} fp@369: fp@1085: Many parts of the EtherCAT master are implemented as \textit{finite state fp@1085: machines} (FSMs\nomenclature{FSM}{Finite State Machine}). Though this leads fp@1085: to a higher grade of complexity in some aspects, is opens many new fp@1085: possibilities. fp@369: fp@369: The below short code example exemplary shows how to read all slave fp@369: states and moreover illustrates the restrictions of ``sequential'' fp@369: coding: fp@369: fp@1085: \begin{lstlisting}[gobble=2,language=C,numbers=left] fp@369: ec_datagram_brd(datagram, 0x0130, 2); // prepare datagram fp@369: if (ec_master_simple_io(master, datagram)) return -1; fp@369: slave_states = EC_READ_U8(datagram->data); // process datagram fp@369: \end{lstlisting} fp@369: fp@1085: The \textit{ec\_master\_simple\_io()} function provides a simple interface for fp@1085: synchronously sending a single datagram and receiving the result\footnote{For fp@1085: all communication issues have been meanwhile sourced out into state machines, fp@1085: the function is deprecated and stopped existing. Nevertheless it is adequate fp@1085: for showing it's own restrictions.}. Internally, it queues the specified fp@1085: datagram, invokes the \textit{ec\_master\_send\_datagrams()} function to send fp@1085: a frame with the queued datagram and then waits actively for its reception. fp@369: fp@1289: This sequential approach is very simple, reflecting in only three lines of fp@1289: code. The disadvantage is, that the master is blocked for the time it waits fp@1289: for datagram reception. There is no difficulty when only one instance is using fp@1289: the master, but if more instances want to (synchronously\footnote{At this fp@1289: time, synchronous master access will be adequate to show the advantages of an fp@2515: FSM. The asynchronous approach will be discussed in \autoref{sec:eoe}}) use fp@1289: the master, it is inevitable to think about an alternative to the sequential fp@1289: model. fp@369: fp@369: Master access has to be sequentialized for more than one instance fp@369: wanting to send and receive datagrams synchronously. With the present fp@369: approach, this would result in having one phase of active waiting for fp@369: each instance, which would be non-acceptable especially in realtime fp@369: circumstances, because of the huge time overhead. fp@369: fp@369: A possible solution is, that all instances would be executed fp@369: sequentially to queue their datagrams, then give the control to the fp@369: next instance instead of waiting for the datagram reception. Finally, fp@369: bus IO is done by a higher instance, which means that all queued fp@369: datagrams are sent and received. The next step is to execute all fp@369: instances again, which then process their received datagrams and issue fp@369: new ones. fp@369: fp@369: This approach results in all instances having to retain their state, fp@369: when giving the control back to the higher instance. It is quite fp@369: obvious to use a \textit{finite state machine} model in this case. fp@2515: \autoref{sec:fsmtheory} will introduce some of the theory used, fp@369: while the listings below show the basic approach by coding the example fp@369: from above as a state machine: fp@369: fp@1085: \begin{lstlisting}[gobble=2,language=C,numbers=left] fp@369: // state 1 fp@369: ec_datagram_brd(datagram, 0x0130, 2); // prepare datagram fp@369: ec_master_queue(master, datagram); // queue datagram fp@369: next_state = state_2; fp@369: // state processing finished fp@369: \end{lstlisting} fp@369: fp@369: After all instances executed their current state and queued their fp@369: datagrams, these are sent and received. Then the respective next fp@369: states are executed: fp@369: fp@1085: \begin{lstlisting}[gobble=2,language=C,numbers=left] fp@369: // state 2 fp@369: if (datagram->state != EC_DGRAM_STATE_RECEIVED) { fp@369: next_state = state_error; fp@369: return; // state processing finished fp@369: } fp@369: slave_states = EC_READ_U8(datagram->data); // process datagram fp@369: // state processing finished. fp@369: \end{lstlisting} fp@369: fp@2515: See \autoref{sec:statemodel} for an introduction to the state machine fp@1289: programming concept used in the master code. fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1085: \section{State Machine Theory} fp@369: \label{sec:fsmtheory} fp@369: \index{FSM!Theory} fp@369: fp@369: A finite state machine \cite{automata} is a model of behavior with fp@369: inputs and outputs, where the outputs not only depend on the inputs, fp@369: but the history of inputs. The mathematical definition of a finite fp@369: state machine (or finite automaton) is a six-tuple $(\Sigma, \Gamma, fp@369: S, s_0, \delta, \omega)$, with fp@369: fp@369: \begin{itemize} fp@369: \item the input alphabet $\Sigma$, with $\Sigma \neq fp@369: \emptyset$, containing all input symbols, fp@369: \item the output alphabet $\Gamma$, with $\Gamma \neq fp@369: \emptyset$, containing all output symbols, fp@369: \item the set of states $S$, with $S \neq \emptyset$, fp@369: \item the set of initial states $s_0$ with $s_0 \subseteq S, s_0 \neq fp@369: \emptyset$ fp@369: \item the transition function $\delta: S \times \Sigma \rightarrow S fp@369: \times \Gamma$ fp@369: \item the output function $\omega$. fp@369: \end{itemize} fp@369: fp@369: The state transition function $\delta$ is often specified by a fp@369: \textit{state transition table}, or by a \textit{state transition fp@369: diagram}. The transition table offers a matrix view of the state fp@2515: machine behavior (see \autoref{tab:statetrans}). The matrix rows fp@369: correspond to the states ($S = \{s_0, s_1, s_2\}$) and the columns fp@369: correspond to the input symbols ($\Gamma = \{a, b, \varepsilon\}$). fp@369: The table contents in a certain row $i$ and column $j$ then represent fp@369: the next state (and possibly the output) for the case, that a certain fp@369: input symbol $\sigma_j$ is read in the state $s_i$. fp@369: fp@369: \begin{table}[htbp] fp@369: \caption{A typical state transition table} fp@369: \label{tab:statetrans} fp@369: \vspace{2mm} fp@369: \centering fp@369: \begin{tabular}{l|ccc} fp@369: & $a$ & $b$ & $\varepsilon$\\ \hline fp@369: $s_0$ & $s_1$ & $s_1$ & $s_2$\\ fp@369: $s_1$ & $s_2$ & $s_1$ & $s_0$\\ fp@369: $s_2$ & $s_0$ & $s_0$ & $s_0$\\ \hline fp@369: \end{tabular} fp@369: \end{table} fp@369: fp@369: The state diagram for the same example looks like the one in fp@2515: \autoref{fig:statetrans}. The states are represented as circles or fp@369: ellipses and the transitions are drawn as arrows between them. Close fp@369: to a transition arrow can be the condition that must be fulfilled to fp@369: allow the transition. The initial state is marked by a filled black fp@369: circle with an arrow pointing to the respective state. fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@369: \includegraphics[width=.5\textwidth]{images/statetrans} fp@369: \caption{A typical state transition diagram} fp@369: \label{fig:statetrans} fp@369: \end{figure} fp@369: fp@369: \paragraph{Deterministic and non-deterministic state machines} fp@369: fp@369: A state machine can be deterministic, meaning that for one state and fp@369: input, there is one (and only one) following state. In this case, the fp@369: state machine has exactly one starting state. Non-deterministic state fp@369: machines can have more than one transitions for a single state-input fp@369: combination. There is a set of starting states in the latter case. fp@369: fp@369: \paragraph{Moore and Mealy machines} fp@369: fp@369: There is a distinction between so-called \textit{Moore machines}, and fp@369: \textit{Mealy machines}. Mathematically spoken, the distinction lies fp@369: in the output function $\omega$: If it only depends on the current fp@369: state ($\omega: S \rightarrow \Gamma$), the machine corresponds to the fp@369: ``Moore Model''. Otherwise, if $\omega$ is a function of a state and fp@369: the input alphabet ($\omega: S \times \Sigma \rightarrow \Gamma$) the fp@369: state machine corresponds to the ``Mealy model''. Mealy machines are fp@369: the more practical solution in most cases, because their design allows fp@369: machines with a minimum number of states. In practice, a mixture of fp@369: both models is often used. fp@369: fp@369: \paragraph{Misunderstandings about state machines} fp@369: fp@1085: There is a phenomenon called ``state explosion'', that is often taken as a fp@1085: counter-argument against general use of state machines in complex environments. fp@1085: It has to be mentioned, that this point is misleading~\cite{fsmmis}. State fp@1085: explosions happen usually as a result of a bad state machine design: Common fp@1085: mistakes are storing the present values of all inputs in a state, or not fp@1085: dividing a complex state machine into simpler sub state machines. The EtherCAT fp@1085: master uses several state machines, that are executed hierarchically and so fp@1085: serve as sub state machines. These are also described below. fp@1085: fp@1085: %------------------------------------------------------------------------------ fp@1085: fp@1085: \section{The Master's State Model} fp@369: \label{sec:statemodel} fp@369: fp@369: This section will introduce the techniques used in the master to fp@369: implement state machines. fp@369: fp@369: \paragraph{State Machine Programming} fp@369: fp@369: There are certain ways to implement a state machine in \textit{C} fp@369: code. An obvious way is to implement the different states and actions fp@369: by one big case differentiation: fp@369: fp@1085: \begin{lstlisting}[gobble=2,language=C,numbers=left] fp@369: enum {STATE_1, STATE_2, STATE_3}; fp@369: int state = STATE_1; fp@369: fp@369: void state_machine_run(void *priv_data) { fp@369: switch (state) { fp@369: case STATE_1: fp@369: action_1(); fp@369: state = STATE_2; fp@369: break; fp@369: case STATE_2: fp@369: action_2() fp@369: if (some_condition) state = STATE_1; fp@369: else state = STATE_3; fp@369: break; fp@369: case STATE_3: fp@369: action_3(); fp@369: state = STATE_1; fp@369: break; fp@369: } fp@369: } fp@369: \end{lstlisting} fp@369: fp@369: For small state machines, this is an option. The disadvantage is, that fp@369: with an increasing number of states the code soon gets complex and an fp@369: additional case differentiation is executed each run. Besides, lots of fp@369: indentation is wasted. fp@369: fp@369: The method used in the master is to implement every state in an own fp@369: function and to store the current state function with a function fp@369: pointer: fp@369: fp@1085: \begin{lstlisting}[gobble=2,language=C,numbers=left] fp@369: void (*state)(void *) = state1; fp@369: fp@369: void state_machine_run(void *priv_data) { fp@369: state(priv_data); fp@369: } fp@369: fp@369: void state1(void *priv_data) { fp@369: action_1(); fp@369: state = state2; fp@369: } fp@369: fp@369: void state2(void *priv_data) { fp@369: action_2(); fp@369: if (some_condition) state = state1; fp@369: else state = state2; fp@369: } fp@369: fp@369: void state3(void *priv_data) { fp@369: action_3(); fp@369: state = state1; fp@369: } fp@369: \end{lstlisting} fp@369: fp@1085: In the master code, state pointers of all state machines\footnote{All except fp@1085: for the EoE state machine, because multiple EoE slaves have to be handled in fp@1085: parallel. For this reason each EoE handler object has its own state pointer.} fp@1202: are gathered in a single object of the \lstinline+ec_fsm_master_t+ class. This fp@1202: is advantageous, because there is always one instance of every state machine fp@1085: available and can be started on demand. fp@369: fp@369: \paragraph{Mealy and Moore} fp@369: fp@1202: If a closer look is taken to the above listing, it can be seen that the fp@1202: actions executed (the ``outputs'' of the state machine) only depend on the fp@1202: current state. This accords to the ``Moore'' model introduced in fp@2515: \autoref{sec:fsmtheory}. As mentioned, the ``Mealy'' model offers a higher fp@1202: flexibility, which can be seen in the listing below: fp@369: fp@1085: \begin{lstlisting}[gobble=2,language=C,numbers=left] fp@369: void state7(void *priv_data) { fp@369: if (some_condition) { fp@369: action_7a(); fp@369: state = state1; fp@369: } fp@369: else { fp@369: action_7b(); fp@369: state = state8; fp@369: } fp@369: } fp@369: \end{lstlisting} fp@369: fp@369: \begin{description} fp@1202: fp@1202: \item[\linenum{3} + \linenum{7}] The state function executes the actions fp@1202: depending on the state transition, that is about to be done. fp@1202: fp@369: \end{description} fp@369: fp@369: The most flexible alternative is to execute certain actions depending fp@369: on the state, followed by some actions dependent on the state fp@369: transition: fp@369: fp@1085: \begin{lstlisting}[gobble=2,language=C,numbers=left] fp@369: void state9(void *priv_data) { fp@369: action_9(); fp@369: if (some_condition) { fp@369: action_9a(); fp@369: state = state7; fp@369: } fp@369: else { fp@369: action_9b(); fp@369: state = state10; fp@369: } fp@369: } fp@369: \end{lstlisting} fp@369: fp@1202: This model is often used in the master. It combines the best aspects of both fp@1202: approaches. fp@369: fp@369: \paragraph{Using Sub State Machines} fp@369: fp@1202: To avoid having too much states, certain functions of the EtherCAT master fp@1202: state machine have been sourced out into sub state machines. This helps to fp@1085: encapsulate the related workflows and moreover avoids the ``state explosion'' fp@2515: phenomenon described in \autoref{sec:fsmtheory}. If the master would instead fp@1289: use one big state machine, the number of states would be a multiple of the fp@1289: actual number. This would increase the level of complexity to a non-manageable fp@1289: grade. fp@369: fp@369: \paragraph{Executing Sub State Machines} fp@369: fp@369: If a state machine starts to execute a sub state machine, it usually fp@369: remains in one state until the sub state machine terminates. This is fp@369: usually done like in the listing below, which is taken out of the fp@369: slave configuration state machine code: fp@369: fp@1085: \begin{lstlisting}[gobble=2,language=C,numbers=left] fp@813: void ec_fsm_slaveconf_safeop(ec_fsm_t *fsm) fp@369: { fp@369: fsm->change_state(fsm); // execute state change fp@369: // sub state machine fp@369: fp@369: if (fsm->change_state == ec_fsm_error) { fp@369: fsm->slave_state = ec_fsm_end; fp@369: return; fp@369: } fp@369: fp@369: if (fsm->change_state != ec_fsm_end) return; fp@369: fp@369: // continue state processing fp@369: ... fp@369: \end{lstlisting} fp@369: fp@369: \begin{description} fp@1202: fp@1202: \item[\linenum{3}] \lstinline+change_state+ is the state pointer of the state fp@1202: change state machine. The state function, the pointer points on, is fp@1202: executed\ldots fp@1202: fp@1202: \item[\linenum{6}] \ldots either until the state machine terminates with the fp@1202: error state \ldots fp@1202: fp@1202: \item[\linenum{11}] \ldots or until the state machine terminates in the end fp@1202: state. Until then, the ``higher'' state machine remains in the current state fp@1202: and executes the sub state machine again in the next cycle. fp@1202: fp@369: \end{description} fp@369: fp@369: \paragraph{State Machine Descriptions} fp@369: fp@1202: The below sections describe every state machine used in the EtherCAT master. fp@1202: The textual descriptions of the state machines contain references to the fp@1202: transitions in the corresponding state transition diagrams, that are marked fp@1202: with an arrow followed by the name of the successive state. Transitions caused fp@1306: by trivial error cases (i.\,e.\ no response from slave) are not described fp@1202: explicitly. These transitions are drawn as dashed arrows in the diagrams. fp@1202: fp@1202: %------------------------------------------------------------------------------ fp@1202: fp@1202: \section{The Master State Machine} fp@1202: \label{sec:fsm-master} fp@1202: \index{FSM!Master} fp@1202: fp@1202: The master state machine is executed in the context of the master thread. fp@2515: \autoref{fig:fsm-master} shows its transition diagram. Its purposes are: fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@1202: \includegraphics[width=\textwidth]{graphs/fsm_master} fp@1202: \caption{Transition diagram of the master state machine} fp@1202: \label{fig:fsm-master} fp@369: \end{figure} fp@369: fp@369: \begin{description} fp@1202: fp@1202: \item[Bus monitoring] The bus topology is monitored. If it changes, the bus is fp@1202: (re-)scanned. fp@1202: fp@1202: \item[Slave configuration] The application-layer states of the slaves are fp@1202: monitored. If a slave is not in the state it supposed to be, the slave is fp@1202: (re-)configured. fp@1202: fp@1202: \item[Request handling] Requests (either originating from the application or fp@1203: from external sources) are handled. A request is a job that the master shall fp@1327: process asynchronously, for example an SII access, SDO access, or similar. fp@369: fp@369: \end{description} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1085: \section{The Slave Scan State Machine} fp@369: \label{sec:fsm-scan} fp@369: \index{FSM!Slave Scan} fp@369: fp@369: The slave scan state machine, which can be seen in fp@2515: \autoref{fig:fsm-slavescan}, leads through the process of reading desired fp@1202: slave information. fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@1202: \includegraphics[height=.8\textheight]{graphs/fsm_slave_scan} fp@369: \caption{Transition diagram of the slave scan state machine} fp@369: \label{fig:fsm-slavescan} fp@369: \end{figure} fp@369: fp@1202: The scan process includes the following steps: fp@1202: fp@369: \begin{description} fp@1202: fp@1202: \item[Node Address] The node address is set for the slave, so that it can be fp@1202: node-addressed for all following operations. fp@1202: fp@1202: \item[AL State] The initial application-layer state is read. fp@1202: fp@1202: \item[Base Information] Base information (like the number of supported FMMUs) fp@1202: is read from the lower physical memory. fp@1202: fp@1202: \item[Data Link] Information about the physical ports is read. fp@1202: fp@1202: \item[SII Size] The size of the SII contents is determined to allocate SII fp@1202: image memory. fp@1202: fp@1202: \item[SII Data] The SII contents are read into the master's image. fp@1202: fp@1202: \item[PREOP] If the slave supports CoE, it is set to PREOP state using the fp@2515: State change FSM (see \autoref{sec:fsm-change}) to enable mailbox fp@1327: communication and read the PDO configuration via CoE. fp@1327: fp@1327: \item[PDOs] The PDOs are read via CoE (if supported) using the PDO Reading FSM fp@2515: (see \autoref{sec:fsm-pdo}). If this is successful, the PDO information from fp@1289: the SII (if any) is overwritten. fp@369: fp@369: \end{description} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1085: \section{The Slave Configuration State Machine} fp@369: \label{sec:fsm-conf} fp@369: \index{FSM!Slave Configuration} fp@369: fp@369: The slave configuration state machine, which can be seen in fp@2515: \autoref{fig:fsm-slaveconf}, leads through the process of configuring a fp@1202: slave and bringing it to a certain application-layer state. fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@1406: \includegraphics[height=\textheight]{graphs/fsm_slave_conf} fp@369: \caption{Transition diagram of the slave configuration state fp@369: machine} fp@369: \label{fig:fsm-slaveconf} fp@369: \end{figure} fp@369: fp@369: \begin{description} fp@1202: fp@1202: \item[INIT] The state change FSM is used to bring the slave to the INIT state. fp@1202: fp@1202: \item[FMMU Clearing] To avoid that the slave reacts on any process data, the fp@1202: FMMU configuration are cleared. If the slave does not support FMMUs, this fp@1202: state is skipped. If INIT is the requested state, the state machine is fp@1202: finished. fp@1202: fp@1202: \item[Mailbox Sync Manager Configuration] If the slaves support mailbox fp@1202: communication, the mailbox sync managers are configured. Otherwise this state fp@1202: is skipped. fp@1202: fp@1202: \item[PREOP] The state change FSM is used to bring the slave to PREOP state. fp@1202: If this is the requested state, the state machine is finished. fp@1202: fp@1327: \item[SDO Configuration] If there is a slave configuration attached (see fp@2515: \autoref{sec:masterconfig}), and there are any SDO configurations are fp@1202: provided by the application, these are sent to the slave. fp@1202: fp@1327: \item[PDO Configuration] The PDO configuration state machine is executed to fp@1327: apply all necessary PDO configurations. fp@1327: fp@1327: \item[PDO Sync Manager Configuration] If any PDO sync managers exist, they are fp@1202: configured. fp@1202: fp@1202: \item[FMMU Configuration] If there are FMMUs configurations supplied by the fp@1327: application (i.\,e.\ if the application registered PDO entries), they are fp@2421: applied. fp@1202: fp@1202: \item[SAFEOP] The state change FSM is used to bring the slave to SAFEOP state. fp@1202: If this is the requested state, the state machine is finished. fp@1202: fp@1202: \item[OP] The state change FSM is used to bring the slave to OP state. fp@1202: If this is the requested state, the state machine is finished. fp@369: fp@369: \end{description} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1085: \section{The State Change State Machine} fp@369: \label{sec:fsm-change} fp@369: \index{FSM!State Change} fp@369: fp@369: The state change state machine, which can be seen in fp@2515: \autoref{fig:fsm-change}, leads through the process of changing a slave's fp@1202: application-layer state. This implements the states and transitions described fp@1289: in \cite[sec.~6.4.1]{alspec}. fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@1203: \includegraphics[width=.6\textwidth]{graphs/fsm_change} fp@1202: \caption{Transition Diagram of the State Change State Machine} fp@369: \label{fig:fsm-change} fp@369: \end{figure} fp@369: fp@369: \begin{description} fp@1203: fp@1203: \item[Start] The new application-layer state is requested via the ``AL Control fp@1306: Request'' register (see~\cite[sec. 5.3.1]{alspec}). fp@1203: fp@1203: \item[Check for Response] Some slave need some time to respond to an AL state fp@1203: change command, and do not respond for some time. For this case, the command fp@1203: is issued again, until it is acknowledged. fp@1203: fp@1203: \item[Check AL Status] If the AL State change datagram was acknowledged, the fp@1289: ``AL Control Response'' register (see~\cite[sec. 5.3.2]{alspec}) must be read fp@1289: out until the slave changes the AL state. fp@1203: fp@1203: \item[AL Status Code] If the slave refused the state change command, the fp@1203: reason can be read from the ``AL Status Code'' field in the ``AL State fp@1289: Changed'' registers (see~\cite[sec. 5.3.3]{alspec}). fp@1203: fp@1203: \item[Acknowledge State] If the state change was not successful, the master fp@1203: has to acknowledge the old state by writing to the ``AL Control request'' fp@1203: register again. fp@1203: fp@1203: \item[Check Acknowledge] After sending the acknowledge command, it has to read fp@1203: out the ``AL Control Response'' register again. fp@369: fp@369: \end{description} fp@369: fp@1203: The ``start\_ack'' state is a shortcut in the state machine for the case, that fp@1203: the master wants to acknowledge a spontaneous AL state change, that was not fp@1203: requested. fp@1203: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1085: \section{The SII State Machine} fp@369: \label{sec:fsm-sii} fp@369: \index{FSM!SII} fp@369: fp@2515: The SII\index{SII} state machine (shown in \autoref{fig:fsm-sii}) fp@1289: implements the process of reading or writing SII data via the Slave fp@1289: Information Interface described in \cite[sec.~6.4]{dlspec}. fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@1203: \includegraphics[width=.5\textwidth]{graphs/fsm_sii} fp@1202: \caption{Transition Diagram of the SII State Machine} fp@369: \label{fig:fsm-sii} fp@369: \end{figure} fp@369: fp@1203: This is how the reading part of the state machine works: fp@1202: fp@369: \begin{description} fp@1203: fp@1203: \item[Start Reading] The read request and the requested word address are fp@1203: written to the SII attribute. fp@1203: fp@1203: \item[Check Read Command] If the SII read request command has been fp@1203: acknowledged, a timer is started. A datagram is issued, that reads out the SII fp@1203: attribute for state and data. fp@1203: fp@1203: \item[Fetch Data] If the read operation is still busy (the SII is usually fp@1203: implemented as an E$^2$PROM), the state is read again. Otherwise the data are fp@1203: copied from the datagram. fp@1203: fp@369: \end{description} fp@369: fp@1203: The writing part works nearly similar: fp@369: fp@369: \begin{description} fp@1203: fp@1203: \item[Start Writing] A write request, the target address and the data word are fp@1203: written to the SII attribute. fp@1203: fp@1203: \item[Check Write Command] If the SII write request command has been fp@1203: acknowledged, a timer is started. A datagram is issued, that reads out the SII fp@1203: attribute for the state of the write operation. fp@1203: fp@1203: \item[Wait while Busy] If the write operation is still busy (determined by a fp@1203: minimum wait time and the state of the busy flag), the state machine remains in fp@1203: this state to avoid that another write operation is issued too early. fp@1203: fp@369: \end{description} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1327: \section{The PDO State Machines} fp@1203: \label{sec:fsm-pdo} fp@1327: \index{FSM!PDO} fp@1327: fp@1327: The PDO state machines are a set of state machines that read or write the PDO fp@1327: assignment and the PDO mapping via the ``CoE Communication Area'' described in fp@1327: \cite[sec. 5.6.7.4]{alspec}. For the object access, the CANopen over EtherCAT fp@2515: access primitives are used (see \autoref{sec:coe}), so the slave must support fp@1289: the CoE mailbox protocol. fp@1203: fp@2515: \paragraph{PDO Reading FSM} This state machine (\autoref{fig:fsm-pdo-read}) fp@1327: has the purpose to read the complete PDO configuration of a slave. It reads fp@1327: the PDO assignment for each Sync Manager and uses the PDO Entry Reading FSM fp@2515: (\autoref{fig:fsm-pdo-entry-read}) to read the mapping for each assigned PDO. fp@1203: fp@1203: \begin{figure}[htbp] fp@1203: \centering fp@1203: \includegraphics[width=.4\textwidth]{graphs/fsm_pdo_read} fp@1327: \caption{Transition Diagram of the PDO Reading State Machine} fp@1203: \label{fig:fsm-pdo-read} fp@1203: \end{figure} fp@1203: fp@1327: Basically it reads the every Sync manager's PDO assignment SDO's fp@1203: (\lstinline+0x1C1x+) number of elements to determine the number of assigned fp@1327: PDOs for this sync manager and then reads out the subindices of the SDO to get fp@1327: the assigned PDO's indices. When a PDO index is read, the PDO Entry Reading fp@1327: FSM is executed to read the PDO's mapped PDO entries. fp@1327: fp@1327: \paragraph{PDO Entry Reading FSM} This state machine fp@2515: (\autoref{fig:fsm-pdo-entry-read}) reads the PDO mapping (the PDO entries) of fp@1327: a PDO. It reads the respective mapping SDO (\lstinline+0x1600+ -- fp@1293: \lstinline+0x17ff+, or \lstinline+0x1a00+ -- \lstinline+0x1bff+) for the given fp@1327: PDO by reading first the subindex zero (number of elements) to determine the fp@1327: number of mapped PDO entries. After that, each subindex is read to get the fp@1327: mapped PDO entry index, subindex and bit size. fp@1203: fp@1203: \begin{figure}[htbp] fp@1203: \centering fp@1203: \includegraphics[width=.4\textwidth]{graphs/fsm_pdo_entry_read} fp@1327: \caption{Transition Diagram of the PDO Entry Reading State Machine} fp@1204: \label{fig:fsm-pdo-entry-read} fp@1203: \end{figure} fp@1203: fp@1203: \begin{figure}[htbp] fp@1203: \centering fp@1203: \includegraphics[width=.9\textwidth]{graphs/fsm_pdo_conf} fp@1327: \caption{Transition Diagram of the PDO Configuration State Machine} fp@1204: \label{fig:fsm-pdo-conf} fp@1203: \end{figure} fp@1203: fp@1203: \begin{figure}[htbp] fp@1203: \centering fp@1203: \includegraphics[width=.4\textwidth]{graphs/fsm_pdo_entry_conf} fp@1327: \caption{Transition Diagram of the PDO Entry Configuration State Machine} fp@1204: \label{fig:fsm-pdo-entry-conf} fp@1203: \end{figure} fp@1203: fp@1203: %------------------------------------------------------------------------------ fp@1203: fp@1085: \chapter{Mailbox Protocol Implementations} fp@369: \index{Mailbox} fp@369: fp@1917: The EtherCAT master implements the CANopen over EtherCAT (CoE), Ethernet over fp@1917: EtherCAT (EoE), File-access over EtherCAT (FoE), Vendor-specific over EtherCAT fp@1917: (VoE) and Servo Profile over EtherCAT (SoE) mailbox protocols. See the below fp@1917: sections for details. fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1327: \section{Ethernet over EtherCAT (EoE)} fp@1269: \label{sec:eoe} fp@369: \index{EoE} fp@369: fp@1306: The EtherCAT master implements the fp@1327: Ethernet over EtherCAT\nomenclature{EoE}{Ethernet over EtherCAT, Mailbox fp@1306: Protocol} mailbox protocol~\cite[sec.~5.7]{alspec} to enable the tunneling of fp@1306: Ethernet frames to special slaves, that can either have physical Ethernet fp@1306: ports to forward the frames to, or have an own IP stack to receive the frames. fp@369: fp@369: \paragraph{Virtual Network Interfaces} fp@369: fp@1202: The master creates a virtual EoE network interface for every EoE-capable fp@1202: slave. These interfaces are called either fp@1202: fp@1202: \begin{description} fp@1202: fp@1293: \item[eoeXsY] for a slave without an alias address (see fp@2515: \autoref{sec:ethercat-alias}), where X is the master index and Y is the fp@1293: slave's ring position, or fp@1202: fp@1202: \item[eoeXaY] for a slave with a non-zero alias address, where X is the master fp@1202: index and Y is the decimal alias address. fp@1202: fp@1202: \end{description} fp@1202: fp@1202: Frames sent to these interfaces are forwarded to the associated slaves by the fp@1202: master. Frames, that are received by the slaves, are fetched by the master and fp@1202: forwarded to the virtual interfaces. fp@369: fp@369: This bears the following advantages: fp@369: fp@369: \begin{itemize} fp@1202: fp@369: \item Flexibility: The user can decide, how the EoE-capable slaves are fp@1202: interconnected with the rest of the world. fp@1202: fp@1202: \item Standard tools can be used to monitor the EoE activity and to configure fp@1202: the EoE interfaces. fp@1202: fp@1202: \item The Linux kernel's layer-2-bridging implementation (according to the fp@1202: IEEE 802.1D MAC Bridging standard) can be used natively to bridge Ethernet fp@1202: traffic between EoE-capable slaves. fp@1202: fp@1202: \item The Linux kernel's network stack can be used to route packets between fp@1202: EoE-capable slaves and to track security issues, just like having physical fp@1202: network interfaces. fp@1202: fp@369: \end{itemize} fp@369: fp@369: \paragraph{EoE Handlers} fp@369: fp@1202: The virtual EoE interfaces and the related functionality is encapsulated in fp@1202: the \lstinline+ec_eoe_t+ class. An object of this class is called ``EoE fp@1202: handler''. For example the master does not create the network interfaces fp@1202: directly: This is done inside the constructor of an EoE handler. An EoE fp@1202: handler additionally contains a frame queue. Each time, the kernel passes a fp@1202: new socket buffer for sending via the interface's fp@1202: \lstinline+hard_start_xmit()+ callback, the socket buffer is queued for fp@1202: transmission by the EoE state machine (see below). If the queue gets filled fp@1202: up, the passing of new socket buffers is suspended with a call to fp@1202: \lstinline+netif_stop_queue()+. fp@1202: fp@1202: \paragraph{Creation of EoE Handlers} fp@1202: fp@2515: During bus scanning (see \autoref{sec:fsm-scan}), the master determines the fp@1289: supported mailbox protocols foe each slave. This is done by examining the fp@1202: ``Supported Mailbox Protocols'' mask field at word address 0x001C of the fp@1202: SII\index{SII}. If bit 1 is set, the slave supports the EoE protocol. In this fp@1202: case, an EoE handler is created for that slave. fp@369: fp@369: \paragraph{EoE State Machine} fp@369: \index{FSM!EoE} fp@369: fp@1202: Every EoE handler owns an EoE state machine, that is used to send frames to fp@1202: the corresponding slave and receive frames from the it via the EoE fp@369: communication primitives. This state machine is showed in fp@2515: \autoref{fig:fsm-eoe}. fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@1202: \includegraphics[width=.7\textwidth]{images/fsm-eoe} % FIXME fp@1202: \caption{Transition Diagram of the EoE State Machine} fp@369: \label{fig:fsm-eoe} fp@369: \end{figure} fp@369: fp@1202: % FIXME fp@1202: fp@369: \begin{description} fp@369: \item[RX\_START] The beginning state of the EoE state machine. A fp@369: mailbox check datagram is sent, to query the slave's mailbox for new fp@379: frames. $\rightarrow$~RX\_CHECK fp@369: fp@369: \item[RX\_CHECK] The mailbox check datagram is received. If the fp@369: slave's mailbox did not contain data, a transmit cycle is started. fp@379: $\rightarrow$~TX\_START fp@369: fp@369: If there are new data in the mailbox, a datagram is sent to fetch fp@379: the new data. $\rightarrow$~RX\_FETCH fp@369: fp@369: \item[RX\_FETCH] The fetch datagram is received. If the mailbox data fp@369: do not contain a ``EoE Fragment request'' command, the data are fp@369: dropped and a transmit sequence is started. fp@379: $\rightarrow$~TX\_START fp@369: fp@369: If the received Ethernet frame fragment is the first fragment, a new fp@369: socket buffer is allocated. In either case, the data are copied into fp@369: the correct position of the socket buffer. fp@369: fp@369: If the fragment is the last fragment, the socket buffer is forwarded fp@369: to the network stack and a transmit sequence is started. fp@379: $\rightarrow$~TX\_START fp@369: fp@369: Otherwise, a new receive sequence is started to fetch the next fp@379: fragment. $\rightarrow$~RX\_\-START fp@369: fp@369: \item[TX\_START] The beginning state of a transmit sequence. It is fp@1085: checked, if the transmission queue contains a frame to send. If not, fp@379: a receive sequence is started. $\rightarrow$~RX\_START fp@369: fp@369: If there is a frame to send, it is dequeued. If the queue was fp@369: inactive before (because it was full), the queue is woken up with a fp@369: call to \textit{netif\_wake\_queue()}. The first fragment of the fp@379: frame is sent. $\rightarrow$~TX\_SENT fp@369: fp@369: \item[TX\_SENT] It is checked, if the first fragment was sent fp@369: successfully. If the current frame consists of further fragments, fp@379: the next one is sent. $\rightarrow$~TX\_SENT fp@369: fp@369: If the last fragment was sent, a new receive sequence is started. fp@379: $\rightarrow$~RX\_START fp@369: \end{description} fp@369: fp@369: \paragraph{EoE Processing} fp@369: fp@1202: To execute the EoE state machine of every active EoE handler, there must be a fp@1202: cyclic process. The easiest solution would be to execute the EoE state fp@1202: machines synchronously with the master state machine (see fp@2515: \autoref{sec:fsm-master}). This approach has the following disadvantage: fp@1202: fp@1202: Only one EoE fragment could be sent or received every few cycles. This fp@1085: causes the data rate to be very low, because the EoE state machines are not fp@1085: executed in the time between the application cycles. Moreover, the data rate fp@1085: would be dependent on the period of the application task. fp@1085: fp@1202: To overcome this problem, an own cyclic process is needed to asynchronously fp@1202: execute the EoE state machines. For that, the master owns a kernel timer, that fp@1202: is executed each timer interrupt. This guarantees a constant bandwidth, but fp@1202: poses the new problem of concurrent access to the master. The locking fp@2515: mechanisms needed for this are introduced in \autoref{sec:concurr}. fp@369: fp@369: \paragraph{Automatic Configuration} fp@369: fp@1202: By default, slaves are left in PREOP state, if no configuration is applied. If fp@1202: an EoE interface link is set to ``up'', the requested slave's fp@1202: application-layer state is automatically set to OP. fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1327: \section{CANopen over EtherCAT (CoE)} fp@1269: \label{sec:coe} fp@369: \index{CoE} fp@369: fp@1327: The CANopen over EtherCAT\nomenclature{CoE}{CANopen over EtherCAT, Mailbox fp@1306: Protocol} protocol~\cite[sec.~5.6]{alspec} is used to configure slaves and fp@1306: exchange data objects on application level. fp@1202: fp@1297: % TODO fp@1203: % fp@1203: % Download / Upload fp@1203: % Expedited / Normal fp@1204: % Segmenting fp@1327: % SDO Info Services fp@1203: % fp@1203: fp@1327: \paragraph{SDO Download State Machine} fp@1327: fp@1327: The best time to apply SDO configurations is during the slave's PREOP state, fp@1289: because mailbox communication is already possible and slave's application will fp@1289: start with updating input data in the succeeding SAFEOP state. Therefore the fp@1327: SDO configuration has to be part of the slave configuration state machine (see fp@2515: \autoref{sec:fsm-conf}): It is implemented via an SDO download state machine, fp@1289: that is executed just before entering the slave's SAFEOP state. In this way, fp@1327: it is guaranteed that the SDO configurations are applied each time, the slave fp@1289: is reconfigured. fp@369: fp@1327: The transition diagram of the SDO Download state machine can be seen fp@2515: in \autoref{fig:fsm-coedown}. fp@369: fp@369: \begin{figure}[htbp] fp@369: \centering fp@1202: \includegraphics[width=.9\textwidth]{images/fsm-coedown} % FIXME fp@369: \caption{Transition diagram of the CoE download state machine} fp@369: \label{fig:fsm-coedown} fp@369: \end{figure} fp@369: fp@1202: % FIXME fp@1202: fp@369: \begin{description} fp@369: \item[START] The beginning state of the CoE download state fp@1327: machine. The ``SDO Download Normal Request'' mailbox command is fp@379: sent. $\rightarrow$~REQUEST fp@369: fp@369: \item[REQUEST] It is checked, if the CoE download request has been fp@369: received by the slave. After that, a mailbox check command is issued fp@379: and a timer is started. $\rightarrow$~CHECK fp@369: fp@369: \item[CHECK] If no mailbox data is available, the timer is checked. fp@369: \begin{itemize} fp@1327: \item If it timed out, the SDO download is aborted. fp@379: $\rightarrow$~ERROR fp@369: \item Otherwise, the mailbox is queried again. fp@379: $\rightarrow$~CHECK fp@369: \end{itemize} fp@369: fp@369: If the mailbox contains new data, the response is fetched. fp@379: $\rightarrow$~RESPONSE fp@369: fp@369: \item[RESPONSE] If the mailbox response could not be fetched, the data fp@1327: is invalid, the wrong protocol was received, or a ``Abort SDO fp@1327: Transfer Request'' was received, the SDO download is aborted. fp@379: $\rightarrow$~ERROR fp@369: fp@1327: If a ``SDO Download Normal Response'' acknowledgement was received, fp@1327: the SDO download was successful. $\rightarrow$~END fp@1327: fp@1327: \item[END] The SDO download was successful. fp@1327: fp@1327: \item[ERROR] The SDO download was aborted due to an error. fp@369: fp@369: \end{description} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1327: \section{Vendor specific over EtherCAT (VoE)} fp@1270: \label{sec:voe} fp@1270: \index{VoE} fp@1270: fp@1270: The VoE protocol opens the possibility to implement a vendor-specific mailbox fp@1270: communication protocol. VoE mailbox messages are prepended by a VoE header fp@1270: containing a 32-bit vendor ID and a 16-bit vendor-type. There are no more fp@1270: constraints regarding this protocol. fp@1270: fp@1270: The EtherCAT master allows to create multiple VoE handlers per slave fp@2515: configuration via the application interface (see \autoref{chap:api}). These fp@1270: handlers contain the state machine necessary for the communication via VoE. fp@1298: fp@2515: For more information about using VoE handlers, see \autoref{sec:api-voe} or fp@1298: the example applications provided in the \textit{examples/} subdirectory. fp@1270: fp@1270: %------------------------------------------------------------------------------ fp@1270: fp@1917: \section{Servo Profile over EtherCAT (SoE)} fp@1917: \label{sec:soe} fp@1917: \index{SoE} fp@1917: fp@1917: The SoE protocol implements the Service Channel layer, specified in IEC fp@1917: 61800-7 \cite{soespec} via EtherCAT mailboxes. fp@1917: fp@1917: The SoE protocol is quite similar to the CoE protocol (see fp@2515: \autoref{sec:coe}). Instead of SDO indices and subindices, so-called fp@1917: identification numbers (IDNs) identify parameters. fp@1917: fp@1917: The implementation covers the ``SCC Read'' and ``SCC Write'' primitives, each fp@1917: with the ability to fragment data. fp@1917: fp@1917: There are several ways to use the SoE implementation: fp@1917: fp@1917: \begin{itemize} fp@1917: fp@1917: \item Reading and writing IDNs via the command-line tool (see fp@2515: \autoref{sec:soeaccess}). fp@1917: fp@1917: \item Storing configurations for arbitrary IDNs via the application interface fp@2515: (see \autoref{chap:api}, i.\,e.~\lstinline+ecrt_slave_config_idn()+). These fp@1917: configurations are written to the slave during configuration in PREOP state, fp@1917: before going to SAFEOP. fp@1917: fp@2515: \item The user-space library (see \autoref{sec:userlib}), offers functions to fp@1917: read/write IDNs in blocking mode (\lstinline+ecrt_master_read_idn()+, fp@1917: \lstinline+ecrt_master_write_idn()+). fp@1917: fp@1917: \end{itemize} fp@1917: fp@1917: %------------------------------------------------------------------------------ fp@1917: fp@1275: \chapter{Userspace Interfaces} fp@369: \label{sec:user} fp@1275: \index{Userspace} fp@1202: fp@1203: For the master runs as a kernel module, accessing it is natively limited to fp@1275: analyzing Syslog messages and controlling using \textit{modutils}. fp@1275: fp@1275: It was necessary to implement further interfaces, that make it easier to access fp@1275: the master from userspace and allow a finer influence. It should be possible fp@1203: to view and to change special parameters at runtime. fp@1203: fp@1275: Bus visualization is another point: For development and debugging purposes it fp@1275: is necessary to show the connected slaves with a single command, for instance fp@2515: (see \autoref{sec:tool}). fp@1275: fp@1275: The application interface has to be available in userspace, to allow userspace fp@1275: programs to use EtherCAT master functionality. This was implemented via a fp@2515: character device and a userspace library (see \autoref{sec:userlib}). fp@1275: fp@1275: Another aspect is automatic startup and configuration. The master must be able fp@1275: to automatically start up with a persistent configuration (see fp@2515: \autoref{sec:system}). fp@1203: fp@1203: A last thing is monitoring EtherCAT communication. For debugging purposes, fp@1203: there had to be a way to analyze EtherCAT datagrams. The best way would be fp@2515: with a popular network analyzer, like Wireshark \cite{wireshark} or others fp@2515: (see \autoref{sec:debug}). fp@1275: fp@1275: This chapter covers all these points and introduces the interfaces and tools fp@1203: to make all that possible. fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1087: \section{Command-line Tool} fp@1289: \label{sec:tool} fp@1087: fp@1297: % TODO --master fp@1087: fp@1202: \subsection{Character Devices} fp@1087: \label{sec:cdev} fp@1087: fp@1214: Each master instance will get a character device as a userspace interface. fp@1214: The devices are named \textit{/dev/EtherCATx}, where $x \in \{0 \ldots n\}$ is fp@1214: the index of the master. fp@1214: fp@1214: \paragraph{Device Node Creation} The character device nodes are automatically fp@1289: created, if the \lstinline+udev+ Package is installed. See fp@2515: \autoref{sec:autonode} for how to install and configure it. fp@1087: fp@1087: %------------------------------------------------------------------------------ fp@1087: fp@1202: \subsection{Setting Alias Addresses} fp@1293: \label{sec:ethercat-alias} fp@1140: fp@1140: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_alias} fp@1140: fp@1140: %------------------------------------------------------------------------------ fp@1140: fp@1202: \subsection{Displaying the Bus Configuration} fp@1293: \label{sec:ethercat-config} fp@1140: fp@1140: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_config} fp@1140: fp@1140: %------------------------------------------------------------------------------ fp@1140: fp@1514: \subsection{Output PDO information in C Language} fp@1514: \label{sec:ethercat-cstruct} fp@1514: fp@1514: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_cstruct} fp@1514: fp@1514: %------------------------------------------------------------------------------ fp@1514: fp@1202: \subsection{Displaying Process Data} fp@1140: fp@1140: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_data} fp@1140: fp@1140: %------------------------------------------------------------------------------ fp@1140: fp@1202: \subsection{Setting a Master's Debug Level} fp@1399: \label{sec:ethercat-debug} fp@1140: fp@1140: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_debug} fp@1140: fp@1140: %------------------------------------------------------------------------------ fp@1140: fp@1202: \subsection{Configured Domains} fp@1140: fp@1140: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_domains} fp@1140: fp@1140: %------------------------------------------------------------------------------ fp@1140: fp@1423: \subsection{SDO Access} fp@1423: fp@1423: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_download} fp@1423: fp@1423: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_upload} fp@1423: fp@1423: %------------------------------------------------------------------------------ fp@1423: fp@1485: \subsection{EoE Statistics} fp@1485: fp@1485: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_eoe} fp@1485: fp@1485: %------------------------------------------------------------------------------ fp@1485: fp@1423: \subsection{File-Access over EtherCAT} fp@1423: fp@1423: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_foe_read} fp@1423: fp@1423: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_foe_write} fp@1423: fp@1423: %------------------------------------------------------------------------------ fp@1423: fp@1423: \subsection{Creating Topology Graphs} fp@1423: fp@1423: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_graph} fp@1423: fp@1423: %------------------------------------------------------------------------------ fp@1423: fp@1202: \subsection{Master and Ethernet Devices} fp@1140: fp@1140: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_master} fp@1140: fp@1140: %------------------------------------------------------------------------------ fp@1140: fp@1327: \subsection{Sync Managers, PDOs and PDO Entries} fp@1140: fp@1140: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_pdos} fp@1140: fp@1140: %------------------------------------------------------------------------------ fp@1140: fp@1423: \subsection{Register Access} fp@1517: \label{sec:regaccess} fp@1423: fp@1423: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_reg_read} fp@1423: fp@1423: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_reg_write} fp@1423: fp@1423: %------------------------------------------------------------------------------ fp@1423: fp@1327: \subsection{SDO Dictionary} fp@1140: fp@1140: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_sdos} fp@1140: fp@1140: %------------------------------------------------------------------------------ fp@1140: fp@1423: \subsection{SII Access} fp@1423: \label{sec:siiaccess} fp@1423: \index{SII!Access} fp@1423: fp@1423: It is possible to directly read or write the complete SII contents of the fp@1423: slaves. This was introduced for the reasons below: fp@1423: fp@1423: \begin{itemize} fp@1423: fp@1423: \item The format of the SII data is still in development and categories can be fp@1423: added in the future. With read and write access, the complete memory contents fp@1423: can be easily backed up and restored. fp@1423: fp@1423: \item Some SII data fields have to be altered (like the alias address). A quick fp@1423: writing must be possible for that. fp@1423: fp@1423: \item Through reading access, analyzing category data is possible from fp@1423: userspace. fp@1423: fp@1423: \end{itemize} fp@1423: fp@1423: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_sii_read} fp@1423: fp@1423: Reading out SII data is as easy as other commands. Though the data are in fp@1423: binary format, analysis is easier with a tool like \textit{hexdump}: fp@1423: fp@1423: \begin{lstlisting} fp@1423: $ `\textbf{ethercat sii\_read --position 3 | hexdump}` fp@1423: 0000000 0103 0000 0000 0000 0000 0000 0000 008c fp@1423: 0000010 0002 0000 3052 07f0 0000 0000 0000 0000 fp@1423: 0000020 0000 0000 0000 0000 0000 0000 0000 0000 fp@1423: ... fp@1423: \end{lstlisting} fp@1423: fp@1423: Backing up SII contents can easily done with a redirection: fp@1423: fp@1423: \begin{lstlisting} fp@1423: $ `\textbf{ethercat sii\_read --position 3 > sii-of-slave3.bin}` fp@1423: \end{lstlisting} fp@1423: fp@1423: To download SII contents to a slave, writing access to the master's character fp@2515: device is necessary (see \autoref{sec:cdev}). fp@1423: fp@1423: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_sii_write} fp@1423: fp@1423: \begin{lstlisting} fp@1423: # `\textbf{ethercat sii\_write --position 3 sii-of-slave3.bin}` fp@1423: \end{lstlisting} fp@1423: fp@1423: The SII contents will be checked for validity and then sent to the slave. The fp@1423: write operation may take a few seconds. fp@1140: fp@1140: %------------------------------------------------------------------------------ fp@1140: fp@1202: \subsection{Slaves on the Bus} fp@1087: fp@1087: Slave information can be gathered with the subcommand \lstinline+slaves+: fp@1087: fp@1140: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_slaves} fp@1140: fp@1140: Below is a typical output: fp@1140: fp@1087: \begin{lstlisting} fp@1087: $ `\textbf{ethercat slaves}` fp@1087: 0 0:0 PREOP + EK1100 Ethernet Kopplerklemme (2A E-Bus) fp@1087: 1 5555:0 PREOP + EL3162 2K. Ana. Eingang 0-10V fp@1087: 2 5555:1 PREOP + EL4102 2K. Ana. Ausgang 0-10V fp@1087: 3 5555:2 PREOP + EL2004 4K. Dig. Ausgang 24V, 0,5A fp@1087: \end{lstlisting} fp@1087: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1917: \subsection{SoE IDN Access} fp@1917: \label{sec:soeaccess} fp@1917: fp@1917: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_soe_read} fp@1917: fp@1917: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_soe_write} fp@1917: fp@1917: %------------------------------------------------------------------------------ fp@1917: fp@1202: \subsection{Requesting Application-Layer States} fp@1140: fp@1140: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_states} fp@1140: fp@1140: %------------------------------------------------------------------------------ fp@1140: fp@1423: \subsection{Displaying the Master Version} fp@1423: fp@1423: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_version} fp@1423: fp@1423: %------------------------------------------------------------------------------ fp@1423: fp@1202: \subsection{Generating Slave Description XML} fp@1140: fp@1140: \lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_xml} fp@1140: fp@1140: %------------------------------------------------------------------------------ fp@1140: fp@1275: \section{Userspace Library} fp@1275: \label{sec:userlib} fp@1275: fp@2515: The native application interface (see \autoref{chap:api}) resides in fp@1282: kernelspace and hence is only accessible from inside the kernel. To make the fp@1282: application interface available from userspace programs, a userspace library fp@1282: has been created, that can be linked to programs under the terms and fp@1282: conditions of the LGPL, version 2 \cite{lgpl}. fp@1282: fp@1282: The library is named \textit{libethercat}. Its sources reside in the fp@1282: \textit{lib/} subdirectory and are build by default when using fp@1282: \lstinline+make+. It is installed in the \textit{lib/} path below the fp@1282: installation prefix as \textit{libethercat.a} (for static linking), fp@1282: \textit{libethercat.la} (for the use with \textit{libtool}) and fp@1282: \textit{libethercat.so} (for dynamic linking). fp@1282: fp@1299: \subsection{Using the Library} fp@1282: fp@1282: The application interface header \textit{ecrt.h} can be used both in kernel fp@1282: and in user context. fp@1282: fp@1282: The following minimal example shows how to build a program with EtherCAT fp@1282: functionality. An entire example can be found in the \textit{examples/user/} fp@1282: path of the master sources. fp@1282: fp@1282: \begin{lstlisting}[language=C] fp@1282: #include fp@1282: fp@1282: int main(void) fp@1282: { fp@1282: ec_master_t *master = ecrt_request_master(0); fp@1282: fp@1282: if (!master) fp@1282: return 1; // error fp@1282: fp@1282: pause(); // wait for signal fp@1282: return 0; fp@1282: } fp@1282: \end{lstlisting} fp@1282: fp@1282: The program can be compiled and dynamically linked to the library with the fp@1282: below command: fp@1282: fp@2515: \begin{lstlisting}[caption=Linker command for using the userspace library, fp@2515: label=lst:linker-user] fp@1282: gcc ethercat.c -o ectest -I/opt/etherlab/include \ fp@1282: -L/opt/etherlab/lib -lethercat \ fp@1282: -Wl,--rpath -Wl,/opt/etherlab/lib fp@1282: \end{lstlisting} fp@1282: fp@1282: The library can also be linked statically to the program: fp@1282: fp@1282: \begin{lstlisting} fp@1282: gcc -static ectest.c -o ectest -I/opt/etherlab/include \ fp@1282: /opt/etherlab/lib/libethercat.a fp@1282: \end{lstlisting} fp@1282: fp@1282: \subsection{Implementation} fp@1282: \label{sec:userimp} fp@1282: fp@1282: Basically the kernel API was transferred into userspace via the master fp@2515: character device (see \autoref{chap:arch}, \autoref{fig:arch} and fp@2515: \autoref{sec:cdev}). fp@1282: fp@1282: The function calls of the kernel API are mapped to the userspace via an fp@1517: \lstinline+ioctl()+ interface. The userspace API functions share a set of fp@1517: generic \lstinline+ioctl()+ calls. The kernel part of the interface calls the fp@1517: according API functions directly, what results in a minimum additional delay fp@2515: (see \autoref{sec:usertiming}). fp@1282: fp@1299: For performance reasons, the actual domain process data (see fp@2515: \autoref{sec:processdata}) are not copied between kernel and user memory on fp@1299: every access: Instead, the data are memory-mapped to the userspace fp@1299: application. Once the master is configured and activated, the master module fp@1299: creates one process data memory area spanning all domains and maps it to fp@1299: userspace, so that the application can directly access the process data. As a fp@1299: result, there is no additional delay when accessing process data from fp@1299: userspace. fp@1299: fp@1299: \paragraph{Kernel/User API Differences} Because of the memory-mapping of the fp@1299: process data, the memory is managed internally by the library functions. As a fp@1299: result, it is not possible to provide external memory for domains, like in the fp@1299: kernel API. The corresponding functions are only available in kernelspace. fp@1299: This is the only difference when using the application interface in userspace. fp@1275: fp@1281: \subsection{Timing} fp@1281: \label{sec:usertiming} fp@1281: fp@1281: An interesting aspect is the timing of the userspace library calls compared to fp@2515: those of the kernel API. \autoref{tab:usertiming} shows the call times and fp@1281: standard deviancies of typical (and time-critical) API functions measured on fp@1281: an Intel Pentium 4 M CPU with \unit{2.2}{\giga\hertz} and a standard 2.6.26 fp@1281: kernel. fp@1281: fp@1281: \begin{table}[htbp] fp@1281: \centering fp@1281: \caption{Application Interface Timing Comparison} fp@1281: \label{tab:usertiming} fp@1281: \vspace{2mm} fp@1281: \begin{tabular}{l|c|c|c|c} fp@1281: fp@1281: & fp@1281: \multicolumn{2}{|c}{\textbf{Kernelspace}} & fp@1281: \multicolumn{2}{|c}{\textbf{Userspace}} \\ fp@1281: fp@1281: \textbf{Function} & fp@1281: $\mu(t)$ & fp@1281: $\sigma(t)$ & fp@1281: $\mu(t)$ & fp@1281: $\sigma(t)$ \\ fp@1281: \hline fp@1281: fp@1281: \lstinline+ecrt_master_receive()+ & fp@1281: \unit{1.1}{\micro\second} & fp@1281: \unit{0.3}{\micro\second} & fp@1281: \unit{2.2}{\micro\second} & fp@1281: \unit{0.5}{\micro\second} \\ fp@1281: fp@1281: \lstinline+ecrt_domain_process()+ & fp@1281: \unit{<0.1}{\micro\second} & fp@1281: \unit{<0.1}{\micro\second} & fp@1281: \unit{1.0}{\micro\second} & fp@1281: \unit{0.2}{\micro\second} \\ fp@1281: fp@1281: \lstinline+ecrt_domain_queue()+ & fp@1281: \unit{<0.1}{\micro\second} & fp@1281: \unit{<0.1}{\micro\second} & fp@1281: \unit{1.0}{\micro\second} & fp@1281: \unit{0.1}{\micro\second} \\ fp@1281: fp@1281: \lstinline+ecrt_master_send()+ & fp@1281: \unit{1.8}{\micro\second} & fp@1281: \unit{0.2}{\micro\second} & fp@1281: \unit{2.5}{\micro\second} & fp@1281: \unit{0.5}{\micro\second} \\ fp@1281: fp@1281: \end{tabular} fp@1281: \end{table} fp@1281: fp@1282: The test results show, that for this configuration, the userspace API causes fp@1282: about \unit{1}{\micro\second} additional delay for each function, compared to fp@1282: the kernel API. fp@1281: fp@1275: %------------------------------------------------------------------------------ fp@1275: fp@2515: \section{RTDM Interface} fp@2515: \label{sec:rtdm} fp@2515: fp@2515: When using the userspace interfaces of realtime extensions like Xenomai or fp@2515: RTAI, the use of \textit{ioctl()} is not recommended, because it may disturb fp@2515: realtime operation. To accomplish this, the Real-Time Device Model (RTDM) fp@2515: \cite{rtdm} has been developed. The master module provides an RTDM interface fp@2515: (see \autoref{fig:arch}) in addition to the normal character device, if the fp@2515: master sources were configured with \lstinline+--enable-rtdm+ (see fp@2515: \autoref{sec:installation}). fp@2515: fp@2515: To force an application to use the RTDM interface instead of the normal fp@2515: character device, it has to be linked with the \textit{libethercat\_rtdm} fp@2515: library instead of \textit{libethercat}. The use of the fp@2515: \textit{libethercat\_rtdm} is transparent, so the EtherCAT header fp@2515: \textit{ecrt.h} with the complete API can be used as usual. fp@2515: fp@2515: To make the example in \autoref{lst:linker-user} use the RTDM library, the fp@2515: linker command has to be altered as follows: fp@2515: fp@2515: \begin{lstlisting} fp@2515: gcc ethercat-with-rtdm.c -o ectest -I/opt/etherlab/include \ fp@2515: -L/opt/etherlab/lib -lethercat_rtdm \ fp@2515: -Wl,--rpath -Wl,/opt/etherlab/lib fp@2515: \end{lstlisting} fp@2515: fp@2515: %------------------------------------------------------------------------------ fp@2515: fp@1085: \section{System Integration} fp@369: \label{sec:system} fp@369: fp@1086: To integrate the EtherCAT master as a service into a running system, it comes fp@2515: with an init script and a sysconfig file, that are described below. Modern fp@2515: systems may be managed by systemd \cite{systemd}. Integration of the master fp@2515: with systemd is described in \autoref{sec:systemd}. fp@1086: fp@1086: \subsection{Init Script} fp@369: \label{sec:init} fp@369: \index{Init script} fp@369: fp@1086: The EtherCAT master init script conforms to the requirements of the ``Linux fp@1086: Standard Base'' (LSB\index{LSB}, \cite{lsb}). The script is installed to fp@1202: \textit{etc/init.d/ethercat} below the installation prefix and has to be fp@1202: copied (or better: linked) to the appropriate location (see fp@2515: \autoref{sec:installation}), before the master can be inserted as a service. fp@1289: Please note, that the init script depends on the sysconfig file described fp@1289: below. fp@1086: fp@1306: To provide service dependencies (i.\,e.\ which services have to be started fp@1306: before others) inside the init script code, LSB defines a special comment fp@1306: block. System tools can extract this information to insert the EtherCAT init fp@1306: script at the correct place in the startup sequence: fp@1086: fp@1086: \lstinputlisting[firstline=38,lastline=48] fp@1086: {../script/init.d/ethercat} fp@1086: fp@1202: \subsection{Sysconfig File} fp@1086: \label{sec:sysconfig} fp@1086: \index{Sysconfig file} fp@1086: fp@1086: For persistent configuration, the init script uses a sysconfig file installed fp@1086: to \textit{etc/sysconfig/ethercat} (below the installation prefix), that is fp@1086: mandatory for the init script. The sysconfig file contains all configuration fp@1086: variables needed to operate one or more masters. The documentation is inside fp@1086: the file and included below: fp@1086: fp@1086: \lstinputlisting[numbers=left,firstline=9,basicstyle=\ttfamily\scriptsize] fp@1086: {../script/sysconfig/ethercat} fp@1086: fp@2515: For systems managed by systemd (see \autoref{sec:systemd}), the sysconfig file fp@2515: has moved to \lstinline+/etc/ethercat.conf+. Both versions are part of the fp@2515: master sources and are meant to used alternatively. fp@2515: fp@1202: \subsection{Starting the Master as a Service} fp@1086: \label{sec:service} fp@1086: \index{Service} fp@1086: fp@1086: After the init script and the sysconfig file are placed into the right fp@1086: location, the EtherCAT master can be inserted as a service. The different Linux fp@1086: distributions offer different ways to mark a service for starting and stopping fp@1086: in certain runlevels. For example, SUSE Linux provides the \textit{insserv} fp@1086: command: fp@1086: fp@1086: \begin{lstlisting} fp@1086: # `\textbf{insserv ethercat}` fp@369: \end{lstlisting} fp@369: fp@369: The init script can also be used for manually starting and stopping fp@369: the EtherCAT master. It has to be executed with one of the parameters fp@379: \texttt{start}, \texttt{stop}, \texttt{restart} or \texttt{status}. fp@369: fp@1085: \begin{lstlisting}[gobble=2] fp@379: # `\textbf{/etc/init.d/ethercat restart}` fp@369: Shutting down EtherCAT master done fp@369: Starting EtherCAT master done fp@369: \end{lstlisting} fp@369: fp@2515: \subsection{Integration with systemd} fp@2515: \label{sec:systemd} fp@2515: \index{systemd} fp@2515: fp@2515: Distributions using \textit{systemd} instead of the SysV init system are using service files to describe how a service is to be maintained. \autoref{lst:service} lists the master's service file: fp@2515: fp@2515: \lstinputlisting[basicstyle=\ttfamily\footnotesize,caption=Service file, fp@2515: label=lst:service]{../script/ethercat.service} fp@2515: fp@2515: The \textit{ethercatctl} command is used to load and unload the master and fp@2515: network driver modules in a similar way to the former init script fp@2515: (\autoref{sec:init}). Because it is installed into the \textit{sbin/} fp@2515: directory, it can also be used separately: fp@2515: fp@2515: \begin{lstlisting}[gobble=2] fp@2515: # `\textbf{ethercatctl start}` fp@2515: \end{lstlisting} fp@2515: fp@2515: When using systemd and/or the \textit{ethercatctl} command, the master fp@2515: configuration must be in \texttt{/etc/ethercat.conf} instead of fp@2515: \texttt{/etc/sysconfig/ethercat}! The latter is ignored. The configuration fp@2515: options are exactly the same. fp@2515: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1307: \section{Debug Interfaces} fp@369: \label{sec:debug} fp@1307: \index{Debug Interfaces} fp@369: fp@1306: EtherCAT buses can always be monitored by inserting a switch between master fp@1306: and slaves. This allows to connect another PC with a network monitor like fp@1588: Wireshark~\cite{wireshark}, for example. It is also possible to listen to fp@1588: local network interfaces on the machine running the EtherCAT master directly. fp@2515: If the generic Ethernet driver (see \autoref{sec:generic-driver}) is used, fp@1588: the network monitor can directly listen on the network interface connected to fp@1588: the EtherCAT bus. fp@1588: fp@2515: When using native Ethernet drivers (see \autoref{sec:native-drivers}), there fp@1588: are no local network interfaces to listen to, because the Ethernet devices fp@1588: used for EtherCAT are not registered at the network stack. For that case, fp@1588: so-called ``debug interfaces'' are supported, which are virtual network fp@1588: interfaces allowing to capture EtherCAT traffic with a network monitor (like fp@1588: Wireshark or tcpdump) running on the master machine without using external fp@1588: hardware. To use this functionality, the master sources have to be configured fp@1588: with the \lstinline+--enable-debug-if+ switch (see fp@2515: \autoref{sec:installation}). fp@1307: fp@1307: Every EtherCAT master registers a read-only network interface per attached fp@1308: physical Ethernet device. The network interfaces are named \textit{ecdbgmX} fp@2515: for the main device, and \textit{ecdbgbX} for the backup device, where X is fp@2515: the master index. The below listing shows a debug interface among some fp@2515: standard network interfaces: fp@1306: fp@1306: \begin{lstlisting} fp@1306: # `\textbf{ip link}` fp@1306: 1: lo: mtu 16436 qdisc noqueue fp@1306: link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 fp@1306: 4: eth0: mtu 1500 qdisc noop qlen 1000 fp@1307: link/ether 00:13:46:3b:ad:d7 brd ff:ff:ff:ff:ff:ff fp@1308: 8: ecdbgm0: mtu 1500 qdisc pfifo_fast fp@1308: qlen 1000 fp@1306: link/ether 00:04:61:03:d1:01 brd ff:ff:ff:ff:ff:ff fp@1307: \end{lstlisting} fp@1307: fp@1307: While a debug interface is enabled, all frames sent or received to or from the fp@1307: physical device are additionally forwarded to the debug interface by the fp@1308: corresponding master. Network interfaces can be enabled with the below fp@1308: command: fp@1306: fp@1306: \begin{lstlisting} fp@1306: # `\textbf{ip link set dev ecdbgm0 up}` fp@1306: \end{lstlisting} fp@1306: fp@1306: Please note, that the frame rate can be very high. With an application fp@1306: connected, the debug interface can produce thousands of frames per second. fp@1306: fp@1309: \paragraph{Attention} The socket buffers needed for the operation of debug fp@1588: interfaces have to be allocated dynamically. Some Linux realtime extensions fp@1588: (like RTAI) do not allow this in realtime context! fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1085: \chapter{Timing Aspects} fp@369: \label{sec:timing} fp@369: fp@1085: Although EtherCAT's timing is highly deterministic and therefore timing issues fp@1085: are rare, there are a few aspects that can (and should be) dealt with. fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@1202: \subsection{Application Interface Profiling} fp@369: \label{sec:timing-profile} fp@1204: \index{Profiling} fp@1204: % FIXME fp@369: fp@1085: One of the most important timing aspects are the execution times of the fp@1204: application interface functions, that are called in cyclic context. These fp@1085: functions make up an important part of the overall timing of the application. fp@1085: To measure the timing of the functions, the following code was used: fp@369: fp@369: \begin{lstlisting}[gobble=2,language=C] fp@369: c0 = get_cycles(); fp@369: ecrt_master_receive(master); fp@369: c1 = get_cycles(); fp@369: ecrt_domain_process(domain1); fp@369: c2 = get_cycles(); fp@369: ecrt_master_run(master); fp@369: c3 = get_cycles(); fp@369: ecrt_master_send(master); fp@369: c4 = get_cycles(); fp@369: \end{lstlisting} fp@369: fp@1085: Between each call of an interface function, the CPU timestamp counter is read. fp@1085: The counter differences are converted to \micro\second\ with help of the fp@1085: \lstinline+cpu_khz+ variable, that contains the number of increments per fp@1085: \milli\second. fp@1085: fp@1085: For the actual measuring, a system with a \unit{2.0}{\giga\hertz} CPU was used, fp@1085: that ran the above code in an RTAI thread with a period of fp@1085: \unit{100}{\micro\second}. The measuring was repeated $n = 100$ times and the fp@2515: results were averaged. These can be seen in \autoref{tab:profile}. fp@369: fp@369: \begin{table}[htpb] fp@369: \centering fp@1204: \caption{Profiling of an Application Cycle on a \unit{2.0}{\giga\hertz} fp@1085: Processor} fp@369: \label{tab:profile} fp@369: \vspace{2mm} fp@369: \begin{tabular}{l|r|r} fp@1085: Element & Mean Duration [\second] & Standard Deviancy [\micro\second] \\ fp@369: \hline fp@369: \textit{ecrt\_master\_receive()} & 8.04 & 0.48\\ fp@369: \textit{ecrt\_domain\_process()} & 0.14 & 0.03\\ fp@369: \textit{ecrt\_master\_run()} & 0.29 & 0.12\\ fp@369: \textit{ecrt\_master\_send()} & 2.18 & 0.17\\ \hline fp@369: Complete Cycle & 10.65 & 0.69\\ \hline fp@369: \end{tabular} fp@369: \end{table} fp@369: fp@1085: It is obvious, that the functions accessing hardware make up the fp@369: lion's share. The \textit{ec\_master\_receive()} executes the ISR of fp@369: the Ethernet device, analyzes datagrams and copies their contents into fp@369: the memory of the datagram objects. The \textit{ec\_master\_send()} fp@369: assembles a frame out of different datagrams and copies it to the fp@369: hardware buffers. Interestingly, this makes up only a quarter of the fp@369: receiving time. fp@369: fp@1085: The functions that only operate on the masters internal data structures are fp@1085: very fast ($\Delta t < \unit{1}{\micro\second}$). Interestingly the runtime of fp@1085: \textit{ec\_domain\_process()} has a small standard deviancy relative to the fp@1085: mean value, while this ratio is about twice as big for fp@1085: \textit{ec\_master\_run()}: This probably results from the latter function fp@1085: having to execute code depending on the current state and the different state fp@1085: functions are more or less complex. fp@1085: fp@1085: For a realtime cycle makes up about \unit{10}{\micro\second}, the theoretical fp@1085: frequency can be up to \unit{100}{\kilo\hertz}. For two reasons, this frequency fp@369: keeps being theoretical: fp@369: fp@369: \begin{enumerate} fp@1085: fp@1085: \item The processor must still be able to run the operating system between the fp@1085: realtime cycles. fp@1085: fp@1085: \item The EtherCAT frame must be sent and received, before the next realtime fp@1085: cycle begins. The determination of the bus cycle time is difficult and covered fp@2515: in \autoref{sec:timing-bus}. fp@1085: fp@369: \end{enumerate} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@369: \subsection{Bus Cycle Measuring} fp@369: \label{sec:timing-bus} fp@369: \index{Bus cycle} fp@369: fp@1297: For measuring the time, a frame is ``on the wire'', two timestamps must be fp@1297: taken: fp@369: fp@369: \begin{enumerate} fp@1297: fp@1297: \item The time, the Ethernet hardware begins with physically sending the fp@1297: frame. fp@1297: fp@1297: \item The time, the frame is completely received by the Ethernet hardware. fp@1297: fp@369: \end{enumerate} fp@369: fp@369: Both times are difficult to determine. The first reason is, that the fp@1297: interrupts are disabled and the master is not notified, when a frame is sent fp@1297: or received (polling would distort the results). The second reason is, that fp@1297: even with interrupts enabled, the time from the event to the notification is fp@1297: unknown. Therefore the only way to confidently determine the bus cycle time is fp@1297: an electrical measuring. fp@369: fp@1204: Anyway, the bus cycle time is an important factor when designing realtime fp@1204: code, because it limits the maximum frequency for the cyclic task of the fp@1204: application. In practice, these timing parameters are highly dependent on the fp@1204: hardware and often a trial and error method must be used to determine the fp@1204: limits of the system. fp@1085: fp@1085: The central question is: What happens, if the cycle frequency is too high? The fp@1297: answer is, that the EtherCAT frames that have been sent at the end of the fp@1297: cycle are not yet received, when the next cycle starts. First this is noticed fp@1297: by \textit{ecrt\_domain\_process()}, because the working counter of the fp@1297: process data datagrams were not increased. The function will notify the user fp@1297: via Syslog\footnote{To limit Syslog output, a mechanism has been implemented, fp@1297: that outputs a summarized notification at maximum once a second.}. In this fp@1297: case, the process data keeps being the same as in the last cycle, because it fp@1297: is not erased by the domain. When the domain datagrams are queued again, the fp@1297: master notices, that they are already queued (and marked as sent). The master fp@1297: will mark them as unsent again and output a warning, that datagrams were fp@1085: ``skipped''. fp@1085: fp@1085: On the mentioned \unit{2.0}{\giga\hertz} system, the possible cycle frequency fp@1085: can be up to \unit{25}{\kilo\hertz} without skipped frames. This value can fp@1297: surely be increased by choosing faster hardware. Especially the RealTek fp@1297: network hardware could be replaced by a faster one. Besides, implementing a fp@1297: dedicated ISR for EtherCAT devices would also contribute to increasing the fp@1297: latency. These are two points on the author's to-do list. fp@1085: fp@1085: %------------------------------------------------------------------------------ fp@1085: fp@1085: \chapter{Installation} fp@1085: \label{sec:installation} fp@1085: \index{Master!Installation} fp@369: fp@1772: \section{Getting the Software} fp@1772: \label{sec:getting} fp@1772: fp@1772: There are several ways to get the master software: fp@1772: fp@1772: \begin{enumerate} fp@1772: fp@1772: \item An official release (for example \masterversion), can be downloaded from fp@1772: the master's website\footnote{\url{http://etherlab.org/en/ethercat/index.php}} fp@1772: at~the EtherLab project~\cite{etherlab} as a tarball. fp@1772: fp@1772: \item The most recent development revision (and moreover any other revision) fp@1772: can be obtained via the Mercurial~\cite{mercurial} repository on the master's fp@1772: project page on fp@1772: SourceForge.net\footnote{\url{http://sourceforge.net/projects/etherlabmaster}}. fp@1772: The whole repository can be cloned with the command fp@1772: fp@1772: \begin{lstlisting}[breaklines=true] fp@1772: hg clone http://etherlabmaster.hg.sourceforge.net/hgweb/etherlabmaster/etherlabmaster `\textit{local-dir}` fp@1772: \end{lstlisting} fp@1772: fp@1772: \item Without a local Mercurial installation, tarballs of arbitrary revisions fp@1772: can be downloaded via the ``bz2'' links in the browsable repository fp@1772: pages\footnote{\url{http://etherlabmaster.hg.sourceforge.net/hgweb/etherlabmaster/etherlabmaster}}. fp@1772: fp@1772: \end{enumerate} fp@1772: fp@1202: \section{Building the Software} fp@1094: fp@1772: After downloading a tarball or cloning the repository as described in fp@2515: \autoref{sec:getting}, the sources have to be prepared and configured for the fp@1772: build process. fp@1772: fp@1772: When a tarball was downloaded, it has to be extracted with the following fp@1772: commands: fp@369: fp@1085: \begin{lstlisting}[gobble=2] fp@1202: $ `\textbf{tar xjf ethercat-\masterversion.tar.bz2}` fp@1202: $ `\textbf{cd ethercat-\masterversion/}` fp@374: \end{lstlisting} fp@374: fp@1772: The software configuration is managed with Autoconf~\cite{autoconf} so the fp@1772: released versions contain a \lstinline+configure+ shell script, that has to be fp@1772: executed for configuration (see below). fp@1772: fp@1772: \paragraph{Bootstrap} When downloading or cloning directly from the fp@1772: repository, the \lstinline+configure+ script does not yet exist. It can be fp@1772: created via the \lstinline+bootstrap.sh+ script in the master sources. The fp@1772: autoconf and automake packages are required for this. fp@1772: fp@1772: \paragraph{Configuration and Build} The configuration and the build process fp@1772: follow the below commands: fp@369: fp@1085: \begin{lstlisting}[gobble=2] fp@1202: $ `\textbf{./configure}` fp@1202: $ `\textbf{make}` fp@1202: $ `\textbf{make modules}` fp@374: \end{lstlisting} fp@374: fp@2515: \autoref{tab:config} lists important configuration switches and options. fp@1085: fp@2297: \begin{longtable}{l|p{.4\textwidth}|l} fp@2297: \caption{Configuration options}\rule[-5ex]{0mm}{0mm} fp@2297: \label{tab:config}\\ fp@2297: fp@2297: \textbf{Option/Switch} & \textbf{Description} & \textbf{Default}\\\hline fp@2297: \endfirsthead fp@2297: fp@2297: \textbf{Option/Switch} & \textbf{Description} & \textbf{Default}\\\hline fp@2297: \endhead fp@1085: fp@1085: \lstinline+--prefix+ & Installation prefix & \textit{/opt/etherlab}\\ fp@1085: fp@1085: \lstinline+--with-linux-dir+ & Linux kernel sources & Use running kernel\\ fp@1085: fp@2297: \lstinline+--with-module-dir+ & Subdirectory in the kernel module tree, where fp@2297: the EtherCAT kernel modules shall be installed. & \textit{ethercat}\\ fp@2297: fp@2297: \hline fp@2297: fp@2297: \lstinline+--enable-generic+ & Build the generic Ethernet driver (see fp@2515: \autoref{sec:generic-driver}). & yes\\ fp@2297: fp@2297: \lstinline+--enable-8139too+ & Build the 8139too driver & yes\\ fp@2297: fp@2297: \lstinline+--with-8139too-kernel+ & 8139too kernel & $\dagger$\\ fp@2297: fp@2297: \lstinline+--enable-e100+ & Build the e100 driver & no\\ fp@2297: fp@2297: \lstinline+--with-e100-kernel+ & e100 kernel & $\dagger$\\ fp@2297: fp@2297: \lstinline+--enable-e1000+ & Enable e1000 driver & no\\ fp@2297: fp@2297: \lstinline+--with-e1000-kernel+ & e1000 kernel & $\dagger$\\ fp@2297: fp@2364: \lstinline+--enable-e1000e+ & Enable e1000e driver & no\\ fp@2364: fp@2364: \lstinline+--with-e1000e-kernel+ & e1000e kernel & $\dagger$\\ fp@2364: fp@2297: \lstinline+--enable-r8169+ & Enable r8169 driver & no\\ fp@2297: fp@2297: \lstinline+--with-r8169-kernel+ & r8169 kernel & $\dagger$\\ fp@2297: fp@2691: \lstinline+--enable-ccat+ & Enable ccat driver (independent of kernel version) fp@2691: & no\\ fp@2691: fp@2691: \lstinline+--enable-igb+ & Enable igb driver & no\\ fp@2691: fp@2691: \lstinline+--with-igb-kernel+ & igb kernel & $\dagger$\\ fp@2691: fp@2297: \hline fp@2297: fp@2691: \lstinline+--enable-kernel+ & Build the master kernel modules & yes\\ fp@2691: fp@2515: \lstinline+--enable-rtdm+ & Create the RTDM interface (RTAI or Xenomai fp@2515: directory needed, see below) & no\\ fp@2515: fp@2515: \lstinline+--with-rtai-dir+ & RTAI path (for RTAI examples and RTDM interface) fp@2515: & \\ fp@2515: fp@2515: \lstinline+--with-xenomai-dir+ & Xenomai path (for Xenomai examples and RTDM fp@2515: interface) & \\ fp@2515: fp@2515: \lstinline+--with-devices+ & Number of Ethernet devices for redundant fp@2515: operation ($>1$ switches redundancy on) & 1\\ fp@1085: fp@2297: \lstinline+--enable-debug-if+ & Create a debug interface for each master & no\\ fp@2297: fp@2297: \lstinline+--enable-debug-ring+ & Create a debug ring to record frames & no\\ fp@2297: fp@2297: \lstinline+--enable-eoe+ & Enable EoE support & yes\\ fp@2297: fp@2297: \lstinline+--enable-cycles+ & Use CPU timestamp counter. Enable this on Intel fp@2297: architecture to get finer timing calculation. & no\\ fp@2297: fp@2297: \lstinline+--enable-hrtimer+ & Use high-resolution timer to let the master fp@2297: state machine sleep between sending frames. & no\\ fp@2297: fp@2691: \lstinline+--enable-regalias+ & Read alias address from register & no\\ fp@1085: fp@1588: \lstinline+--enable-tool+ & Build the command-line tool ``ethercat'' (see fp@2691: \autoref{sec:tool}) & yes\\ fp@2691: fp@2691: \lstinline+--enable-userlib+ & Build the userspace library & yes\\ fp@2691: fp@2691: \lstinline+--enable-tty+ & Build the TTY driver & no\\ fp@2297: fp@2297: \lstinline+--enable-wildcards+ & Enable \textit{0xffffffff} to be wildcards fp@2691: for vendor ID and product code & no\\ fp@1085: fp@2515: \lstinline+--enable-sii-assign+ & Enable assigning SII access to the PDI layer fp@2691: during slave configuration & no\\ fp@2691: fp@2691: \lstinline+--enable-rt-syslog+ & Enable syslog statements in realtime context & fp@2691: yes\\ fp@2515: fp@1085: \hline fp@1085: fp@2297: \end{longtable} fp@1085: fp@1085: \begin{description} fp@1085: fp@1085: \item[$\dagger$] If this option is not specified, the kernel version to use is fp@1085: extracted from the Linux kernel sources. fp@1085: fp@1085: \end{description} fp@1085: fp@1202: \section{Building the Interface Documentation} fp@1094: \label{sec:gendoc} fp@1094: fp@1094: The source code is documented using Doxygen~\cite{doxygen}. To build the HTML fp@1202: documentation, the Doxygen software has to be installed. The below command fp@1095: will generate the documents in the subdirectory \textit{doxygen-output}: fp@1094: fp@1094: \begin{lstlisting} fp@1094: $ `\textbf{make doc}` fp@1094: \end{lstlisting} fp@1094: fp@1204: The interface documentation can be viewed by pointing a browser to the file fp@1293: \textit{doxygen-output/html/index.html}. The functions and data structures of fp@1293: the application interface a covered by an own module ``Application fp@1293: Interface''. fp@1202: fp@1202: \section{Installing the Software} fp@1094: fp@1106: The below commands have to be entered as \textit{root}: The first one will fp@1275: install the EtherCAT header, init script, sysconfig file and the userspace fp@1202: tool to the prefix path. The second one will install the kernel modules to the fp@1202: kernel's modules directory. The final \lstinline+depmod+ call is necessary to fp@1202: include the kernel modules into the \textit{modules.dep} file to make it fp@2421: available to the \lstinline+modprobe+ command, used in the init script. fp@369: fp@1094: \begin{lstlisting} fp@1106: # `\textbf{make install}` fp@1094: # `\textbf{make modules\_install}` fp@369: \end{lstlisting} fp@369: fp@1095: If the target kernel's modules directory is not under \textit{/lib/modules}, a fp@1095: different destination directory can be specified with the \lstinline+DESTDIR+ fp@1095: make variable. For example: fp@487: fp@1094: \begin{lstlisting} fp@1094: # `\textbf{make DESTDIR=/vol/nfs/root modules\_install}` fp@487: \end{lstlisting} fp@487: fp@487: This command will install the compiled kernel modules to fp@487: \textit{/vol/nfs/root/lib/modules}, prepended by the kernel release. fp@487: fp@1085: If the EtherCAT master shall be run as a service\footnote{Even if the EtherCAT fp@1085: master shall not be loaded on system startup, the use of the init script is fp@2515: recommended for manual (un-)loading.} (see \autoref{sec:system}), the init fp@2515: script and the sysconfig file (or the systemd service file, respectively) have fp@2515: to be copied (or linked) to the appropriate locations. The below example is fp@2515: suitable for SUSE Linux. It may vary for other distributions. fp@1085: fp@1107: % FIXME relative ln -s? fp@1094: \begin{lstlisting} fp@1094: # `\textbf{cd /opt/etherlab}` fp@1094: # `\textbf{cp etc/sysconfig/ethercat /etc/sysconfig/}` fp@1094: # `\textbf{ln -s etc/init.d/ethercat /etc/init.d/}` fp@1094: # `\textbf{insserv ethercat}` fp@374: \end{lstlisting} fp@374: fp@376: Now the sysconfig file \texttt{/etc/sysconfig/ethercat} (see fp@2515: \autoref{sec:sysconfig}), or the configuration file fp@2515: \textit{/etc/ethercat.conf}, if using systemd, has to be customized. The fp@2515: minimal customization is to set the \lstinline+MASTER0_DEVICE+ variable to the fp@2515: MAC address of the Ethernet device to use (or \lstinline+ff:ff:ff:ff:ff:ff+ to fp@2515: use the first device offered) and selecting the driver(s) to load via the fp@1085: \lstinline+DEVICE_MODULES+ variable. fp@369: fp@1297: After the basic configuration is done, the master can be started with the fp@1297: below command: fp@369: fp@1094: \begin{lstlisting} fp@1094: # `\textbf{/etc/init.d/ethercat start}` fp@369: \end{lstlisting} fp@369: fp@2515: When using systemd, the following command can be used alternatively: fp@2515: fp@2515: \begin{lstlisting} fp@2515: # `\textbf{ethercatctl start}` fp@2515: \end{lstlisting} fp@2515: fp@1214: At this time, the operation of the master can be observed by viewing the fp@1214: Syslog\index{Syslog} messages, which should look like the ones below. If fp@1214: EtherCAT slaves are connected to the master's EtherCAT device, the activity fp@1214: indicators should begin to flash. fp@369: fp@369: \begin{lstlisting}[numbers=left] fp@1085: EtherCAT: Master driver `\masterversion` fp@1085: EtherCAT: 1 master waiting for devices. fp@1085: EtherCAT Intel(R) PRO/1000 Network Driver - version 6.0.60-k2 fp@1085: Copyright (c) 1999-2005 Intel Corporation. fp@1085: PCI: Found IRQ 12 for device 0000:01:01.0 fp@1085: PCI: Sharing IRQ 12 with 0000:00:1d.2 fp@1085: PCI: Sharing IRQ 12 with 0000:00:1f.1 fp@1085: EtherCAT: Accepting device 00:0E:0C:DA:A2:20 for master 0. fp@1085: EtherCAT: Starting master thread. fp@1085: ec_e1000: ec0: e1000_probe: Intel(R) PRO/1000 Network fp@1085: Connection fp@1085: ec_e1000: ec0: e1000_watchdog_task: NIC Link is Up 100 Mbps fp@1085: Full Duplex fp@1085: EtherCAT: Link state changed to UP. fp@1085: EtherCAT: 7 slave(s) responding. fp@1085: EtherCAT: Slave states: PREOP. fp@1085: EtherCAT: Scanning bus. fp@1085: EtherCAT: Bus scanning completed in 431 ms. fp@369: \end{lstlisting} fp@369: fp@369: \begin{description} fp@1085: fp@1085: \item[\linenum{1} -- \linenum{2}] The master module is loading, and one master fp@1085: is initialized. fp@1085: fp@1085: \item[\linenum{3} -- \linenum{8}] The EtherCAT-capable e1000 driver is fp@1085: loading. The master accepts the device with the address fp@1085: \lstinline+00:0E:0C:DA:A2:20+. fp@1085: fp@1085: \item[\linenum{9} -- \linenum{16}] The master goes to idle phase, starts its fp@1085: state machine and begins scanning the bus. fp@1085: fp@369: \end{description} fp@369: fp@1214: \section{Automatic Device Node Creation} fp@1214: \label{sec:autonode} fp@1214: fp@2515: The \lstinline+ethercat+ command-line tool (see \autoref{sec:tool}) fp@1214: communicates with the master via a character device. The corresponding device fp@1289: nodes are created automatically, if the udev daemon is running. Note, that on fp@1289: some distributions, the \lstinline+udev+ package is not installed by default. fp@1214: fp@1214: The device nodes will be created with mode \lstinline+0660+ and group fp@1292: \lstinline+root+ by default. If ``normal'' users shall have reading access, a fp@1292: udev rule file (for example \textit{/etc/udev/rules.d/99-EtherCAT.rules}) has fp@1292: to be created with the following contents: fp@1214: fp@1214: \begin{lstlisting} fp@1214: KERNEL=="EtherCAT[0-9]*", MODE="0664" fp@1214: \end{lstlisting} fp@1214: fp@1214: After the udev rule file is created and the EtherCAT master is restarted with fp@1214: \lstinline[breaklines=true]+/etc/init.d/ethercat restart+, the device node fp@1214: will be automatically created with the desired rights: fp@1214: fp@1214: \begin{lstlisting} fp@1214: # `\textbf{ls -l /dev/EtherCAT0}` fp@1214: crw-rw-r-- 1 root root 252, 0 2008-09-03 16:19 /dev/EtherCAT0 fp@1214: \end{lstlisting} fp@1214: fp@2515: Now, the \lstinline+ethercat+ tool can be used (see \autoref{sec:tool}) even fp@1289: as a non-root user. fp@1214: fp@1306: If non-root users shall have writing access, the following udev rule can be fp@1306: used instead: fp@1306: fp@1306: \begin{lstlisting} fp@1306: KERNEL=="EtherCAT[0-9]*", MODE="0664", GROUP="users" fp@1306: \end{lstlisting} fp@1306: fp@369: %------------------------------------------------------------------------------ fp@369: fp@369: \begin{thebibliography}{99} fp@1094: fp@1094: \bibitem{etherlab} Ingenieurgemeinschaft IgH: EtherLab -- Open Source Toolkit fp@1094: for rapid realtime code generation under Linux with Simulink/RTW and EtherCAT fp@1094: technology. \url{http://etherlab.org/en}, 2008. fp@1094: fp@369: \bibitem{dlspec} IEC 61158-4-12: Data-link Protocol Specification. fp@1095: International Electrotechnical Commission (IEC), 2005. fp@1094: fp@1094: \bibitem{alspec} IEC 61158-6-12: Application Layer Protocol Specification. fp@1095: International Electrotechnical Commission (IEC), 2005. fp@1094: fp@1094: \bibitem{gpl} GNU General Public License, Version 2. fp@1275: \url{http://www.gnu.org/licenses/gpl-2.0.html}. October~15, 2008. fp@1275: fp@1275: \bibitem{lgpl} GNU Lesser General Public License, Version 2.1. fp@1275: \url{http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html}. October~15, fp@1275: 2008. fp@1094: fp@1094: \bibitem{lsb} Linux Standard Base. fp@1306: \url{http://www.linuxfoundation.org/en/LSB}. August~9, 2006. fp@1094: fp@2515: \bibitem{systemd} systemd System and Service Manager fp@2515: \url{http://freedesktop.org/wiki/Software/systemd}. January~18, 2013. fp@2515: fp@1094: \bibitem{wireshark} Wireshark. \url{http://www.wireshark.org}. 2008. fp@1094: fp@1306: \bibitem{automata} {\it Hopcroft, J.\,E.\ / Ullman, J.\,D.}: Introduction to fp@1094: Automata Theory, Languages and Computation. Adison-Wesley, Reading, fp@1094: Mass.~1979. fp@1094: fp@1306: \bibitem{fsmmis} {\it Wagner, F.\ / Wolstenholme, P.}: State machine fp@1094: misunderstandings. In: IEE journal ``Computing and Control Engineering'', fp@1094: 2004. fp@1094: fp@1094: \bibitem{rtai} RTAI. The RealTime Application Interface for Linux from DIAPM. fp@1588: \url{https://www.rtai.org}, 2010. fp@1588: fp@1588: \bibitem{rt-preempt} RT PREEMPT HOWTO. fp@1588: \url{http://rt.wiki.kernel.org/index.php/RT_PREEMPT_HOWTO}, 2010. fp@1094: fp@1094: \bibitem{doxygen} Doxygen. Source code documentation generator tool. fp@1094: \url{http://www.stack.nl/~dimitri/doxygen}, 2008. fp@1094: fp@1772: \bibitem{mercurial} Mercurial SCM. \url{http://mercurial.selenic.com}, 2010. fp@1772: fp@1772: \bibitem{autoconf} Autoconf -- GNU Project -- Free Software Foundation (FSF). fp@1772: \url{http://www.gnu.org/software/autoconf}, 2010. fp@1772: fp@1917: \bibitem{soespec} IEC 61800-7-304: Adjustable speed electrical power drive fp@1917: systems - Part 7-300: Generic interface and use of profiles for power drive fp@1917: systems - Mapping of profiles to network technologies. International fp@1917: Electrotechnical Commission (IEC), 2007. fp@1917: fp@2515: \bibitem{rtdm} {\it J. Kiszka}: The Real-Time Driver Model and First fp@2515: Applications. fp@2515: \url{http://svn.gna.org/svn/xenomai/tags/v2.4.0/doc/nodist/pdf/RTDM-and-Applications.pdf}, fp@2515: 2013. fp@2515: fp@369: \end{thebibliography} fp@369: fp@917: \printnomenclature fp@369: \addcontentsline{toc}{chapter}{\nomname} fp@369: \markleft{\nomname} fp@369: fp@369: \printindex fp@369: \markleft{Index} fp@369: fp@369: %------------------------------------------------------------------------------ fp@369: fp@369: \end{document} fp@369: fp@369: %------------------------------------------------------------------------------