From ed8f6cd9e1a4cb96576a492a6c9707451a33030d Mon Sep 17 00:00:00 2001 From: Nicola Fontana Date: Wed, 7 Apr 2021 16:49:42 +0200 Subject: [PATCH 01/14] Fix small typo in INSTALL --- INSTALL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index bc402463..d211cedb 100644 --- a/INSTALL +++ b/INSTALL @@ -18,7 +18,7 @@ section of the documentation available from http://etherlab.org/en/ethercat. For the impatient: The procedure mainly consists of calling -$ ./boostrap # to create the configure script, if downloaded from the repo +$ ./bootstrap # to create the configure script, if downloaded from the repo $ ./configure $ make all modules From 566e9289c300024a187a73da82a73ee42458b2c8 Mon Sep 17 00:00:00 2001 From: Bjarne von Horn Date: Thu, 8 Apr 2021 17:35:04 +0200 Subject: [PATCH 02/14] Add .pc file for ethercat lib --- configure.ac | 2 ++ lib/Makefile.am | 2 ++ lib/libethercat.pc.in | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 lib/libethercat.pc.in diff --git a/configure.ac b/configure.ac index 47712deb..e9517115 100644 --- a/configure.ac +++ b/configure.ac @@ -45,6 +45,7 @@ AM_INIT_AUTOMAKE([-Wall -Werror dist-bzip2 subdir-objects]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([config.h.in]) AC_CONFIG_MACRO_DIR([m4]) +PKG_INSTALLDIR() #------------------------------------------------------------------------------ # Global @@ -1112,6 +1113,7 @@ AC_CONFIG_FILES([ examples/xenomai_posix/Makefile include/Makefile lib/Makefile + lib/libethercat.pc m4/Makefile master/Kbuild master/Makefile diff --git a/lib/Makefile.am b/lib/Makefile.am index 764e6b6a..d0cb1bd6 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -73,6 +73,8 @@ libethercat_la_CFLAGS = -fno-strict-aliasing -Wall -I$(top_srcdir) # libethercat_la_LDFLAGS = -version-info 2:0:1 +pkgconfig_DATA = libethercat.pc + #------------------------------------------------------------------------------ if ENABLE_RTDM diff --git a/lib/libethercat.pc.in b/lib/libethercat.pc.in new file mode 100644 index 00000000..54a20b98 --- /dev/null +++ b/lib/libethercat.pc.in @@ -0,0 +1,40 @@ +# +# pkgconfig file for ethercat library +# +# Copyright 2021 Bjarne von Horn (vh at igh dot de) +# +# This file is part of the ethercat library. +# +# The ethercat library is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# The ethercat library is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with the ethercat library. If not, see . +# +# --- +# +# The license mentioned above concerns the source code only. Using the +# EtherCAT technology and brand is only permitted in compliance with the +# industrial property and similar rights of Beckhoff Automation GmbH. +# +# vim: tw=78 noexpandtab +# + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libethercat +Description: Client support library for the EtherCAT Master +URL: http://www.etherlab.org +Version: @VERSION@ +Libs: -L${libdir} -lethercat +Cflags: -I${includedir} From 751f0de50edb2e21c5f9f8a5da4dcf066d6b2fbe Mon Sep 17 00:00:00 2001 From: Sebastien BLANCHET Date: Thu, 8 Apr 2021 18:51:17 +0200 Subject: [PATCH 03/14] doc: compile twice the documentation to update the TOC If you compile once the documentation, the table of contents is empty You have to compile twice to fill the table of contents. --- documentation/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/Makefile b/documentation/Makefile index dc05c80e..d3e4018c 100644 --- a/documentation/Makefile +++ b/documentation/Makefile @@ -55,6 +55,8 @@ pdf: $(EXT_FILES) $(MAKE) -C images $(MAKE) -C graphs pdflatex $(LATEX_OPTIONS) $(FILE) +# compile twice to update the table of contents + pdflatex $(LATEX_OPTIONS) $(FILE) index: makeindex $(FILE) From c76c83fbe2fc15abc4cdab0ff9c02b1314ab6018 Mon Sep 17 00:00:00 2001 From: Sebastien BLANCHET Date: Thu, 8 Apr 2021 18:55:53 +0200 Subject: [PATCH 04/14] doc: promote \subsection to \section in chapter "Timing Aspects" The chapter "Timing Aspects" had \subsection but not \section Therefore, promote all \subsection to \section --- documentation/ethercat_doc.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/ethercat_doc.tex b/documentation/ethercat_doc.tex index fd0bc75a..381ff083 100644 --- a/documentation/ethercat_doc.tex +++ b/documentation/ethercat_doc.tex @@ -2903,7 +2903,7 @@ are rare, there are a few aspects that can (and should be) dealt with. %------------------------------------------------------------------------------ -\subsection{Application Interface Profiling} +\section{Application Interface Profiling} \label{sec:timing-profile} \index{Profiling} % FIXME @@ -2985,7 +2985,7 @@ in \autoref{sec:timing-bus}. %------------------------------------------------------------------------------ -\subsection{Bus Cycle Measuring} +\section{Bus Cycle Measuring} \label{sec:timing-bus} \index{Bus cycle} From 14ed629e3c737d84cef4ffa8c6cfc621bb9ddccf Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Fri, 9 Apr 2021 13:58:52 +0000 Subject: [PATCH 05/14] Update .gitlab-ci.yml file --- .gitlab-ci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 00000000..ecc256c9 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,9 @@ +build: + stage: build + script: + - ./bootstrap + - ./configure + - make all modules + + + \ No newline at end of file From 537fe56414253ca7576a0b5147a4758ca085a6c5 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Fri, 9 Apr 2021 14:02:33 +0000 Subject: [PATCH 06/14] Update .gitlab-ci.yml --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ecc256c9..56a3be57 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,8 +2,8 @@ build: stage: build script: - ./bootstrap - - ./configure + - ./configure --with-linux-dir=/usr/src/linux - make all modules - \ No newline at end of file + From a040c9c16c8d747d9a43493d84ca34a4844c96b8 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Fri, 9 Apr 2021 14:39:27 +0000 Subject: [PATCH 07/14] Update .gitlab-ci.yml --- .gitlab-ci.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 56a3be57..a00bc6c6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,10 @@ build: stage: build + + before_script: + - apt update + - apt install linux-source + script: - ./bootstrap - ./configure --with-linux-dir=/usr/src/linux From 845437f982dd776cf7e98e9f2cf28b4d29a15483 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Fri, 9 Apr 2021 15:38:21 +0000 Subject: [PATCH 08/14] Update .gitlab-ci.yml --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a00bc6c6..f38c27b2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,12 +3,12 @@ build: before_script: - apt update - - apt install linux-source + - apt install -y linux-source linux-headers-4.19.0-16-all script: - ./bootstrap - - ./configure --with-linux-dir=/usr/src/linux - - make all modules + - ./configure --with-linux-dir=/usr/src/linux-headers-4.19.0-16-amd64 --disable-8139too + - make -j8 all modules From 708adaad0d02186f9f502ed11b43ff39bba424fa Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Fri, 9 Apr 2021 16:11:19 +0000 Subject: [PATCH 09/14] Update .gitlab-ci.yml --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f38c27b2..96699ded 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,5 +10,6 @@ build: - ./configure --with-linux-dir=/usr/src/linux-headers-4.19.0-16-amd64 --disable-8139too - make -j8 all modules - +include: + - template: 'Workflows/MergeRequest-Pipelines.gitlab-ci.yml' From 224b7f238b5d3ac3fb7cdd2200b5f47b20f8b842 Mon Sep 17 00:00:00 2001 From: Sebastien BLANCHET Date: Fri, 9 Apr 2021 19:07:29 +0200 Subject: [PATCH 10/14] fix typo --- documentation/ethercat_doc.tex | 2 +- tool/CommandDomains.cpp | 2 +- tool/CommandPdos.cpp | 2 +- tool/CommandSlaves.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/documentation/ethercat_doc.tex b/documentation/ethercat_doc.tex index 381ff083..2e10b0a0 100644 --- a/documentation/ethercat_doc.tex +++ b/documentation/ethercat_doc.tex @@ -307,7 +307,7 @@ EtherCAT functionality (see \autoref{chap:api}). \item Accessing IDNs via the command-line tool. - \item Accessing IDNs at runtime via the the user-space library. + \item Accessing IDNs at runtime via the user-space library. \end{itemize} diff --git a/tool/CommandDomains.cpp b/tool/CommandDomains.cpp index 13fc6cb3..2eb446cd 100644 --- a/tool/CommandDomains.cpp +++ b/tool/CommandDomains.cpp @@ -77,7 +77,7 @@ string CommandDomains::helpString(const string &binaryBaseName) const << endl << "Command-specific options:" << endl << " --domain -d Positive numerical domain index." << endl - << " If ommitted, all domains are" << endl + << " If omitted, all domains are" << endl << " displayed." << endl << endl << " --verbose -v Show FMMUs and process data" << endl diff --git a/tool/CommandPdos.cpp b/tool/CommandPdos.cpp index 126b76c9..b805534e 100644 --- a/tool/CommandPdos.cpp +++ b/tool/CommandPdos.cpp @@ -64,7 +64,7 @@ string CommandPdos::helpString(const string &binaryBaseName) const << "Enable 1" << endl << endl << "2) Assigned PDOs - PDO direction, hexadecimal index and" << endl - << " the PDO name, if avaliable. Note that a 'Tx' and 'Rx'" << endl + << " the PDO name, if available. Note that a 'Tx' and 'Rx'" << endl << " are seen from the slave's point of view. Example:" << endl << endl << " TxPDO 0x1a00 \"Channel1\"" << endl diff --git a/tool/CommandSlaves.cpp b/tool/CommandSlaves.cpp index dedbc089..549068a7 100644 --- a/tool/CommandSlaves.cpp +++ b/tool/CommandSlaves.cpp @@ -58,7 +58,7 @@ string CommandSlaves::helpString(const string &binaryBaseName) const << endl << "1 5555:0 PREOP + EL3162 2C. Ana. Input 0-10V" << endl << "| | | | | |" << endl - << "| | | | | \\- Name from the SII if avaliable," << endl + << "| | | | | \\- Name from the SII if available," << endl << "| | | | | otherwise vendor ID and product" << endl << "| | | | | code (both hexadecimal)." << endl << "| | | | \\- Error flag. '+' means no error," << endl From 6350d7b5ebcb285b59ac12be8a4d32001cdcb953 Mon Sep 17 00:00:00 2001 From: Sebastien BLANCHET Date: Mon, 15 Mar 2021 17:33:33 +0100 Subject: [PATCH 11/14] documentation: add French translation --- documentation/Makefile | 37 +- documentation/ethercat_doc_fr.tex | 3872 +++++++++++++++++++++++++++++ 2 files changed, 3894 insertions(+), 15 deletions(-) create mode 100644 documentation/ethercat_doc_fr.tex diff --git a/documentation/Makefile b/documentation/Makefile index d3e4018c..11db2538 100644 --- a/documentation/Makefile +++ b/documentation/Makefile @@ -54,30 +54,37 @@ $(EXT_FILES): $(ETHERCAT_CMD) pdf: $(EXT_FILES) $(MAKE) -C images $(MAKE) -C graphs - pdflatex $(LATEX_OPTIONS) $(FILE) + # compile twice to update the table of contents pdflatex $(LATEX_OPTIONS) $(FILE) + pdflatex $(LATEX_OPTIONS) $(FILE) + + pdflatex $(LATEX_OPTIONS) $(FILE)_fr + pdflatex $(LATEX_OPTIONS) $(FILE)_fr index: makeindex $(FILE) makeindex $(FILE).nlo -s nomencl.ist -o $(FILE).nls + makeindex $(FILE)_fr + makeindex $(FILE)_fr.nlo -s nomencl.ist -o $(FILE)_fr.nls + clean: @rm -f \ - $(FILE).aux \ - $(FILE).dvi \ - $(FILE).idx \ - $(FILE).ilg \ - $(FILE).ind \ - $(FILE).lof \ - $(FILE).log \ - $(FILE).lol \ - $(FILE).lot \ - $(FILE).nlo \ - $(FILE).nls \ - $(FILE).out \ - $(FILE).pdf \ - $(FILE).toc \ + *.aux \ + *.dvi \ + *.idx \ + *.ilg \ + *.ind \ + *.lof \ + *.log \ + *.lol \ + *.lot \ + *.nlo \ + *.nls \ + *.out \ + *.pdf \ + *.toc \ *~ \ images/*.bak diff --git a/documentation/ethercat_doc_fr.tex b/documentation/ethercat_doc_fr.tex new file mode 100644 index 00000000..9d19e7bd --- /dev/null +++ b/documentation/ethercat_doc_fr.tex @@ -0,0 +1,3872 @@ + +%------------------------------------------------------------------------------ +% +% IgH EtherCAT Master Documentation (French version) +% +% $Id$ +% +% vi: spell spelllang=en tw=78 +% +%------------------------------------------------------------------------------ + +\documentclass[a4paper,12pt,BCOR6mm,bibtotoc,idxtotoc]{scrbook} + +\usepackage[latin1]{inputenc} +\usepackage[automark,headsepline]{scrpage2} +\usepackage[french]{babel} +\usepackage{graphicx} +\usepackage{makeidx} +\usepackage[refpage]{nomencl} +\usepackage{listings} +\usepackage[nofancy]{rcsinfo} +\usepackage{SIunits} +\usepackage{amsmath} % for \text{} +\usepackage{longtable} +\usepackage{hyperref} + + +\hypersetup{pdfpagelabels,plainpages=false} +\hypersetup{linkcolor=blue,colorlinks=true,urlcolor=blue} + +\setlength{\parskip}{0.8ex plus 0.8ex minus 0.5ex} +\setlength{\parindent}{0mm} + +\setcounter{secnumdepth}{\subsubsectionlevel} + +\DeclareFontShape{OT1}{cmtt}{bx}{n} +{ + <5><6><7><8><9><10><10.95><12><14.4><17.28><20.74><24.88>cmttb10 +}{} + +\lstset{basicstyle=\ttfamily\small,numberstyle=\tiny,aboveskip=4mm, + belowskip=2mm,escapechar=`,breaklines=true} +\renewcommand\lstlistlistingname{List of Listings} + +% Workaround for lstlistoflistings bug +\makeatletter% --> De-TeX-FAQ +\renewcommand*{\lstlistoflistings}{% + \begingroup + \if@twocolumn + \@restonecoltrue\onecolumn + \else + \@restonecolfalse + \fi + \lol@heading + \setlength{\parskip}{\z@}% + \setlength{\parindent}{\z@}% + \setlength{\parfillskip}{\z@ \@plus 1fil}% + \@starttoc{lol}% + \if@restonecol\twocolumn\fi + \endgroup +} +\makeatother% --> \makeatletter + +\renewcommand\nomname{Glossaire} + +\newcommand{\IgH}{\raisebox{-0.7667ex} + {\includegraphics[height=2.2ex]{images/ighsign}}} + +\rcsInfo $RCSId$ + +\newcommand{\masterversion}{1.5.2} +\newcommand{\linenum}[1]{\normalfont\textcircled{\tiny #1}} + +\makeindex +\makenomenclature + +% Revision and date on inner footer +\ifoot[\scriptsize\rcsInfoRevision, \rcsInfoDate] + {\scriptsize\rcsInfoRevision, \rcsInfoDate} + +%------------------------------------------------------------------------------ + +\begin{document} + +\pagenumbering{roman} +\pagestyle{empty} + +\begin{titlepage} + \begin{center} + \rule{\textwidth}{1.5mm} + + {\Huge\sf\textbf{IgH \includegraphics[height=2.4ex]{images/ethercat} + Master \masterversion}\\[1ex] + \textbf{Documentation}} + + \vspace{1ex} + \rule{\textwidth}{1.5mm} + + \vspace{\fill} {\Large Dipl.-Ing. (FH) Florian Pose, + \url{fp@igh.de}\\[1ex] Ingenieurgemeinschaft \IgH} + + \vspace{\fill} + {\Large Essen, \rcsInfoLongDate\\[1ex] + R\'evision \rcsInfoRevision} + + \vspace{\fill} {\Large Traduit en fran\c{c}ais par S\'ebastien BLANCHET } + + + \end{center} +\end{titlepage} + +%------------------------------------------------------------------------------ + +\pagestyle{scrplain} + +\tableofcontents +\listoftables +\listoffigures +%\lstlistoflistings + +%------------------------------------------------------------------------------ + +\newpage +\pagestyle{scrheadings} + +\section*{Conventions} +\addcontentsline{toc}{section}{Conventions} +\markleft{Conventions} + +Ce document utilise les conventions typographiques suivantes: + +\begin{itemize} + +\item Le \textit{texte en italique} est utilis\'e pour introduire des nouveaux termes et pour les noms de fichiers. + +\item Le \texttt{texte \`a chasse fixe} est utilis\'e pour les exemples de code et les sorties des lignes de commandes. + +\item Le \texttt{\textbf{texte en gras \`a chasse fixe}} est utilis\'e pour les entr\'ees utilisateurs dans les lignes de commandes. + +\end{itemize} + +Les valeurs des donn\'ees et des adresses sont habituelles +sp\'ecifi\'ees en valeurs hexad\'ecimales. Elles sont indiqu\'ees dans +le style du langage de programmation \textit{C} avec le pr\'efixe +\lstinline+0x+ (par exemple: \lstinline+0x88A4+). Sauf mention +contraire, les valeurs des adresses sont sp\'ecifi\'ees en adresse +d'octets. + + +Les noms des fonctions sont toujours \'ecrits avec des parenth\`eses, +mais sans param\`etre. Ainsi, si une fonction +\lstinline+ecrt_request_master()+ a des parenth\`eses vides, ceci +n'indique pas qu'elle ne prend pas de param\`etres. + +Les commandes shell \`a taper, sont indiqu\'ees par un prompt dollar: + +\begin{lstlisting} +$ +\end{lstlisting} + +Par ailleurs, si une commande shell doit \^etre tap\'ee en tant que le +super utilisateur, le prompt est un di\`ese: + +\begin{lstlisting} +# +\end{lstlisting} + +%------------------------------------------------------------------------------ + +\chapter{Le ma\^itre EtherCAT IgH} +\label{chapter:master} +\pagenumbering{arabic} + +Ce chapitre couvre les informations g\'en\'erales \`a propos du +ma\^itre EtherCAT. + +%------------------------------------------------------------------------------ + +\section{R\'esum\'e des fonctionnalit\'es} +\label{sec:summary} +\index{Master!Features} + +La liste ci-dessous donne un bref r\'esum\'e des fonctionnalit\'es du +ma\^itre. + +\begin{itemize} + +\item Con\c{c}u en tant que module noyau pour Linux 2.6 / 3.x. + +\item Impl\'ement\'e suivant la norme IEC 61158-12 \cite{dlspec} + \cite{alspec}. + +\item Fourni avec des pilotes natifs EtherCAT pour plusieurs + p\'eriph\'eriques Ethernet courants, mais aussi avec un pilote + g\'en\'erique pour toutes les puces Ethernet support\'ees par le + noyau Linux. + + \begin{itemize} + + \item Les pilotes natifs g\`erent le mat\'eriel sans interruption. + + \item Des pilotes natifs pour d'autres p\'eriph\'eriques Ethernet + peuvent \^etre facilement impl\'ement\'es en utilisant l'interface + commune des p\'eriph\'eriques (voir~\autoref{sec:ecdev}) fournie + par le module ma\^itre. + + \item Pour les autres mat\'eriels, le pilote g\'en\'erique peut + \^etre utilis\'e. Il utilise les couches basses de la pile + r\'eseau de Linux. + + \end{itemize} + +\item Le module ma\^itre supporte l'ex\'ecution en parall\`ele de plusieurs ma\^itres EtherCAT. + +\item Le code du ma\^itre supporte n'importe quelle extension temps r\'eel de Linux + au travers de son architecture ind\'ependante. + + + \begin{itemize} + + \item RTAI\nomenclature{RTAI}{Realtime Application Interface} \cite{rtai} + (y compris LXRT via RTDM), ADEOS\nomenclature{ADEOS}{Adaptive Domain + Environment for Operating Systems}, RT-Preempt \cite{rt-preempt}, Xenomai + (y compris RTDM), etc. + + \item Il fonctionne aussi sans extension temps r\'eel. + + \end{itemize} + +\item Une ``API'' commune pour les applications qui veulent utiliser + les fonctionnalit\'es EtherCAT (voir \autoref{chap:api}). + +\item Des \textit{domaines} sont ajout\'es, pour permettre de grouper + les transferts de donn\'ees des processus avec diff\'erents groupes + d'esclaves et de p\'eriodes des t\^aches. + + + \begin{itemize} + + \item Gestion de domaines multiples avec diff\'erentes p\'eriodes de + t\^aches. + + \item Calcul automatique de la cartographie des donn\'ees des + processus, FMMU et configuration automatique des gestionnaires de + synchronisation au sein de chaque domaine. + + \end{itemize} + +\item Communication au travers de plusieurs automates. + + \begin{itemize} + + \item Analyse automatique du bus apr\`es les changements de topologie. + + \item Surveillance du bus pendant les op\'erations. + + \item Reconfiguration automatique des esclaves (par exemple apr\`es + une panne d'alimentation) pendant les op\'erations. + + \end{itemize} + +\item Support des horloges distribu\'ees (Distributed Clocks)(voir + \autoref{sec:dc}). + + \begin{itemize} + + \item Configuration des param\`etres d'horloges distribu\'ees de + l'esclave via l'interface de l'application. + + \item Synchronisation (compensation du d\'ecalage et de la d\'erive) + des horloges distribu\'ees des esclaves avec l'horloge de + r\'ef\'erence. + + \item Synchronisation optionnelle de l'horloge de r\'ef\'erence avec + l'horloge ma\^itre ou dans l'autre sens. + + \end{itemize} + +\item CANopen over EtherCAT (CoE) + + \begin{itemize} + + \item T\'el\'eversement, t\'el\'echargement et service d'information SDO. + + \item Configuration des esclaves via SDOs. + + \item Acc\`es SDO depuis l'espace utilisateur et depuis l'application. + + \end{itemize} + +\item Ethernet over EtherCAT (EoE) + + \begin{itemize} + + \item Utilisation transparente des esclaves EoE via des interfaces + r\'eseaux virtuelles. + + \item Support natif des architectures r\'eseaux EoE commut\'ees ou + rout\'ees. + + \end{itemize} + +\item Vendor-specific over EtherCAT (VoE) + + \begin{itemize} + + \item Communication avec les bo\^ites aux lettres sp\'ecifiques des + vendeurs via l'API. + + \end{itemize} + +\item File Access over EtherCAT (FoE) + + \begin{itemize} + + \item Chargement et enregistrement des fichiers via l'outil en ligne + de commande. + + \item La mise \`a jour du firmware de l'esclave peut \^etre faite + facilement. + + \end{itemize} + +\item Servo Profile over EtherCAT (SoE) + + \begin{itemize} + + \item Impl\'ementation conforme \`a IEC 61800-7 \cite{soespec}. + + \item Enregistrement des configurations IDN, qui sont \'ecrites dans l'esclave pendant le d\'emarrage. + + \item Acc\`es aux IDNs via l'outil en ligne de commande. + + \item Acc\`es aux IDNs pendant l'ex\'ecution via la biblioth\`eque en espace utilisateur. + + \end{itemize} + +\item Outil en ligne de commande ``ethercat'' dans l'espace + utilisateur (voir \autoref{sec:tool}) + + \begin{itemize} + + \item Information d\'etaill\'ee \`a propos du ma\^itre, des + esclaves, domaines et configuration du bus. + \item Param\'etrage du niveau de d\'everminage du ma\^itre. + \item Lecture/Ecriture des adresses d'alias. + \item Listage des configurations des esclaves. + \item Affichage des donn\'ees des processus. + \item T\'el\'echargement/T\'el\'eversement SDO; listage des + dictionnaires SDO. + \item Chargement et enregistrement de fichiers via FoE. + \item Acc\`es IDN SoE. + \item Acc\`es aux registres des esclaves. + \item Acc\`es \`a la SII (EEPROM) de l'esclave. + \item Contr\^ole des \'etats de la couche application. + \item G\'en\'eration de la description des esclaves au format XML et + code C pour les esclaves existants. + + \end{itemize} + +\item Int\'egration syst\`eme transparente au travers de la + conformit\'e LSB\nomenclature{LSB}{Linux Standard Base}. + + \begin{itemize} + + \item Configuration du ma\^itre et des p\'eriph\'eriques r\'eseaux + via des fichiers sysconfig. + + \item Script d'initialisation pour le contr\^ole du ma\^itre. + + \item Fichier de service pour systemd. + + \end{itemize} + +\item Interface r\'eseau virtuelle en lecture seule pour la surveillance et le d\'everminage. + +\end{itemize} + +%------------------------------------------------------------------------------ + +\section{License} +\label{sec:license} + +Le code source du ma\^itre est publi\'ee selon les termes et +conditions de la GNU General Public License (GPL +\cite{gpl})\index{GPL}, version 2. Les d\'eveloppeurs, qui veulent +utiliser EtherCAT pour les syst\`emes Linux, sont invit\'es \`a +utiliser le code source du ma\^itre ou m\^eme \`a participer \`a son +d\'eveloppement. + +Pour autoriser la liaison statique d'une application en espace +utilisateur avec l'API du ma\^itre (voir \autoref{chap:api}), la +biblioth\`eque pour l'espace utilisateur (voir \autoref{sec:userlib}) +est publi\'ee selon les termes et conditions de la GNU Lesser General +Public License (LGPL \cite{lgpl})\index{LGPL}, version 2.1. + +%------------------------------------------------------------------------------ + +\chapter{Architecture} +\label{chap:arch} +\index{Master!Architecture} + +Le ma\^itre EtherCAT est int\'egr\'e au noyau Linux. C'\'etait une +d\'ecision originelle de conception, qui a \'et\'e prise pour +plusieurs raisons: + +\begin{itemize} + +\item Le code du noyau a des caract\'eristiques de temps r\'eel + significativement meilleures, i.\,e.\ une latence plus faible que le + code de l'espace utilisateur. Il \'etait pr\'evisible, qu'un + ma\^itre pour un bus de terrain, ait beaucoup de travail cyclique + \`a faire. Le travail cyclique est habituellement d\'eclench\'e par + des interruptions de timer dans le noyau. Le d\'elai d'ex\'ecution + d'une fonction qui traite une interruption de timer est moindre si + elle r\'eside dans l'espace noyau, parce qu'il n'y a pas besoin de + passer du temps \`a commuter le contexte vers le processus en espace + utilisateur. + +\item Il \'etait pr\'evisible, que le code du ma\^itre doive + communiquer directement avec le mat\'eriel Ethernet. Ceci doit + \^etre fait dans le noyau de toute fa\c{c}on (au travers des pilotes + des p\'eriph\'eriques r\'eseau), ce qui constitue une raison + suppl\'ementaire pour que le code du ma\^itre soit dans l'espace du + noyau. + +\end{itemize} + +La \autoref{fig:arch} fournit une vue d'ensemble de l'architecture du +ma\^itre. + +\begin{figure}[htbp] + \centering + \includegraphics[width=\textwidth]{images/architecture} + \caption{Architecture du ma\^itre} + \label{fig:arch} +\end{figure} + +Les composants de l'environnement du ma\^itre sont d\'ecrits +ci-dessous: + +\begin{description} + +\item[Master Module]\index{Master Module} Module noyau contenant une + ou plusieurs instances du ma\^itre EtherCAT (voir + \autoref{sec:mastermod}), le ``Device Interface'' (interface du + p\'eriph\'erique, voir \autoref{sec:ecdev}) et l'``Application + Interface'' (interface de programmation applicative, voir + \autoref{chap:api}). + +\item[Device Modules]\index{Device modules} Modules\index{Device + modules} de pilotes de p\'eriph\'erique Ethernet supportant EtherCAT + qui offrent leurs p\'eriph\'eriques au ma\^itre EtherCAT via + l'interface du p\'eriph\'erique (voir \autoref{sec:ecdev}). Ces + pilotes r\'eseaux modifi\'es peuvent g\'erer en parall\`ele les + interfaces r\'eseaux utilis\'ees pour les op\'erations EtherCAT et + les interfaces r\'eseaux Ethernet ``normales''. Un ma\^itre peut + accepter un p\'eriph\'erique particulier pour envoyer et recevoir + des trames EtherCAT. Les p\'eriph\'eriques Ethernet d\'eclin\'es + par le module ma\^itre sont connect\'es comme d'habitude \`a la pile + r\'eseau du noyau. + +\item[Application]\index{Application} Un programme qui utilise le + ma\^itre EtherCAT (habituellement pour un \'echange cyclique de + donn\'ees de processus avec les esclaves EtherCAT). Ces programmes + n'appartiennent pas au code du ma\^itre EtherCAT\footnote{Toutefois, + il y a des exemples fournis dans le dossier \textit{examples/}.}, + mais ils doivent \^etre g\'en\'er\'es ou \'ecrits par + l'utilisateur. Une application peut demander un ma\^itre via l'API + (voir \autoref{chap:api}). Si la demande r\'eussie, elle a alors le + contr\^ole du ma\^itre: elle peut fournir une configuration de bus + et \'echanger des donn\'ees de processus. Les applications peuvent + \^etre des modules noyaux (qui utilisent directement l'API du noyau) + ou des programmes dans l'espace utilisateur, qui utilisent l'API via + la biblioth\`eque EtherCAT (voir~\autoref{sec:userlib}), ou la + biblioth\`eque RTDM (voir~\autoref{sec:rtdm}). + +\end{description} + +%------------------------------------------------------------------------------ + +\section{Module Ma\^itre} +\label{sec:mastermod} +\index{Master module} + +Le module noyau du ma\^itre EtherCAT \textit{ec\_master} peut contenir +plusieurs instances ma\^itresses. Chaque ma\^itre attend des +p\'eriph\'eriques Ethernet particuliers identifi\'es par leurs adresses +MAC\index{MAC address}. Ces adresses doivent \^etre sp\'ecifi\'ees au +chargement du module via le param\`etre de module +\textit{main\_devices} (et en option: \textit{backup\_devices}). Le +nombre d'instances ma\^itresses \`a initialiser est d\'efini par le +nombre d'adresses MAC fournies. + +La commande ci-dessous charge le module ma\^itre avec une unique +instance ma\^itresse qui attend un seul p\'eriph\'erique Ethernet dont +l'adresse MAC est \lstinline+00:0E:0C:DA:A2:20+. Le ma\^itre sera +accessible \`a l'index $0$. + +\begin{lstlisting} +# `\textbf{modprobe ec\_master main\_devices=00:0E:0C:DA:A2:20}` +\end{lstlisting} + +Pour plusieurs ma\^itres, des virgules s\'eparent les adresses MAC : + +\begin{lstlisting} +# `\textbf{modprobe ec\_master main\_devices=00:0E:0C:DA:A2:20,00:e0:81:71:d5:1c}` +\end{lstlisting} + +Les deux ma\^itres peuvent \^etre adress\'es par leurs indices +respectifs 0 et 1 (voir \autoref{fig:masters}). L'index du ma\^itre +est requis par la fonction \lstinline+ecrt_master_request()+ de l'API +(voir \autoref{chap:api}) et par l'option \lstinline+--master+ de +l'outil de commande en ligne \textit{ethercat} (voir +\autoref{sec:tool}), qui vaut $0$ par d\'efaut. + +\begin{figure}[htbp] + \centering + \includegraphics[width=.5\textwidth]{images/masters} + \caption{Plusieurs ma\^itres dans un module} + \label{fig:masters} +\end{figure} + +\paragraph{Niveau de d\'everminage} Le module ma\^itre a aussi un +param\`etre \textit{debug\_level} pour configurer le niveau initial de +d\'everminage pour tous les ma\^itres (voir +aussi~\autoref{sec:ethercat-debug}). + +\paragraph{Script d'initialisation} +\index{Init script} + +Dans la plupart des cas, il n'est pas n\'ecessaire de charger +manuellement le module ma\^itre et les modules des pilotes Ethernet. +Un script d'initialisation est disponible pour d\'emarrer le ma\^itre +en tant que service (voir \autoref{sec:system}). Un fichier de service +est aussi disponible pour les syst\`emes qui sont g\'er\'es par +systemd \cite{systemd}. + +\paragraph{Syslog} + +Le module ma\^itre publie des informations \`a propos de son \'etat et ses +\'ev\'enement dans le tampon circulaire du noyau. Elles aboutissent aussi +dans les journaux syst\`emes. La commande de chargement du module +devrait produire les messages ci-dessous: + +\begin{lstlisting} +# `\textbf{dmesg | tail -2}` +EtherCAT: Master driver `\masterversion` +EtherCAT: 2 masters waiting for devices. + +# `\textbf{tail -2 /var/log/messages}` +Jul 4 10:22:45 ethercat kernel: EtherCAT: Master driver `\masterversion` +Jul 4 10:22:45 ethercat kernel: EtherCAT: 2 masters waiting + for devices. +\end{lstlisting} + +Les messages du ma\^itre sont pr\'efix\'es par \lstinline+EtherCAT+ pour +faciliter la recherche dans les journaux. + +%------------------------------------------------------------------------------ + +\section{Phases du ma\^itre} +\index{Master phases} + +Chaque ma\^itre EtherCAT fourni par le module ma\^itre (voir +\autoref{sec:mastermod}) traverse plusieurs phases au cours de son +ex\'ecution (voir \autoref{fig:phases}): + +\begin{figure}[htbp] + \centering + \includegraphics[width=.9\textwidth]{images/phases} + \caption{Phases et transitions du ma\^itre} + \label{fig:phases} +\end{figure} + +\begin{description} + +\item[Phase orpheline (Orphaned)]\index{Orphaned phase} Ce mode prend + effet quand le ma\^itre attend encore pour se connecter \`a ses + p\'eriph\'eriques Ethernet. Aucune communication de bus n'est possible + pour l'instant. + +\item[Phase paresseuse (Idle)]\index{Idle phase} Ce mode prend effet + quand le ma\^itre a accept\'e tous les p\'eriph\'eriques Ethernet + requis, mais qu'aucune application ne l'a encore mobilis\'e. Le + ma\^itre ex\'ecute son automate (voir \autoref{sec:fsm-master}), qui + analyse automatiquement le bus pour rechercher les esclaves et + ex\'ecuter les op\'erations en attente depuis l'interface en espace + utilisateur (par exemple les acc\`es SDO). L'outil en ligne de + commande peut \^etre utilis\'e pour acc\'eder au bus, mais il n'y a + aucun \'echange de donn\'ee de processus parce que la configuration + du bus est manquante. + +\item[Phase d'op\'eration]\index{Operation phase} Le ma\^itre est + mobilis\'e par une application qui peut fournir une configuration de + bus et \'echanger des donn\'ees de processus.. + +\end{description} + +%------------------------------------------------------------------------------ + +\section{Donn\'ees de processus} +\label{sec:processdata} + +Cette section pr\'esente quelques termes et id\'ees sur la mani\`ere +dont le ma\^itre traite les donn\'ees de processus. + +\paragraph{Image des donn\'ees de processus} +\index{Process data} + +Les esclaves pr\'esentent leurs entr\'es et sorties au ma\^itre au +travers d'objet de donn\'ees de processus ``Process Data Objects'' +(PDOs\index{PDO}). Les PDOs disponibles peuvent \^etre d\'etermin\'es +en lisant les cat\'egories SII TxPDO et RxPDO de l'esclave depuis +l'E$^2$PROM (en cas de PDOs fixes) ou en lisant les objets CoE +appropri\'es (voir \autoref{sec:coe}), si disponibles. L'application +peut inscrire les entr\'ees des PDOs pour l'\'echange pendant +l'op\'eration cyclique. La somme de toutes les entr\'ees PDO +inscrites d\'efinit l'``image des donn\'ees du processus'', qui peut +\^etre \'echang\'ee via des datagrammes avec des acc\`es m\'emoires +``logiques'' (comme LWR\footnote{LWR: Logical Write}, +LRD\footnote{LRD: Logical Read} ou LRW\footnote{LRW: Logical +Read/Write}) pr\'esent\'es dans ~\cite[sec.~5.4]{dlspec}. + +\paragraph{Domaine de donn\'ees de processus} +\index{Domain} + +Les images des donn\'ees de processus peuvent \^etre facilement +g\'er\'ees en cr\'eant des ``domaines'', qui permettent l'\'echange de +PDO group\'es. Ils s'occupent \'egalement de g\'erer les structures +des datagrammes qui sont n\'ecessaires pour \'echanger les PDOs. Les +domaines sont obligatoires pour l'\'echange de donn\'ees de processus, +donc il doit y en avoir au moins un. Ils ont \'et\'e introduits pour +les raisons suivantes: + +\begin{itemize} + +\item La taille maximale d'un datagramme est limit\'ee par celle d'une + trame Ethernet. La taille maximale des donn\'ees est la taille du + champ ``donn\'ees'' d'Ethernet moins l'ent\^ete de la trame + Ethernet, moins l'ent\^ete du datagramme EtherCAT et moins la + terminaison du datagramme EtherCAT: $1500 - 2 - 12 - 2 = 1484$ + octets. Si la taille de l'image des donn\'ees de processus d\'epasse + cette limite, il faut envoyer plusieurs trames et partitionner + l'image pour utiliser plusieurs datagrammes. Un domaine g\`ere cela + automatiquement. + +\item Tous les PDOs n'ont pas besoin d'\^etre \'echang\'es \`a la + m\^eme fr\'equence: les valeurs des PDOs peuvent varier lentement au + cours du temps (par exemple des valeurs de temp\'erature), aussi les + \'echanger \`a haute fr\'equence serait un gaspillage de la bande + passante du bus. Pour cette raison, plusieurs domaines peuvent + \^etre cr\'e\'es, pour grouper diff\'erents PDOs et ainsi s\'eparer + les \'echanges. + +\end{itemize} + +Il n'y a aucune limite sup\'erieure pour le nombre de domaines, mais +chaque domaine occupe une FMMU\footnote{FMMU: Fieldbus Memory +Management Unit} dans l'esclave concern\'e, donc le nombre maximal de +domaines est en fait limit\'e par les esclaves. + +\paragraph{Configuration FMMU} +\index{FMMU!Configuration} + +Une application peut inscrire des entr\'ees PDO pour l'\'echange. +Chaque entr\'ee PDO et son PDO parent font partie d'une zone m\'emoire +dans la m\'emoire physique de l'esclave, qui est prot\'eg\'ee par un +gestionnaire de synchronisation (sync manager) \cite[sec.~6.7]{dlspec} +pour des acc\`es synchronis\'es. Pour que le gestionnaire de +synchronisation r\'eagisse \`a un datagramme qui acc\`ede \`a sa +m\'emoire, il est n\'ecessaire d'acc\'eder au dernier octet couvert +par le gestionnaire de synchronisation. Sinon le gestionnaire de +synchronisation ne r\'eagira pas au datagramme et aucune donn\'ee ne +sera \'echang\'ee. C'est pourquoi l'ensemble de la zone m\'emoire +synchronis\'ee doit \^etre inclus dans l'image des donn\'ees de +processus: par exemple; si une entr\'ee PDO particuli\`ere d'un +esclave est inscrite pour l'\'echange avec un domaine particulier, une +FMMU sera configur\'ee pour mapper toute la m\'emoire prot\'eg\'ee par +le gestionnaire de synchronisation dans laquelle l'entr\'ee PDO +r\'eside. Si une deuxi\`eme entr\'ee PDO du m\^eme esclave est +inscrite pour l'\'echange de donn\'ee de processus au sein du m\^eme +domaine, et s'il r\'eside dans la m\^eme zone m\'emoire prot\'eg\'ee +par le gestionnaire de synchronisation que la premi\`ere entr\'ee, +alors la configuration FMMU n'est pas modifi\'ee, parce que la +m\'emoire d\'esir\'ee fait d\'ej\`a partie de l'image des donn\'ees du +processus du domaine. Si la deuxi\`eme entr\'ee appartenait \`a une +autre zone prot\'eg\'ee par le gestionnaire de synchronisation, alors +cette zone enti\`ere serait aussi incluse dans l'image des donn\'ees +des processus des domaines. + +\autoref{fig:fmmus} fournit un aper\c{c}u de la mani\`ere de +configurer les FMMUs pour mapper la m\'emoire physique vers les images +logiques des donn\'ees des processus. + +\begin{figure}[htbp] + \centering + \includegraphics[width=\textwidth]{images/fmmus} + \caption{Configuration FMMU} + \label{fig:fmmus} +\end{figure} + +%------------------------------------------------------------------------------ + +\chapter{Interface de Programmation Applicative (API)} +\label{chap:api} +\index{Application interface} + +% TODO +% +% Interface version +% Master Requesting and Releasing +% Master Locking +% Configuring PDO assignment and mapping +% Domains (memory) +% PDO entry registration +% SDO configuration +% SDO access +% IDN configurations +% IDN access + +L'interface de programmation applicative fournit les fonctions et +structures de donn\'ees pour acc\'eder au ma\^itre EtherCAT. La +documentation compl\`ete de l'interface est incluse sous forme de +commentaires Doxygen~\cite{doxygen} dans le fichier d'ent\^ete +\textit{include/ecrt.h}. Elle peut \^etre lue directement depuis les +commentaires du fichier, ou plus confortablement sous forme de +documentation HTML. La g\'en\'eration du HTML est d\'ecrite dans +\autoref{sec:gendoc}. + +Les sections suivantes couvrent une description g\'en\'erale de l'API. + +Chaque application devrait utiliser le ma\^itre en deux \'etapes: + +\begin{description} + +\item[Configuration] Le ma\^itre est mobilis\'e et la configuration + est appliqu\'ee. Par exemple, les domaines sont cr\'e\'es, les + esclaves sont configur\'es et les entr\'ees PDO sont inscrites. + (voir \autoref{sec:masterconfig}). + +\item[Op\'eration] Le code cyclique est ex\'ecut\'e et les donn\'ees de + processus sont \'echang\'ees (voir \autoref{sec:cyclic}). + +\end{description} + +\paragraph{Exemple d'Applications}\index{Example Applications} +Il y a quelques exemples d'applications dans le sous-dossier +\textit{examples/} du code du ma\^itre. Ils sont document\'es dans le +code source. + +%------------------------------------------------------------------------------ + +\section{Configuration du ma\^itre} +\label{sec:masterconfig} + +La configuration du bus est fournie via l'API. La +\autoref{fig:app-config} donne une vue d'ensemble des objets qui +peuvent \^etre configur\'es par l'application. + +\begin{figure}[htbp] + \centering + \includegraphics[width=.8\textwidth]{images/app-config} + \caption{Configuration du ma\^itre} + \label{fig:app-config} +\end{figure} + +\subsection{Configuration de l'esclave} + +L'application doit dire au ma\^itre quelle est la topologie attendue +du bus. Ceci peut \^etre fait en cr\'eant des ``configurations +d'esclaves''. Une configuration d'esclave peut \^etre vue comme un +esclave attendu. Quand une configuration d'esclave est cr\'e\'ee, +l'application fournit la position sur le bus (voir ci-dessous), +l'identifiant du fabricant (vendor id) et le code du produit (product +code). + +Quand la configuration du bus est appliqu\'ee, le ma\^itre v\'erifie +s'il y a un esclave avec l'identifiant du fabricant et le code du +produit \`a la position donn\'ee. Si c'est le cas, la configuration +de l'esclave est ``attach\'ee'' \`a l'esclave r\'eel sur le bus et +l'esclave est configur\'e en fonction des param\`etres fournis par +l'application. L'\'etat de la configuration de l'esclave peut soit +\^etre demand\'e via l'API ou via l'outil en ligne de commande (voir +\autoref{sec:ethercat-config}). + +\paragraph{Position de l'esclave} La position de l'esclave doit \^etre +sp\'ecifi\'ee sous forme d'un couple ``alias'' et ``position''. Ceci +permet d'adresser les esclaves via la position absolue sur le bus ou +via un identifiant stock\'e et appel\'e ``alias'' ou via un m\'elange +des deux. L'alias est une valeur 16 bits stock\'ee dans E$^2$PROM de +l'esclave. Il peut \^etre modifi\'e via l'outil en ligne de commande +(voir \autoref{sec:ethercat-alias}). \autoref{tab:slaveposition} +montre comment les valeurs sont interpr\'et\'ees. + +\begin{table}[htbp] + \centering + \caption{Sp\'ecifier la position d'un esclave} + \label{tab:slaveposition} + \vspace{2mm} + \begin{tabular}{c|c|p{70mm}} + Alias & Position & Interpr\'etation\\ + \hline + + \lstinline+0+ & \lstinline+0+ -- \lstinline+65535+ & + + Adressage par position. Le param\`etre de position est + interpr\'et\'e comme la position absolue de l'anneau sur le + bus.\\ \hline + + \lstinline+1+ -- \lstinline+65535+ & \lstinline+0+ -- \lstinline+65535+ & + + Adressage par alias. Le param\`etre de position est interpr\'et\'e + comme une position relative apr\`es le premier esclave + avec une adresse d'alias donn\'ee. \\ \hline + + \end{tabular} +\end{table} + +\autoref{fig:attach} montre un exemple d'attachement des +configurations des esclaves. Certaines configurations sont +attach\'ees, tandis que d'autres restes d\'etach\'ees. La liste +ci-dessous en donne les raisons en commen\c{c}ant par la configuration +de l'esclave du haut. + +\begin{figure}[htbp] + \centering + \includegraphics[width=.7\textwidth]{images/attach} + \caption{Attachement de la configuration des esclaves} + \label{fig:attach} +\end{figure} + +\begin{enumerate} + +\item L'alias z\'ero signifie un adressage simple par position. + L'esclave \#1 existe et l'identifiant du fabricant et le code + produit correspondent aux valeurs attendues. + +\item Bien que l'esclave en position 0 a \'et\'e trouv\'e, le code + produit ne correspond pas, aussi la configuration n'est pas + attach\'ee. + +\item L'alias n'est pas z\'ero, aussi l'adressage par alias est + utilis\'e. L'esclave \#2 est le premier esclave avec l'alias + \lstinline+0x2000+. Comme la valeur de position est z\'ero, le + m\^eme esclave est utilis\'e. + +\item Il n'y a aucun esclave avec l'alias demand\'e, aussi la + configuration ne peut pas \^etre attach\'ee. + +\item L'esclave \#2 est encore le premier esclave avec l'alias + \lstinline+0x2000+, mais la position est maintenant 1, aussi + l'esclave \#3 est attach\'e. +\end{enumerate} + +Si les sources du ma\^itre sont configur\'ees avec +\lstinline+--enable-wildcards+, alors +\lstinline+0xffffffff+ correspond \`a n'importe quel identifiant de fabricant et/ou code produit. + +%------------------------------------------------------------------------------ + +\section{Op\'eration cyclique} +\label{sec:cyclic} + +Pour entrer dans le mode d'op\'eration cyclique, le ma\^itre doit \^etre +``activ\'e'' pour calculer l'image des donn\'ees de processus et appliquer +la configuration du bus pour la premi\`ere fois. Apr\`es l'activation, +l'application est responsable d'envoyer et recevoir les trames. +La configuration ne peut pas \^etre modifi\'ee apr\`es l'activation. + +% TODO +% +% PDO endianess +% Datagram injection + +%------------------------------------------------------------------------------ + +\section{Gestionnaires VoE} +\label{sec:api-voe} + +Pendant la phase de configuration, l'application peut cr\'eer des +gestionnaires pour le protocole de bo\^ite aux lettres VoE, d\'ecrit +dans \autoref{sec:voe}. Un gestionnaire VoE appartient toujours \`a +une configuration d'esclave particuli\`ere, aussi la fonction de +cr\'eation est une m\'ethode de la configuration de l'esclave. + +Un gestionnaire VoE g\`ere les donn\'ees VoE et les datagrammes +utilis\'es pour transmettre et recevoir les messages VoE. Il contient +l'automate n\'ecessaire au transfert des messages VoE. + +L'automate VoE peut traiter seulement une op\'eration \`a la fois. Par +cons\'equent, seule une op\'eration de lecture ou une op\'eration +d'\'ecriture peut \^etre \'emise \`a un moment donn\'e\footnote{Si, on +d\'esire envoyer et recevoir simutan\'ement, deux gestionnaires VoE +peuvent \^etre cr\'e\'es pour la configuration de l'esclave.}. Apr\`es +l'initialisation de l'op\'eration, le gestionnaire doit \^etre +ex\'ecut\'e de mani\`ere cyclique jusqu'\`a ce qu'il se termine. +Apr\`es cela, les r\'esultats de l'op\'eration peuvent \^etre +r\'ecup\'er\'es. + +Un gestionnaire VoE a sa propre structure de datagramme, qui est +marqu\'e pour l'\'echange apr\`es chaque pas d'ex\'ecution. Aussi, +l'application peut d\'ecider, combien de gestionnaires elle ex\'ecute +avant d'envoyer les trames EtherCAT correspondantes. + +Pour obtenir davantage d'information sur les gestionnaires VoE, +consultez la documentation des fonctions de l'API et les exemples +d'applications fournis dans le dossier \textit{examples/}. + +%------------------------------------------------------------------------------ + +\section{Acc\`es concurrents au ma\^itre} +\label{sec:concurr} +\index{Concurrency} + +Dans certains cas, plusieurs instances utilisent un seul ma\^itre, +par exemple quand une application \'echange des donn\'ees de processus +cyclique et qu'il y a des esclaves EoE qui ont besoin d'\'echanger des +donn\'ees Ethernet avec le noyau (voir \autoref{sec:eoe}). Pour +cette raison, le ma\^itre est une ressource partag\'ee qui doit \^etre +s\'equentialis\'ee. Ceci est habituellement r\'ealis\'e en +verrouillant au moyen de s\'emaphores ou d'autres m\'ethodes pour +prot\'eger les sections critiques. + +Le ma\^itre ne fournit pas lui-m\^eme de m\'ecanismes de +verrouillage, parce qu'il ne peut conna\^itre le type de +verrou appropri\'e. Par exemple, si l'application est en espace noyau +et utilise la fonctionnalit\'e RTAI, les s\'emaphores ordinaires du +noyau ne seraient pas suffisants. Pour cela, une d\'ecision de +conception importante a \'et\'e faite: l'application qui a r\'eserv\'e +un ma\^itre doit en avoir le contr\^ole total, c'est pourquoi elle +doit prendre la responsabilit\'e de fournir les m\'ecanismes de +verrouillage appropri\'es. Si une autre instance veut acc\'eder au +ma\^itre, elle doit demander l'acc\`es au bus via des fonctions de +rappels qui doivent \^etre fournis par l'application. De plus, +l'application peut refuser l'acc\`es au ma\^itre, si elle consid\`ere +que le moment est g\^enant. + +\begin{figure}[htbp] + \centering + \includegraphics[width=.6\textwidth]{images/master-locks} + \caption{Acc\`es concurrent au ma\^itre} + \label{fig:locks} +\end{figure} + +L'exemple \autoref{fig:locks} montre comment deux processus partagent +un ma\^itre: la t\^ache cyclique de l'application utilise le ma\^itre +pour l'\'echange de donn\'ees de processus, tandis que le processus +EoE interne au ma\^itre l'utilise pour communiquer avec les esclaves +EoE. Les deux ont acc\`es au bus de temps en temps, mais le processus +EoE le fait en ``demandant'' \`a l'application de r\'ealiser l'acc\`es +au bus pour lui. De cette mani\`ere, l'application peut utiliser le +m\'ecanisme de verrouillage appropri\'e pour \'eviter d'acc\`eder au +bus en m\^eme temps. Voir la documentation de l'API +(\autoref{chap:api}) pour savoir comment utiliser ces fonctions de +rappel. + +%------------------------------------------------------------------------------ + +\section{Horloges distribu\'ees} +\label{sec:dc} +\index{Distributed Clocks} + +\`A partir de la version 1.5, le ma\^itre supporte les ``horloges distribu\'ees'' (Distributed Clocks) EtherCAT pour synchroniser les horloges des esclaves +sur le bus avec l'horloge de ``r\'ef\'erence'' +(qui est l'horloge locale du premier esclave qui supporte l'horloge +distribu\'ee) et pour synchroniser l'horloge de r\'ef\'erence avec +``l'horloge ma\^itresse'' (qui est l'horloge locale du ma\^itre). +Toutes les autres horloges du bus (apr\`es l'horloge de r\'ef\'erence) +sont consid\'er\'es comme ``horloges esclaves'' (voir \autoref{fig:dc}). + +\begin{figure}[htbp] + \centering + \includegraphics[width=.8\textwidth]{images/dc} + \caption{Horloges distribu\'ees} + \label{fig:dc} +\end{figure} + +\paragraph{Horloges locales} Tout esclave EtherCAT qui supporte +l'horloge distribu\'ee +poss\`ede un registre d'horloge locale avec une r\'esolution \`a la +nanoseconde. Si l'esclave est allum\'e, l'horloge d\'emarre depuis +z\'ero, ce qui signifie que lorsque des esclaves sont allum\'es \`a +diff\'erents instants, leurs horloges auront des valeurs diff\'erentes. +Ces ``d\'ecalages'' doivent \^etre compens\'es par le m\'ecanisme des +horloges distribu\'ees. En outre, les horloges ne tournent +pas exactement \`a la m\^eme vitesse, puisque les quartzs ont une +d\'eviation de leur fr\'equence naturelle. Cette d\'eviation est +habituellement tr\`es faible, mais au bout de longues p\'eriodes, +l'erreur s'accumulera et la diff\'erence entre les horloges locales +grandira. Cette ``d\'erive'' des horloges doit aussi \^etre +compens\'ee par le m\'ecanisme des horloges distribu\'ees. + +\paragraph{Temps de l'Application} La base de temps commune pour le bus +doit \^etre fournie par l'application. +Ce temps d'application $t_\text{app}$ est utilis\'e + +\begin{enumerate} +\item pour configurer les d\'ecalages des horloges des esclaves (voir ci-dessous), +\item pour programmer les temps de d\'emarrage de l'esclave pour + la g\'en\'eration des impulsions synchrones. (voir ci-dessous) +\item pour synchroniser les horloges de r\'ef\'erence avec l'horloge + ma\^itresse (optionnel). +\end{enumerate} + +\paragraph{Compensation du d\'ecalage} Pour la compensation du d\'ecalage, +chaque esclave fournit un registre de ``d\'ecalage du temps +syst\`eme'' $t_\text{off}$, qui est ajout\'e \`a la valeur de +l'horloge interne $t_\text{int}$ pour obtenir le ``Temps Syst\`eme'' +$t_\text{sys}$: + +\begin{eqnarray} +t_\text{sys} & = & t_\text{int} + t_\text{off} \\ +\Rightarrow t_\text{int} & = & t_\text{sys} - t_\text{off} \nonumber +\end{eqnarray} + +Le ma\^itre lit les valeurs des deux registres pour calculer un nouveau +d\'ecalage du temps syst\`eme de telle mani\`ere que +le temps syst\`eme r\'esultant corresponde au temps de l'application du +ma\^itre $t_\text{app}$: + +\begin{eqnarray} +t_\text{sys} & \stackrel{!}{=} & t_\text{app} \\ +\Rightarrow t_\text{int} + t_\text{off} & \stackrel{!}{=} & t_\text{app} \nonumber \\ +\Rightarrow t_\text{off} & = & t_\text{app} - t_\text{int} \nonumber \\ +\Rightarrow t_\text{off} & = & t_\text{app} - (t_\text{sys} - t_\text{off}) \nonumber \\ +\Rightarrow t_\text{off} & = & t_\text{app} - t_\text{sys} + t_\text{off} +\end{eqnarray} + + +La petite erreur de d\'ecalage du temps r\'esultant des diff\'erences +de temps entre la lecture et l'\'ecriture des registres sera compens\'ee +par la compensation de la d\'erive. + +\paragraph{Compensation de la d\'erive} La compensation de la d\'erive +est possible gr\^ace \`a un m\'ecanisme sp\'ecial de chaque esclave +compatible avec les horloges distribu\'ees: une op\'eration +d'\'ecriture dans le registre du ``Temps syst\`eme'' obligera la boucle +de contr\^ole du temps interne \`a comparer le temps \'ecrit (moins le +d\'elai de transmission programm\'e, voir ci-dessous) avec le temps +syst\`eme courant. L'erreur de temps calcul\'ee sera utilis\'ee comme +une entr\'ee pour le contr\^oleur de temps, qui ajustera la vitesse de +l'horloge locale pour \^etre l\'eg\`erement plus rapide ou plus +lente\footnote{ L'horloge locale de l'esclave sera incr\'ement\'ee de +\unit{9}{\nano\second}, \unit{10}{\nano\second} ou +\unit{11}{\nano\second} toute les \unit{10}{\nano\second}.}, en +fonction du signe de l'erreur. + +\paragraph{D\'elais de transmission} La trame Ethernet a besoin +d'une petite quantit\'e de temps pour se propager d'esclave en +esclave. Les d\'elais de transmission s'accumulent sur le bus et +peuvent attendre la magnitude de la microseconde et doivent alors +\^etre pris en compte par la compensation de la d\'erive. Les +esclaves EtherCAT qui supportent les horloges distribu\'ees +fournissent un m\'ecanisme pour mesurer les d\'elais de transmission: +pour chacun des 4 ports de l'esclave il y a un registre d'heure de +r\'eception. Une op\'eration d'\'ecriture sur le registre d'heure de +r\'eception du port d\'emarre la mesure et l'heure syst\`eme courante +est captur\'ee et stock\'ee dans un registre d'heure de r\'eception +une fois que la trame est re\c{c}ue sur le port correspondant. Le +ma\^itre peut lire le temps de r\'eception relatif puis calculer les +d\'elais entre les esclaves (en utilisant sa connaissance de la +topologie du bus), et finalement calculer les d\'elais de chaque +esclave avec l'horloge de r\'ef\'erence. Ces valeurs sont +programm\'ees dans les registres de d\'elai de transmission des +esclaves. De cette mani\`ere, la compensation de la d\'erive peut +attendre une synchronie \`a la nanoseconde. + +\paragraph{V\'erification de la synchronie} +Les esclaves compatibles avec les horloge distribu\'ees fournissent un +registre 32 bits ``Diff\'erence de l'heure syst\`eme'' \`a l'adresse +\lstinline+0x092c+, dans lequel la diff\'erence de temps syst\`eme de +la derni\`ere compensation de la d\'erive est stock\'ee avec une +r\'esolution d'une nanoseconde et un codage +signe-et-magnitude\footnote{Ceci permet une lecture-diffusion de tous +les registres de diff\'erence de temps syst\`eme sur le bus pour +obtenir une approximation de la valeur sup\'erieure.}. Pour v\'erifier +la synchronie du bus, les registres de diff\'erence du temps syst\`eme +peuvent aussi \^etre lus via l'outil en ligne de commande (voir +\autoref{sec:regaccess}): + +\begin{lstlisting} +$ `\textbf{watch -n0 "ethercat reg\_read -p4 -tsm32 0x92c"}` +\end{lstlisting} + +\paragraph{Signaux synchrones} Les horloge synchrones +sont seulement un pr\'e-requis pour des \'ev\`enements synchrones sur +le bus. Chaque esclave qui supporte les horloges distribu\'ees +fournit deux ``signaux synchrones'', qui peuvent \^etre programm\'es +pour cr\'eer des \'ev\`enements, qui vont par exemple obliger +l'application esclave \`a capturer ses entr\'ees \`a un instant +pr\'ecis. Un \'ev\`enement synchrone peut \^etre g\'en\'er\'e soit +une seule fois ou p\'eriodiquement, selon ce qui a du sens pour +l'application esclave. La programmation des signaux synchrones est +une question de r\'eglage du mot ``AssignActivate'' et des temps +de cycle et d\'ecalage des signaux de synchronisation. Le mot +AssignActivate est sp\'ecifique \`a chaque esclave et doit \^etre +r\'ecup\'er\'e depuis la description XML de l'esclave +(\lstinline+Device+ $\rightarrow$ \lstinline+Dc+), o\`u se trouvent +aussi typiquement les signaux de configurations ``OpModes''. + +%------------------------------------------------------------------------------ + +\chapter{Interfaces Ethernet} +\label{sec:devices} + +Le protocole EtherCAT est fond\'e sur le standard Ethernet standard, +aussi un ma\^itre d\'epend du mat\'eriel Ethernet standard pour communiquer +avec le bus. + +Le terme \textit{device} est utilis\'e comme synonyme pour mat\'eriel +d'interface r\'eseau Ethernet. + +\paragraph{Pilotes natifs pour p\'eriph\'eriques Ethernet} +Il y a des modules natifs pour les pilotes de p\'eriph\'eriques (voir +\autoref{sec:native-drivers}) qui g\`erent le mat\'eriel Ethernet +qu'utilise le ma\^itre pour se connecter au bus EtherCAT. Ils offrent +leurs mat\'eriels Ethernet au module ma\^itre via l'interface de +device (voir \autoref{sec:ecdev}) et doivent \^etre capable de +pr\'eparer les p\'eriph\'eriques Ethernet pour les op\'erations +EtherCAT (temps r\'eel) ou pour les op\'erations ``normales'' en +utilisant la pile r\'eseau du noyau. L'avantage de cete approche est +que le ma\^itre peut op\'erer pratiquement directement avec le +mat\'eriel ce qui permet des performances +\'elev\'ees. L'inconv\'enient est qu'il faut avoir une version +compatible EtherCAT du pilote Ethernet original. + +\paragraph{Pilote g\'en\'erique pour les p\'eriph\'eriques Ethernet} +\`A partir du ma\^itre version 1.5, il y a un module de pilote +g\'en\'erique pour les p\'eriph\'eriques Ethernet (voir +\autoref{sec:generic-driver}), qui utilise les couches basses de la +pile r\'eseau pour se connecter au mat\'eriel. L'avantage est que +n'importe quel p\'eriph\'erique Ethernet peut \^etre utilis\'e pour les +op\'erations EtherCAT, ind\'ependamment du pilote mat\'eriel r\'eel +(ainsi tous les pilotes Ethernet Linux sont support\'es sans +modification). L'inconv\'enient est que cette approche ne supporte +pas les extensions temps r\'eel, comme RTAI, parce que la pile +r\'eseau de Linux est utilis\'ee. Cependant la performance est +l\'eg\`erement moins bonne qu'avec l'approche native, car les donn\'ees +de la trame Ethernet doivent traverser la pile r\'eseau. + +%------------------------------------------------------------------------------ + +\section{Principes de base du pilote r\'eseau} +\label{sec:networkdrivers} +\index{Network drivers} + +EtherCAT repose sur le mat\'eriel Ethernet et le ma\^itre a besoin d'un +p\'eriph\'erique Ethernet physique pour communiquer avec le bus. +C'est pourquoi, il est n\'ecessaire de comprendre comment Linux g\`ere +les p\'eriph\'eriques r\'eseaux et leurs pilotes. + +\paragraph{T\^aches d'un pilote r\'eseau} +Les pilotes de p\'eriph\'eriques r\'eseaux g\`erent habituellement les +deux couches les plus basses du mod\`ele OSI, qui sont la couche +physique et la couche liaison de donn\'ees. Le p\'eriph\'erique +r\'eseau g\`ere nativement les probl\`emes de la couche physique: il +repr\'esente le mat\'eriel pour se connecter au m\'edia et pour +envoyer et recevoir des donn\'ees de la mani\`ere d\'ecrite par le +protocole de la couche physique. Le pilote de p\'eriph\'erique +r\'eseau est responsable de r\'ecup\'erer les donn\'ees depuis la pile +r\'eseau du noyau et de les faire suivre au p\'eriph\'erique qui fait +la transmission physique. Si des donn\'ees sont re\c{c}ues par le +p\'eriph\'erique alors le pilote est notifi\'e (habituellement au moyen +d'une interruption) et il doit lire les donn\'ees depuis la m\'emoire +du p\'eriph\'erique et l'envoyer \`a la pile r\'eseau. Un pilote de +p\'eriph\'erique r\'eseau doit aussi g\'erer d'autres t\^aches telles +que le contr\^ole de la file d'attente, les statistiques et les +fonctionnalit\'es sp\'ecifiques du p\'eriph\'erique. + +\paragraph{D\'emarrage du pilote} Habituellement, un pilote recherche +des p\'eriph\'eriques compatibles lors du chargement du module. Pour +les pilotes PCI, ceci est fait en analysant le bus PCI et en +v\'erifiant les identifiants (ID) des p\'eriph\'eriques. Si un +p\'eriph\'erique est trouv\'e, les structures de donn\'ees sont +allou\'ees et le p\'eriph\'erique est mis en service. + +\paragraph{Fonctionnement des interruptions}\index{Interrupt} Un +p\'eriph\'erique r\'eseau fournit g\'en\'eralement une interruption +mat\'erielle qui est utilis\'ee pour notifier le pilote des trames +re\c{c}ues et des succ\`es ou erreurs des transmissions. Le pilote +doit enregistrer une routine de service d'interruption -- en anglais +\textit{interrupt service routine} -- +(ISR\index{ISR}\nomenclature{ISR}{Interrupt Service Routine}), qui est +ex\'ecut\'ee \`a chaque fois que le mat\'eriel signale un tel +\'ev\`enement. Si l'interruption a \'et\'e envoy\'ee par le bon +p\'eriph\'erique (plusieurs p\'eriph\'eriques peuvent partager une +m\^eme interruption mat\'erielle), la raison de l'interruption doit +\^etre d\'etermin\'ee en lisant le registre d'interruption du +p\'eriph\'erique. Par exemple, si le drapeau pour les trames +re\c{c}ues est activ\'e, les donn\'ees des trames doivent \^etre +copi\'ees depuis le mat\'eriel vers la m\'emoire du noyau puis +transmise \`a la pile r\'eseau. + +\paragraph{La structure \lstinline+net_device+}\index{net\_device} Le +pilote enregistre une structure \lstinline+net_device+ pour chaque +p\'eriph\'erique pour communiquer avec la pile r\'eseau et cr\'e\'e +une ``interface r\'eseau''. Dans le cas d'un pilote Ethernet, cette +interface appara\^it sous la forme \textit{ethX}, o\`u X est le +num\'ero assign\'e par le noyau \`a l'enregistrement. La structure +\lstinline+net_device+ re\c{c}oit les \'ev\`enements (soit depuis +l'espace utilisateur, soit depuis la pile r\'eseau) via diff\'erentes +fonctions de rappel, qui doivent \^etre d\'efinies avant +l'enregistrement. Toutes les fonctions de rappel ne sont pas +obligatoires, mais pour un fonctionnement raisonnable, celles qui sont +d\'efinies ci-dessous sont n\'ecessaires dans tous les cas: + +\newsavebox\boxopen +\sbox\boxopen{\lstinline+open()+} +\newsavebox\boxstop +\sbox\boxstop{\lstinline+stop()+} +\newsavebox\boxxmit +\sbox\boxxmit{\lstinline+hard_start_xmit()+} +\newsavebox\boxstats +\sbox\boxstats{\lstinline+get_stats()+} + +\begin{description} + +\item[\usebox\boxopen] Cette fonction est appel\'ee quand la + communication a d\'emar\'e, par exemple apr\`es une commande + \lstinline+ip link set ethX up+ depuis l'espace utilisateur. La + r\'eception des trames doit \^etre activ\'ee par le pilote. + +\item[\usebox\boxstop] Le but de cette fonction de rappel est de + ``fermer'' le p\'eriph\'erique, c'est-\`a-dire faire en sorte que le + mat\'eriel cesse de recevoir des trames. + +\item[\usebox\boxxmit] Cette fonction est appel\'ee pour chaque trame + qui a \'et\'e transmise. La pile r\'eseau passe la trame sous la + forme d'un pointeur vers une structure \lstinline+sk_buff+ (``socket + buffer''\index{Socket buffer} -- tampon de socket -- voir ci-dessous), + qui doit \^etre lib\'er\'ee apr\`es l'envoi. + +\item[\usebox\boxstats] Cet appel doit retourner un pointeur vers la + structure \lstinline+net_device_stats+, qui doit \^etre + continuellement mise \`a jour avec les statistiques des trames. Cela + signifie qu'\`a chaque fois qu'une trame est re\c{c}ue, envoy\'ee ou + qu'une erreur se produit, le compteur appropri\'e de cette structure + doit \^etre augment\'e. + +\end{description} + +L'inscription r\'eelle est faite par l'appel \lstinline+register_netdev()+, +la d\'esinscription est faite par \lstinline+unregister_netdev()+. + +\paragraph{L'interface \lstinline+netif+}\index{netif} Toute autre +communication dans la direction interface $\to$ r\'eseau est faite via +les appels \lstinline+netif_*()+. Par exemple, apr\`es l'ouverture +r\'eussie du p\'eriph\'erique, la pile r\'eseau doit \^etre +notifi\'ee, pour qu'elle puisse maintenant passer les trames \`a +l'interface. Ceci est fait en appelant +\lstinline+netif_start_queue()+. Apr\`es cet appel, la fonction de +rappel \lstinline+hard_start_xmit()+ peut \^etre rappel\'ee par la +pile r\'eseau. De plus, un pilote r\'eseau g\`ere habituellement une +file d'attente pour la transmission des trames. Quand elle est pleine, +il faut informer la pile r\'eseau qu'elle doit cesser de pousser +davantage de trames pendant un moment. Ceci se produit avec un appel +\`a \lstinline+netif_stop_queue()+. Si des trames ont \'et\'e +envoy\'ees, et qu'il y a \`a nouveau suffisamment de place pour les +mettre en file d'attente, ceci peut \^etre notifi\'e avec +\lstinline+netif_wake_queue()+. Un autre appel important est +\lstinline+netif_receive_skb()+\footnote{Cette fonction fait partie de +NAPI (``New API''), qui remplace la technique du noyau 2.4 pour +interfacer la pile r\'eseau (avec \lstinline+netif_rx()+). NAPI est +une technique pour am\'eliorer la performance r\'eseau de +Linux. Davantage d'information dans +\url{http://www.cyberus.ca/~hadi/usenix-paper.tgz}.}: il passe une +trame qui vient juste d'\^etre re\c{c}ue par le p\'eriph\'erique, \`a +la pile r\'eseau. Les donn\'ees de la trame doivent \^etre incluses +\`a cet effet dans le ``tampon de socket'' (voir ci-dessous). + +\paragraph{Tampons de Socket}\index{Socket buffer} Les tampons de sockets +sont le type de donn\'ees fondamental de toute la pile r\'eseau. Ils +servent de container pour les donn\'ees r\'eseaux et sont capables +d'ajouter rapidement des donn\'ees au d\'ebut et \`a la fin, ou bien +de les retirer. C'est pourquoi, un tampon de socket consiste en un +tampon allou\'e et plusieurs pointeurs qui marquent le d\'ebut du +tampon (\lstinline+head+), le d\'ebut des donn\'ees data +(\lstinline+data+), la fin des donn\'ees (\lstinline+tail+) et la fin +du tampon (\lstinline+end+). De plus, un tampon de socket contient les +informations d'ent\^ete pour le r\'eseau et (en cas de donn\'ees +re\c{c}ue), un pointeur vers le \lstinline+net_device+, qui l'a +r\'eceptionn\'e. Il existe des fonctions qui cr\'eent un tampon +socket (\lstinline+dev_alloc_skb()+), ajoutent des donn\'ees au +d\'ebut (\lstinline+skb_push()+) ou \`a la fin +(\lstinline+skb_put()+), suppriment des donn\'ees au d\'ebut +(\lstinline+skb_pull()+) ou \`a la fin (\lstinline+skb_trim()+), ou +suppriment le tampon (\lstinline+kfree_skb()+). Un tampon socket est +pass\'e de couche en couche et il est lib\'er\'e par la couche qui +s'en sert en dernier. En cas d'envoi, la lib\'eration est faite par le +pilote r\'eseau. + +%------------------------------------------------------------------------------ + +\section{Les pilotes natifs pour p\'eriph\'eriques EtherCAT} +\label{sec:native-drivers} + +Il y a quelques conditions qui s'appliquent au mat\'eriel Ethernet +lorsqu'il est utilis\'e avec un pilote Ethernet natif avec les +fonctionnalit\'es EtherCAT. + +\paragraph{Mat\'eriel d\'edi\'e} Pour des raisons de performances et +de temps r\'eel, le ma\^itre EtherCAT a besoin d'un acc\`es direct et +exclusif au mat\'eriel Ethernet. Cela implique que le p\'eriph\'erique +r\'eseau ne doit pas \^etre connect\'e \`a la pile r\'eseau du noyau +comme d'habitude, car le noyau essaierait de l'utiliser comme un +p\'eriph\'erique Ethernet ordinaire. + +\paragraph{Op\'eration sans interruption}\index{Interrupt} +Les trames EtherCAT voyagent au travers de l'anneau logique EtherCAT +et sont alors renvoy\'ees au ma\^itre. La communication est hautement +d\'eterministe: une trame est envoy\'ee et sera re\c{c}ue apr\`es un +temps constant, aussi il n'y pas besoin de notifier le pilote de la +r\'eception de la trame. \`A la place, le ma\^itre peut interroger le +mat\'eriel pour les trames re\c{c}ues, s'il s'attend \`a ce qu'elles +soient d\'ej\`a arriv\'ees. + + +La \autoref{fig:interrupt} montre deux flots de travail pour la +transmission et r\'eception cyclique de trames avec et sans +interruptions. + +\begin{figure}[htbp] + \centering + \includegraphics[width=.9\textwidth]{images/interrupt} + \caption{Op\'eration avec interruption versus Op\'eration sans interruption} + \label{fig:interrupt} +\end{figure} + +Dans le flux de travail de gauche, ``Op\'eration avec interruption'', +les donn\'ees venant du dernier cycle sont d'abord trait\'ees et une +nouvelle trame est assembl\'ee avec des nouveaux datagrammes, puis +elle est envoy\'ee. Le travail cyclique est fait pout l'instant. +Plus tard, quand la trame est \`a nouveau re\c{c}ue par le mat\'eriel, +une interruption est d\'eclench\'ee et l'ISR est ex\'ecut\'ee. L'ISR +va r\'ecup\'erer les donn\'ees de la trame depuis le mat\'eriel et +commencer la dissection de la trame: les datagrammes seront trait\'es, +et alors les donn\'ees seront pr\^etes pour le traitement dans le +prochain cycle. + +Dans le flux de travail de droite, ``Op\'eration sans interruption'', +aucune interruption mat\'erielle n'est activ\'ee. \`A la place, le +ma\^itre va sonder le mat\'eriel en ex\'ecutant l'ISR. Si la trame a +\'et\'e re\c{c}ue entre temps, elle sera diss\'equ\'ee. La situation est +maintenant la m\^eme qu'au d\'ebut de flux de travail de gauche : les +donn\'ees re\c{c}ues sont trait\'ees et une nouvelle trame est +assembl\'ee et envoy\'ee. Il n'y a rien d'autre \`a faire pour le +reste du cycle. + +L'op\'eration sans interruption est pr\'ef\'erable, parce que les +interruptions mat\'erielles ne sont pas propices \`a l'am\'elioration +du comportement temps r\'eel du pilote: leurs incidences +ind\'eterministes contribuent \`a augmenter la gigue. En outre, si une +extension temps r\'eel (comme RTAI) est utilis\'ee, un effort +suppl\'ementaire devra \^etre fait pour hi\'erarchiser les +interruptions. + +\paragraph{P\'eriph\'eriques Ethernet et EtherCAT} +Un autre probl\`eme r\'eside dans la fa\c{c}on dont Linux g\`ere les +p\'eriph\'eriques du m\^eme type. Par exemple, un pilote +PCI\nomenclature{PCI}{Peripheral Component Interconnect, Bus + informatique} analyse le bus PCI pour chercher des p\'eriph\'eriques +qu'il peut g\'erer. Alors, il s'enregistre lui-m\^eme comme pilote +responsable pour tous les p\'eriph\'eriques trouv\'es. Le probl\`eme +est que l'on ne peut pas dire \`a un pilote non modifi\'e d'ignorer un +p\'eriph\'erique pour l'utiliser ult\'erieurement pour EtherCAT. Il +faut donc un moyen de g\'erer plusieurs p\'eriph\'eriques du m\^eme +type, l'un \'etant r\'eserv\'e \`a EtherCAT, tandis que l'autre est +trait\'e comme un p\'eriph\'erique Ethernet ordinaire. + +Pour toutes ces raisons, l'auteur a d\'ecid\'e que la seule solution +acceptable \'etait de modifier les pilotes Ethernet standards de +mani\`ere \`a ce qu'ils conservent leurs fonctionnalit\'es normales, +tout en gagnant la possibilit\'e de traiter un ou plusieurs +p\'eriph\'eriques comme \'etant compatibles EtherCAT. + +Les avantages de cette solution sont list\'es ci-dessous: + +\begin{itemize} +\item Pas besoin de dire aux pilotes standards d'ignorer certains + p\'eriph\'eriques. +\item Un seul pilote r\'eseau pour les p\'eriph\'eriques EtherCAT et + non-EtherCAT. +\item Pas besoin d'impl\'ementer un pilote r\'eseau depuis z\'ero et + de rencontrer des probl\`emes que les anciens d\'eveloppeurs ont + d\'ej\`a r\'esolus. +\end{itemize} + +L'approche choisie a les inconv\'enients suivants: + +\begin{itemize} +\item Le pilote modifi\'e est plus compliqu\'e car il doit g\'erer les + p\'eriph\'eriques EtherCAT et non-EtherCAT. +\item De nombreuses diff\'erenciations de cas suppl\'ementaires dans le + code du pilote. +\item Les modifications et changements dans les pilotes standards + doivent \^etre port\'es de temps en temps vers les versions compatibles + EtherCAT. +\end{itemize} + +%------------------------------------------------------------------------------ + +\section{Le pilote de p\'eriph\'erique EtherCAT g\'en\'erique} +\label{sec:generic-driver} + +Puisqu'il existe des approches pour activer un fonctionnement en temps +r\'eel \cite{rt-preempt} du noyau Linux complet, il est possible +d'op\'erer sans impl\'ementation native des pilotes de +p\'eriph\'eriques Ethernet compatibles EtherCAT et d'utiliser la pile +r\'eseau \`a la place. La \autoref{fig:arch} pr\'esente le ``Module de +pilote Ethernet g\'en\'erique'', qui se connecte \`a des +p\'eriph\'eriques Ethernet locaux via la pile r\'eseau. Le module +noyau se nomme \lstinline+ec_generic+ et il peut \^etre charg\'e +apr\`es le module ma\^itre comme un pilote Ethernet compatible +EtherCAT. + +Le pilote de p\'eriph\'erique g\'en\'erique analyse la pile r\'eseau +\`a la recherche d'interfaces enregistr\'ees par les pilotes de +p\'eriph\'eriques Ethernet. Il offre tous les p\'eriph\'eriques +possibles au ma\^itre EtherCAT. Si le ma\^itre accepte un +p\'eriph\'erique, le pilote g\'en\'erique cr\'ee un socket de paquet +(voir \lstinline+man 7 packet+) avec \lstinline+socket_type+ mis \`a +\lstinline+SOCK_RAW+, li\'e \`a ce p\'eriph\'erique. Toutes les +fonctions de l'interface de ce p\'eriph\'erique (voir +\autoref{sec:ecdev}) op\'ereront alors sur ce socket. + +Les avantages de cette solution sont list\'es ci-dessous: + +\begin{itemize} +\item Tout mat\'eriel, qui est g\'er\'e par un pilote Ethernet + Linux, peut \^etre utilis\'e pour EtherCAT. +\item Aucune modification n'est n\'ec\'essaire sur les pilotes Ethernet + r\'eels. +\end{itemize} + +L'approche g\'en\'erique a les inconv\'enients suivants: + +\begin{itemize} +\item La performance est un peut moins bonne qu'avec l'approche + native, parce que les donn\'ees de la trame doivent traverser les + couches basses de la pile r\'eseau. +\item Il n'est pas possible d'utiliser des extensions en temps r\'eel + dans le noyau comme RTAI avec le pilote g\'en\'erique, car le code + de la pile r\'eseau utilise des allocations dynamiques de m\'emoire + et d'autres choses, qui pourraient provoquer le gel du syst\`eme + dans un contexte temps r\'eel. +\end{itemize} + +\paragraph{Activation du p\'eriph\'erique} Dans le but d'envoyer +et recevoir des trames au travers d'un socket, le p\'eriph\'erique +Ethernet li\'e \`a ce socket doit \^etre activ\'e, autrement toutes +les trames seront rejet\'ees. L'activation doit avoir lieu avant le +chargement du module ma\^itre et peut avoir lieu de diff\'erentes +mani\`eres: + +\begin{itemize} + +\item Ad-hoc, en utilisant la commande + \lstinline+ip link set dev ethX up+ + (ou la commande plus ancienne \lstinline+ifconfig ethX up+), + +\item Configur\'ee, en fonction de la distribution, par exemple en + utilisant les fichiers \lstinline+ifcfg+ + (\lstinline+/etc/sysconfig/network/ifcfg-ethX+) dans openSUSE et + d'autres. C'est le meilleur choix si le ma\^itre EtherCAT doit + d\'emarrer avec le syst\`eme. Puisque le p\'eriph\'erique Ethernet doit + seulement \^etre activ\'e, mais qu'aucune adresse IP etc.\ ne sera + assign\'ee, il est suffisant d'utiliser \lstinline+STARTMODE=auto+ + comme configuration. + +\end{itemize} + +%------------------------------------------------------------------------------ + +\section{Fourniture de p\'eriph\'eriques Ethernet} +\label{sec:providing-devices} + +Apr\`es le chargement du module ma\^itre, des modules additionnels +doivent \^etre charg\'es pour offrir des p\'eriph\'eriques au(x) +ma\^itre(s) (voir \autoref{sec:ecdev}). Le module ma\^itre conna\^it +les p\'eriph\'eriques \`a choisir gr\^ace aux param\`etres de module +(voir \autoref{sec:mastermod}). Si le script d'initialisation est +utilis\'e pour d\'emarrer le ma\^itre, les pilotes et +p\'eriph\'eriques \`a utiliser peuvent \^etre sp\'ecifi\'es dans le +fichier sysconfig (voir \autoref{sec:sysconfig}). + +Les modules offrant des p\'eriph\'eriques Ethernet peuvent \^etre + +\begin{itemize} +\item des modules natifs de pilotes r\'eseaux compatibles EtherCAT (voir + \autoref{sec:native-drivers}) ou +\item le module g\'en\'erique de p\'eriph\'erique EtherCAT (voir + \autoref{sec:generic-driver}). +\end{itemize} + +%------------------------------------------------------------------------------ + +\section{Redondance} +\label{sec:redundancy} +\index{Redondance} + +L'op\'eration redondante de bus signifie, qu'il y a plus qu'une +connexion Ethernet entre le ma\^itre et les esclaves. Les +datagrammes de l'\'echange de donn\'ees de processus sont envoy\'es +sur chaque lien ma\^itre, aussi l'\'echange se terminera, m\^eme si le +bus est d\'econnect\'e quelque part entre les deux. + +La condition pour une op\'eration redondante de bus est que chaque +esclave puisse \^etre atteint par au moins un lien ma\^itre. Dans ce +cas, une panne de connexion unique (i.\,e.~la rupture d'un c\^able) ne +conduira jamais \`a des donn\'ees de processus incompl\`etes. Les +doubles d\'efauts ne peuvent pas \^etre trait\'es avec deux +p\'eriph\'eriques Ethernet. + +La redondance peut \^etre configur\'ee avec le commutateur +\lstinline+--with-devices+ au moment de la configuration (voir +\autoref{sec:installation}) et en utilisant le param\`etre +\lstinline+backup_devices+ du module noyau \lstinline+ec_master+ (voir +\autoref{sec:mastermod}) ou la variable appropri\'ee +\lstinline+MASTERx_BACKUP+ dans le fichier de configuration sysconfig +(voir \autoref{sec:sysconfig}). + +L'analyse du bus est faite apr\`es un changement de topologie sur +n'importe quel lien Ethernet. L'API (voir \autoref{chap:api}) et +l'outil en ligne de commande (voir \autoref{sec:tool}) ont tous les +deux des m\'ethodes pour interroger le status de l'op\'eration redondante. + +%------------------------------------------------------------------------------ + +\section{Interface de p\'eriph\'erique EtherCAT} +\label{sec:ecdev} +\index{Device interface} + +Une anticipation de la section concernant le module ma\^itre +(\autoref{sec:mastermod}) est n\'ecessaire pour comprendre la +mani\`ere dont un module de pilote de p\'eriph\'erique r\'eseau peut +connecter un p\'eriph\'erique \`a un ma\^itre EtherCAT sp\'ecifique. + +Le module ma\^itre fournit une ``interface de p\'eriph\'erique'' pour +les pilotes de p\'eriph\'eriques r\'eseaux. Pour utiliser cette +interface, un module de pilote de p\'eriph\'erique r\'eseau doit +inclure l'ent\^ete +\textit{devices/ecdev.h}\nomenclature{ecdev}{EtherCAT Device}, +provenant du code du ma\^itre EtherCAT. Cet ent\^ete offre une +interface de fonction pour les p\'eriph\'eriques EtherCAT. Toutes les +fonctions de l'interface du p\'eriph\'erique sont nomm\'ees avec le +pr\'efixe \lstinline+ecdev+. + +La documentation de l'interface du p\'eriph\'erique peut \^etre +trouv\'ee dans le fichier d'ent\^ete ou dans le module appropri\'e de +la documentation de l'interface (voir \autoref{sec:gendoc} pour les +instruction pour la g\'en\'erer). + +% TODO general description of the device interface + +%------------------------------------------------------------------------------ + +\section{Application de correctifs aux pilotes de r\'eseau natifs} +\label{sec:patching} +\index{Network drivers} + +Cette section d\'ecrit, comment fabriquer un pilote Ethernet standard +compatible EtherCAT, en utilisant l'approche native (voir +\autoref{sec:native-drivers}). Malheureusement, il n'y a pas de +proc\'edure standard pour permettre l'utilisation d'un pilote Ethernet +par le ma\^itre EtherCAT, mais il existe quelques techniques +courantes. + +\begin{enumerate} + +\item Une premi\`ere r\`egle simple est d'\'eviter les appels + \lstinline+netif_*()+ pour tous les p\'eriph\'eriques EtherCAT. + Comme indiqu\'e pr\'ec\'edemment, les p\'eriph\'eriques EtherCAT ne + doivent avoir aucune connexion avec la pile r\'eseau, et c'est + pourquoi ils ne doivent pas appeler ces fonctions d'interface. + +\item Une autre chose importante est, que les p\'eriph\'eriques + EtherCAT doivent fonctionner sans interruption. Aussi tous les + appels pour inscrire les gestionnaires d'interruption et activer les + interruptions au niveau mat\'eriel doivent aussi \^etre \'evit\'es. + +\item Le ma\^itre n'utilise pas un nouveau tampon de socket pour + chaque op\'eration d'envoi: \`a la place, il y a un tampon fixe, + allou\'e pendant l'initialisation du ma\^itre. Ce tampon de socket + est rempli avec une trame EtherCAT par chaque op\'eration d'envoi et + transmis \`a la fonction de rappel + \lstinline+hard_start_xmit()+. C'est pourquoi, il est n\'ecessaire + que le tampon de socket ne soit pas lib\'er\'e comme d'habitude par + le pilote r\'eseau. + +\end{enumerate} + +Un pilote Ethernet g\`ere habituellement plusieurs p\'eriph\'eriques +Ethernet, chacun est d\'ecrit par une structure \lstinline+net_device+ +avec un champ \lstinline+priv_data+ pour attacher les donn\'ees qui +d\'ependent du pilote \`a la structure. Pour distinguer entre les +p\'eriph\'eriques Ethernet normaux et ceux qui sont utilis\'es par les +ma\^itres EtherCAT, la structure de donn\'ees priv\'ees utilis\'ee par +le pilote peut \^etre \'etendue avec un pointeur, qui pointe vers un +objet \lstinline+ec_device_t+ retourn\'e par +\lstinline+ecdev_offer()+ (voir \autoref{sec:ecdev}) si le +p\'eriph\'erique est utilis\'e par un ma\^itre ou sinon qui est \`a +z\'ero. + +Le pilote Ethernet RealTek RTL-8139 est un pilote Ethernet ``simple'' +qui peut servir d'exemple pour modifier des nouveaux pilotes. Les +sections int\'eressantes peuvent \^etre trouv\'ees en recherchant la +cha\^ine ``ecdev" dans le fichier +\textit{devices/8139too-2.6.24-ethercat.c}. + +%------------------------------------------------------------------------------ + +\chapter{Automates finis} +\label{sec:fsm} +\index{FSM} + +Beaucoup de parties du ma\^itre EtherCAT sont impl\'ement\'ees sous +forme d' \textit{automates finis} -- en anglais \textit{finite state + machines} (FSMs\nomenclature{FSM}{Finite State Machine}). Bien +qu'ils am\`enent une plus grande complexit\'e pour certains aspects, +ils ouvrent de nombreuses nouvelles possibilit\'es. + +Le court exemple de code ci-dessous montre comment lire tous les \'etats +d'esclave et illustre en outre les restrictions du codage `` +s\'equentiel '': + + +\begin{lstlisting}[gobble=2,language=C,numbers=left] + ec_datagram_brd(datagram, 0x0130, 2); // prepare datagram + if (ec_master_simple_io(master, datagram)) return -1; + slave_states = EC_READ_U8(datagram->data); // process datagram +\end{lstlisting} + +La fonction \textit{ec\_master\_simple\_io()} fournit une interface +simple pour envoyer de mani\`ere synchrone un datagramme unique et +recevoir le r\'esultat\footnote{ Comme tous les probl\`emes de + communication ont \'et\'e entre temps transmis aux automates finis, + la fonction est obsol\`ete et a cess\'e d'exister. N\'eanmoins, elle + est suffisante pour montrer ses propres restrictions. }. En +interne, elle met en file d'attente le datagramme sp\'ecifi\'e, +invoque la fonction \textit{ec\_master\_send\_datagrams()} pour +envoyer une trame avec le datagramme en attente, puis attend +activement la r\'eception. + +Cette approche s\'equentielle est tr\`es simple, se refl\'etant dans +seulement trois lignes de code. L'inconv\'enient est que le ma\^itre +est bloqu\'e pendant le temps o\`u il attend la r\'eception du +datagramme. Ce n'est pas vraiment un probl\`eme, s'il n'y a qu'une +seule instance qui utilise le ma\^itre, mais si plusieurs instances +veulent (de mani\`ere synchrone\footnote{ \`A ce stade, l'acc\`es + synchrone au ma\^itre sera suffisant pour montrer les avantages + d'un automate. L'approche asynchrone sera discut\'ee dans la + \autoref{sec:eoe}}) utiliser le ma\^itre, il est in\'evitable de +songer \`a une alternative au mod\`ele s\'equentiel. + +L'acc\`es ma\^itre doit \^etre s\'equentalis\'e pour que plusieurs +instances puissent envoyer et recevoir des datagrammes de mani\`ere +synchrone. Avec la pr\'esente approche, cela se traduirait par une +phase d'attente active pour chaque instance, ce qui serait +inacceptable, en particulier dans des circonstances en temps r\'eel, +en raison de l'\'enorme surcharge de temps. + +Une solution possible serait, que toutes les instances soient +ex\'ecut\'ees s\'equentiellement pour mettre en file d'attente leurs +datagrammes, et qu'elles passent alors le contr\^ole \`a la prochaine +instance au lieu d'attendre la r\'eception du datagramme. Finalement, +une instance sup\'erieure ferait l'entr\'ee-sortie sur le bus pour +envoyer et recevoir tous les datagrammes en attente. La prochaine +\'etape serait d'ex\'ecuter \`a nouveau toutes les instances pour +qu'elles traitent leurs datagrammes re\c{c}us et en \'emettent des +nouveaux. + +Cette approche aboutit \`a ce que toutes les instances m\'emorisent +leurs \'etats lorsqu'elles redonnent le contr\^ole \`a l'instance +sup\'erieure. Il est \'evident dans ce cas d'utiliser le mod\`ele +d'\textit{automate}. La \autoref{sec:fsmtheory} introduira une partie +de la th\'eorie utilis\'ee, tandis que l'extrait ci-dessous montre +l'approche de base en codant l'exemple ci-dessus sous forme +d'automate: + +\begin{lstlisting}[gobble=2,language=C,numbers=left] + // state 1 + ec_datagram_brd(datagram, 0x0130, 2); // prepare datagram + ec_master_queue(master, datagram); // queue datagram + next_state = state_2; + // state processing finished +\end{lstlisting} + +Apr\`es que toutes les instances ont ex\'ecut\'e leur \'etat courant et mis en +file d'attente leurs datagrammes, ceci sont envoy\'es et re\c{c}us. Alors +les \'etats suivants respectifs sont ex\'ecut\'es: + +\begin{lstlisting}[gobble=2,language=C,numbers=left] + // state 2 + if (datagram->state != EC_DGRAM_STATE_RECEIVED) { + next_state = state_error; + return; // state processing finished + } + slave_states = EC_READ_U8(datagram->data); // process datagram + // state processing finished. +\end{lstlisting} + +Voir \autoref{sec:statemodel} pour une introduction au concept de +programmation d'automate fini utilis\'e dans le code du ma\^itre. + +%------------------------------------------------------------------------------ + +\section{Th\'eorie des automates finis} +\label{sec:fsmtheory} +\index{FSM!Theory} + +Un automate fini \cite{automata} est un mod\`ele de comportement avec +des entr\'ees et des sorties, o\`u les sorties d\'ependent non-seulement des +entr\'ees, mais aussi de l'historique des entr\'ees. La d\'efinition +math\'ematique d'un automate fini (ou automate avec un nombre fini +d'\'etats) est un six-tuple $(\Sigma, \Gamma, S, s_0, \delta, \omega)$, +avec + +\begin{itemize} +\item l'alphabet d'entr\'ee $\Sigma$, avec $\Sigma \neq + \emptyset$, contenant tous les symboles d'entr\'ees, +\item l'alphabet de sortie $\Gamma$, avec $\Gamma \neq + \emptyset$, contenant tous les symboles de sorties, +\item l'ensemble des \'etats $S$, avec $S \neq \emptyset$, +\item l'ensemble des \'etats initiauxs $s_0$ avec + $s_0 \subseteq S, s_0 \neq \emptyset$ +\item la fonction de transition + $\delta: S \times \Sigma \rightarrow S \times \Gamma$ +\item la fonction de sortie $\omega$. +\end{itemize} + +La fonction de transition d'\'etat $\delta$ est souvent sp\'ecifi\'ee +sous la forme d'une \textit{table de transition d'\'etat}, ou par un +\textit{diagramme de transition d'\'etat}. La table de transition +offre une vue matricielle du comportement de l'automate fini (voir +\autoref{tab:statetrans}). Les lignes de la matrice correspondent aux +\'etats ($S = \{s_0, s_1, s_2\}$) et les colonnes correspondent aux +symboles d'entr\'ee ($\Gamma = \{a, b, \varepsilon\}$). Le contenu de +la table \`a la ligne $i$ et \`a la colonne $j$ repr\'esente alors le +prochain \'etat (et \'eventuellement la sortie) pour le cas o\`u le +symbole $\sigma_j$ est lu dans l'\'etat $s_i$. + +\begin{table}[htbp] + \caption{Une table typique de transition d'\'etat} + \label{tab:statetrans} + \vspace{2mm} + \centering + \begin{tabular}{l|ccc} + & $a$ & $b$ & $\varepsilon$\\ \hline + $s_0$ & $s_1$ & $s_1$ & $s_2$\\ + $s_1$ & $s_2$ & $s_1$ & $s_0$\\ + $s_2$ & $s_0$ & $s_0$ & $s_0$\\ \hline + \end{tabular} +\end{table} + +Le diagramme d'\'etat pour le m\^eme exemple est semblable \`a +\autoref{fig:statetrans}. Les \'etats sont repr\'esent\'es par des +cercles ou des ellipses et les transitions sont repr\'esent\'ees par +des fl\`eches entre eux. La condition \`a remplir pour autoriser la +transition se trouve \`a proximit\'e de la fl\`eche de transition. +L'\'etat initial est marqu\'e par un disque noir avec une fl\`eche +pointant vers l'\'etat respectif. + +\begin{figure}[htbp] + \centering + \includegraphics[width=.5\textwidth]{images/statetrans} + \caption{Un diagramme typique de transition d'\'etat} + \label{fig:statetrans} +\end{figure} + +\paragraph{Automate fini d\'eterministe et non-d\'eterministe} + +Un automate fini peut \^etre d\'eterministe, ce qui signifit que pour +un \'etat et une entr\'ee, il y a un (et seulement un) \'etat +suivant. Dans ce cas, l'automate fini a exactement un \'etat de +d\'epart. Les automates finis non-d\'eterministes peuvent avoir +plusieurs transitions pour une paire unique \'etat-entr\'ee. +Il existe un ensemble d'\'etats de d\'epart dans ce dernier cas. + + + +\paragraph{Automates de Moore et de Mealy} + +Il y a une distinction entre ce qu'on appelle les \textit{automates de + Moore}, et les \textit{automates de Mealy}. Math\'ematiquement +parlant, la distinction se situe dans la fonction de sortie $\omega$: +si elle ne d\'epend que de l'\'etat courant ($\omega: S \rightarrow +\Gamma$), l'automate correspond au ``mod\`ele de Moore''. Sinon, si +$\omega$ est une fonction de l'\'etat et de l'alphabet d'entr\'ee +($\omega: S \times \Sigma \rightarrow \Gamma$) l'automate correspond +au ``mod\`ele de Mealy''. Les automates de Mealy sont plus +pratiques dans la plupart des cas, car leur conception permet d'obtenir +des automates avec un nombre minimal d'\'etats. En pratique, un m\'elange +des deux mod\`eles est souvent employ\'e. + +\paragraph{Malentendu sur les automates finis} + +Il y a un ph\'enom\`ene appel\'e ``explosion d'\'etats'', qui est souvent +utilis\'e comme argument d\'efavorable contre l'usage g\'en\'eral des +automates finis dans les environnements complexes. Il faut mentionner +que ce point est trompeur~\cite{fsmmis}. Les explosions d'\'etats sont +souvent le r\'esultat d'une mauvaise conception de l'automate: les +erreurs courantes sont de stocker la valeur pr\'esente de toutes les +entr\'ees dans un \'etat, ou de ne pas diviser un automate complexe +en sous-automates plus simples. Le ma\^itre EtherCAT utilise plusieurs +automates, qui sont ex\'ecut\'es de mani\`ere hi\'erarchique et qui +servent de sous-automates. Ils sont aussi d\'ecrits ci-dessous. + + +%------------------------------------------------------------------------------ + +\section{Le mod\`ele d'\'etat du ma\^itre} +\label{sec:statemodel} + +Cette section pr\'esente les techniques utilis\'ees dans le ma\^itre +pour impl\'ementer les automates. + +\paragraph{Programmation des automates} + +Il y a plusieurs mani\`ere d'impl\'ementer un automate avec du code +\textit{C}. La mani\`ere \'evidente est d'impl\'ementer les +diff\'erents \'etats et actions avec un branchement \`a choix multiple +(switch): + +\begin{lstlisting}[gobble=2,language=C,numbers=left] + enum {STATE_1, STATE_2, STATE_3}; + int state = STATE_1; + + void state_machine_run(void *priv_data) { + switch (state) { + case STATE_1: + action_1(); + state = STATE_2; + break; + case STATE_2: + action_2() + if (some_condition) state = STATE_1; + else state = STATE_3; + break; + case STATE_3: + action_3(); + state = STATE_1; + break; + } + } +\end{lstlisting} + +Cette technique reste possible pour les petits automates, mais +pr\'esente l'inconv\'enient de complexifier rapidement le code lorsque +le nombre d'\'etats augmente. De plus le branchement \`a choix +multiple doit \^etre ex\'ecut\'e \`a chaque it\'eration et beaucoup +d'indentations sont gaspill\'es. + +La m\'ethode retenue par le ma\^itre est d'impl\'ementer chaque \'etat +dans sa propre fonction et de stocker la fonction d'\'etat courante +dans un pointeur de fonction: + +\begin{lstlisting}[gobble=2,language=C,numbers=left] + void (*state)(void *) = state1; + + void state_machine_run(void *priv_data) { + state(priv_data); + } + + void state1(void *priv_data) { + action_1(); + state = state2; + } + + void state2(void *priv_data) { + action_2(); + if (some_condition) state = state1; + else state = state2; + } + + void state3(void *priv_data) { + action_3(); + state = state1; + } +\end{lstlisting} + +Dans le code du ma\^itre, les pointeurs d'\'etat de tous les +automates\footnote{Tous sauf l'automate EoE, parce plusieurs esclaves + Eoe doivent \^etre g\'er\'es en parall\`ele. Pour cette raison, + chaque objet gestionnaire EoE a son propre pointeur d'\'etat.} sont +rassembl\'es dans un objet unique de la classe +\lstinline+ec_fsm_master_t+. C'est avantageux, car il y a toujours +une instance disponible de chaque automate qui peut \^etre d\'emarr\'ee +\`a la demande. + +\paragraph{Mealy et Moore} + +Une vue rapproch\'ee du code ci-dessus montre que les actions ex\'ecut\'ees +(les ``sorties'' de l'automate) d\'ependent uniquement de l'\'etat +courant. Ceci correspond au mod\`ele de ``Moore'' introduit dans +\autoref{sec:fsmtheory}. Comme d\'ej\`a mentionn\'e, le mod\`ele de ``Mealy'' +offre une flexibilit\'e sup\'erieure, visible dans le code +ci-dessous: + +\begin{lstlisting}[gobble=2,language=C,numbers=left] + void state7(void *priv_data) { + if (some_condition) { + action_7a(); + state = state1; + } + else { + action_7b(); + state = state8; + } + } +\end{lstlisting} + +\begin{description} + +\item[\linenum{3} + \linenum{7}] la fonction d'\'etat ex\'ecute les + actions en fonction de la transition d'\'etat, qui est sur le point + d'\^etre effectu\'ee. + +\end{description} + +L'alternative la plus flexible est d'ex\'ecuter certaines actions en +fonction de l'\'etat, puis d'autres actions en fonction de la +transition d'\'etat: + +\begin{lstlisting}[gobble=2,language=C,numbers=left] + void state9(void *priv_data) { + action_9(); + if (some_condition) { + action_9a(); + state = state7; + } + else { + action_9b(); + state = state10; + } + } +\end{lstlisting} + +Ce mod\`ele est souvent utilis\'e dans le ma\^itre. Il combine les +meilleurs aspects des deux approches. + +\paragraph{Utilisation de sous-automates} + +Pour \'eviter d'avoir trop d'\'etats, certaines fonctions de l'automate du +ma\^itre EtherCAT ont \'et\'e extraites vers des sous-automates. Ceci +am\'eliore l'encapsulation des flux de travail concern\'es et surtout +\'evite le ph\'enom\`ene d'``explosion d'\'etats'' d\'ecrit dans +\autoref{sec:fsmtheory}. Si le ma\^itre utilisait \`a la place un seul +gros automate, le nombre d'\'etat serait d\'emultipli\'e. Ce qui +augmenterait le niveau de complexit\'e jusqu'\`a un niveau ing\'erable. + +\paragraph{Ex\'ecution de sous-automates} + +Si un automate d\'emarre l'ex\'ecution d'un sous-automate, il reste +habituellement dans un \'etat jusqu'\`a ce que le sous-automate +termine son ex\'ecution. Ceci est g\'en\'erallement fait comme dans +l'extrait de code ci-dessous, qui provient du code de l'automate de +configuration des esclaves: + +\begin{lstlisting}[gobble=2,language=C,numbers=left] + void ec_fsm_slaveconf_safeop(ec_fsm_t *fsm) + { + fsm->change_state(fsm); // execute state change + // sub state machine + + if (fsm->change_state == ec_fsm_error) { + fsm->slave_state = ec_fsm_end; + return; + } + + if (fsm->change_state != ec_fsm_end) return; + + // continue state processing + ... +\end{lstlisting} + +\begin{description} + +\item[\linenum{3}] \lstinline+change_state+ est le pointeur d'\'etat + de l'automate. La fonction d'\'etat, sur laquelle pointe le + pointeur, est ex\'ecut\'ee \ldots + +\item[\linenum{6}] \ldots jusqu'\`a ce que l'automate termine par + l'\'etat d'erreur \ldots + +\item[\linenum{11}] \ldots ou jusqu'\`a ce que l'automate termine dans + l'\'etat de fin. Pendant ce temps, l'automate ``sup\'erieur'' reste + dans l'\'etat courant et ex\'ecute \`a nouveau le sous-automate dans + le prochain cycle. + +\end{description} + +\paragraph{Description des automates} + +Les sections ci-dessous d\'ecrivent chaque automate utilis\'e par le +ma\^itre EtherCAT. Les descriptions textuelles des automates contiennent +des r\'ef\'erences aux transitions dans les diagrammes de transitions +d'\'etats correspondants, qui sont marqu\'es avec une fl\`eche suivie par le +nom de l'\'etat successeur. Les transitions provoqu\'ees par des cas +d'erreurs triviales (c'est-\`a-dire, pas de r\'eponse de l'esclave) ne +sont pas d\'ecrites explicitement. Ces transitions sont d\'ecrites sous +forme de fl\`eches en tirets dans les diagrammes. +%------------------------------------------------------------------------------ + +\section{L'automate du ma\^itre} +\label{sec:fsm-master} +\index{FSM!Master} + +L'automate du ma\^itre s'ex\'ecute dans le contexte du fil d'ex\'ecution +(thread) du ma\^itre. La \autoref{fig:fsm-master} montre son diagramme de +transition. Ses buts sont: + +\begin{figure}[htbp] + \centering + \includegraphics[width=\textwidth]{graphs/fsm_master} + \caption{Diagramme de transition de l'automate du ma\^itre} + \label{fig:fsm-master} +\end{figure} + +\begin{description} + +\item[Surveillance du bus] La topologie du bus est surveill\'ee. Si elle + change, le bus est \`a nouveau analys\'e. + +\item[Configuration des esclaves] Les \'etats de la couche application + des esclaves sont surveill\'es. Si un esclave n'est pas dans l'\'etat + suppos\'e, alors l'esclave est (re)configur\'e. + +\item[Gestion des requ\^etes] Les requ\^etes (qui proviennent soit de + l'application ou bien de sources externes) sont g\'er\'ees. Une requ\^ete + est un travail que le ma\^itre traitera de mani\`ere asynchrone, par + exemple un acc\`es SII, un acc\`es SDO ou similaire. + +\end{description} + +%------------------------------------------------------------------------------ + +\section{L'automate d'analyse des esclaves} +\label{sec:fsm-scan} +\index{FSM!Slave Scan} + +L'automate d'analyse des esclaves, qui est repr\'esent\'e dans +\autoref{fig:fsm-slavescan}, conduit le processus de lecture des +informations des esclaves. + +\begin{figure}[htbp] + \centering + \includegraphics[height=.8\textheight]{graphs/fsm_slave_scan} + \caption{Diagramme de transition de l'automate d'analyse des esclaves} + \label{fig:fsm-slavescan} +\end{figure} + +Le processus d'analyse comprend les \'etapes suivantes: + +\begin{description} + +\item[Node Address] L'adresse du n\oe{}ud est d\'efinie pour l'esclave, + de sorte qu'il puisse \^etre adress\'e par n\oe{}ud pour toutes les + op\'erations suivantes. + +\item[AL State] L'\'etat initial de la couche application + (Application Layer) est lu. + +\item[Base Information] L'information de base (tel que le nombre de + FMMUs support\'ees) est lue depuis la m\'emoire physique la plus basse. + +\item[Data Link] L'information sur les ports physiques est lue. + +\item[SII Size] La taille des contenus SII est d\'etermin\'ee pour allouer + l'image m\'emoire SII. + +\item[SII Data] Les contenus SII sont lus dans l'image du ma\^itre. + +\item[PREOP] Si l'esclave supporte CoE, son \'etat est d\'efini \`a PREOP en + utilisant l'automate de changement d'\'etat (voir + \autoref{sec:fsm-change}) pour autoriser la communication par bo\^ite + aux lettres et lire la configuration PDO via CoE. + +\item[PDOs] Les PDOs sont lus via CoE (si support\'e) en utilisant + l'automate de lecture des PDO (voir \autoref{sec:fsm-pdo}). Si cela + r\'eussit, les informations PDO du SII sont (le cas \'ech\'eant) \'ecras\'ees. + +\end{description} + +%------------------------------------------------------------------------------ + +\section{L'automate de configuration de l'\'etat de l'esclave} +\label{sec:fsm-conf} +\index{FSM!Slave Configuration} + +L'automate de configuration de l'\'etat de l'esclave, qui est +repr\'esent\'e dans \autoref{fig:fsm-slaveconf}, configure un esclave +et l'am\`ene dans un \'etat particulier de la couche application. + +\begin{figure}[htbp] + \centering + \includegraphics[height=\textheight]{graphs/fsm_slave_conf} + \caption{Diagramme de transition de l'automate de configuration de + l'\'etat de l'esclave} + \label{fig:fsm-slaveconf} +\end{figure} + +\begin{description} + +\item[INIT] L'automate de changement d'\'etat est utilis\'e pour + amener l'esclave \`a l'\'etat INIT. + +\item[FMMU Clearing] Pour \'eviter que l'esclave r\'eagisse \`a + n'importe quelle donn\'ee de processus, la configuration FMMU est + effac\'ee. Si l'esclave ne supporte pas les FMMUs, cet \'etat est + saut\'e. Si INIT est l'\'etat demand\'e, l'automate est termin\'e. + +\item[Mailbox Sync Manager Configuration] Si l'esclave supporte la + communication par bo\^ite aux lettres, les gestionnaires de + synchronisation des bo\^ites aux lettres sont configur\'es. Sinon + cet \'etat est saut\'e. + +\item[PREOP] L'automate de changement d'\'etat est utilis\'e pour amener + l'esclave \`a l'\'etat PREOP. Si PREOP est l'\'etat demand\'e, l'automate + est termin\'e. + +\item[SDO Configuration] Si une configuration d'esclave est attach\'ee + (voir \autoref{sec:masterconfig}), et que l'application fournit des + configurations SDO, elles sont envoy\'ees \`a l'esclave. + + +\item[PDO Configuration] L'automate de configuration PDO est ex\'ecut\'e + pour appliquer toutes les configurations PDO n\'ecessaires. + +\item[PDO Sync Manager Configuration] S'il y a des gestionnaires + de synchronisation PDO, ils sont configur\'es. + +\item[FMMU Configuration] Si l'application fournit des configurations + FMMU (i.\,e.\ si l'application a inscrit des entr\'ees PDO), elles + sont appliqu\'ees. + +\item[SAFEOP] L'automate de changement d'\'etat est utilis\'e pour + amener l'esclave \`a l'\'etat SAFEOP. Si SAFEOP est l'\'etat + demand\'e, l'automate est termin\'e. + +\item[OP] L'automate de changement d'\'etat est utilis\'e pour + amener l'esclave \`a l'\'etat OP. Si OP est l'\'etat demand\'e, + l'automate est termin\'e. + +\end{description} + +%------------------------------------------------------------------------------ + +\section{L'automate de changement d'\'etat} +\label{sec:fsm-change} +\index{FSM!State Change} + +L'automate de changement d'\'etat, qui est repr\'esent\'e dans +\autoref{fig:fsm-change}, conduit le processus de changement d'\'etat de +la couche application de l'esclave. Il impl\'emente les \'etats et +transitions d\'ecrits dans \cite[sec.~6.4.1]{alspec}. + +\begin{figure}[htbp] + \centering + \includegraphics[width=.6\textwidth]{graphs/fsm_change} + \caption{Diagramme de transition de l'automate de changement d'\'etat} + \label{fig:fsm-change} +\end{figure} + +\begin{description} + +\item[Start] Le nouvel \'etat de la couche d'application (AL: + application-layer) est demand\'e via le registre ``AL Control + Request'' (voir~\cite[sec. 5.3.1]{alspec}). + +\item[Check for Response] Certains esclaves ont besoin de temps pour + r\'epondre \`a une commande de changement d'\'etat AL et ne + r\'epondent pas pendant un certain temps. Dans ce cas, la commande + est \`a nouveau \'emise, jusqu'\`a l'accus\'e de r\'eception. + +\item[Check AL Status] Si le datagramme de changement d'\'etat AL a + \'et\'e acquit\'e, le registre ``AL Control Response'' + (voir~\cite[sec. 5.3.2]{alspec}) doit \^etre lu jusqu'\`a ce que + l'esclave change l'\'etat AL. + +\item[AL Status Code] Si l'esclave refuse la commande de changement + d'\'etat, la raison peut \^etre lue dans le champ ``AL Status Code'' + des registres ``AL State Changed'' (voir~\cite[sec. 5.3.3]{alspec}). + +\item[Acknowledge State] Si le changement d'\'etat n'a pas r\'eussi, + le ma\^itre doit accuser r\'eception de l'ancien \'etat en + \'ecrivant \`a nouveau dans le registre ``AL Control request''. + + +\item[Check Acknowledge] Apr\`es l'envoi de la commande d'accus\'e de + r\'eception, le registre ``AL Control Response'' doit \^etre lu \`a + nouveau. + +\end{description} + +L'\'etat ``start\_ack'' est un raccourci dans l'automate quand le +ma\^itre veut accuser r\'eception d'un changement spontan\'e d'\'etat +AL, qui n'avait pas \'et\'e demand\'e. + +%------------------------------------------------------------------------------ + +\section{L'automate SII} +\label{sec:fsm-sii} +\index{FSM!SII} + +L'automate SII\index{SII} (pr\'esent\'e dans \autoref{fig:fsm-sii}) +impl\'emente le processus de lecture ou d'\'ecriture des donn\'ees +SII via l'interface d'information de l'esclave (Slave Information +Interface) d\'ecrite dans \cite[sec.~6.4]{dlspec}. + +\begin{figure}[htbp] + \centering + \includegraphics[width=.5\textwidth]{graphs/fsm_sii} + \caption{Diagramme de transition de l'automate SII} + \label{fig:fsm-sii} +\end{figure} + +Voici comment fonctionne la partie lecture de l'automate: + +\begin{description} + +\item[Start Reading] La requ\^ete de lecture et l'adresse du + mot demand\'e sont \'ecrits dans l'attribut SII. + +\item[Check Read Command] Si la commande de lecture SII a re\c{c}u son + accus\'e de r\'eception, un chronom\`etre est d\'emarr\'e. Un + datagramme est envoy\'e pour lire l'attribut SII pour l'\'etat et + les donn\'ees. + +\item[Fetch Data] Si l'op\'eration de lecture est encore en attente + (la SII est habituellement impl\'ement\'ee avec une E$^2$PROM), + l'\'etat est lu \`a nouveau. Sinon les donn\'ees sont copi\'ees dans + le datagramme. + +\end{description} + +La partie \'ecriture est presque similaire: + +\begin{description} + +\item[Start Writing] Une requ\^ete d'\'ecriture, l'adresse destination + et le mot de donn\'ee sont \'ecrits dans l'attribut SII. + +\item[Check Write Command] Si la commande d'\'ecriture SII a re\c{c}u + son accus\'e de r\'eception, un chronom\`etre est d\'emarr\'e. Un + datagramme est envoy\'e pour lire l'attribut SII pour l'\'etat de + l'op\'eration d'\'ecriture. + +\item[Wait while Busy] Si l'op\'eration d'\'ecriture est encore en + attente (d\'etermin\'e par un temps d'attente minimal et l'\'etat du + drapeau busy), l'automate reste dans cet \'etat pour \'eviter qu'une + autre op\'eration d'\'ecriture ne soit \'emise trop t\^ot. + +\end{description} + +%------------------------------------------------------------------------------ + +\section{Les automates PDO} +\label{sec:fsm-pdo} +\index{FSM!PDO} + +Les automates PDO sont un ensemble d'automates qui lisent ou +\'ecrivent l'affectation PDO et la cartographie des PDO via la ``zone +de communication CoE'' d\'ecrite dans \cite[sec. 5.6.7.4]{alspec}. +Pour l'acc\`es aux objets, les primitives CANopen over EtherCAT sont +utilis\'ees (voir \autoref{sec:coe}), donc l'esclave doit +obligatoirement supporter le protocole de bo\^ite aux lettres CoE. + +\paragraph{Automate de lecture PDO} Cet automate +(\autoref{fig:fsm-pdo-read}) a pour but de lire la configuration PDO +compl\`ete d'un esclave. Il lit l'affectation PDO et pour chaque +gestionnaire de configuration il utilise l'automate de lecture des +entr\'ees PDO (\autoref{fig:fsm-pdo-entry-read}) pour lire la +cartographie de chaque PDO assign\'e. + + +\begin{figure}[htbp] + \centering + \includegraphics[width=.4\textwidth]{graphs/fsm_pdo_read} + \caption{Diagramme de transition de l'automate de lecture des PDO} + \label{fig:fsm-pdo-read} +\end{figure} + +Fondamentalement, il lit pour chaque gestionnaire de synchronisation, +le compteur de PDOs affect\'es \`a ce gestionnaire de synchronisation +via l'objet SDO \lstinline+0x1C1x+. Il lit ensuite les sous-index +du SDO pour obtenir les indices des PDO affect\'es. Quand un index +PDO est lu, l'automate de lecture des entr\'ees PDO est ex\'ecut\'e +pour lire les entr\'ees PDO qui sont mapp\'ees en m\'emoire. + + +\paragraph{L'automate de lecture des entr\'ees PDO} +Cet automate (\autoref{fig:fsm-pdo-entry-read}) lit la cartograhie PDO +(les entr\'ees PDO) d'un PDO. Il lit la cartographie SDO respective +(\lstinline+0x1600+ -- \lstinline+0x17ff+, ou \lstinline+0x1a00+ -- +\lstinline+0x1bff+) pour le PDO donn\'e en lisant le sous-index z\'ero +(nombre d'\'el\'ements) pour d\'eterminer le nombre d'entr\'ee PDO +projet\'es en m\'emoire. Apr\`es cela, chaque sous-index est lu +pour obtenir l'index de l'entr\'ee PDO mapp\'ee en m\'emoire, ainsi +que son sous-index et sa taille en bits. + +\begin{figure}[htbp] + \centering + \includegraphics[width=.4\textwidth]{graphs/fsm_pdo_entry_read} + \caption{Diagramme de transition de l'automate de lecture des entr\'ees PDO} + \label{fig:fsm-pdo-entry-read} +\end{figure} + +\begin{figure}[htbp] + \centering + \includegraphics[width=.9\textwidth]{graphs/fsm_pdo_conf} + \caption{Diagramme de transition de l'automate de configuration des PDO} + \label{fig:fsm-pdo-conf} +\end{figure} + +\begin{figure}[htbp] + \centering + \includegraphics[width=.4\textwidth]{graphs/fsm_pdo_entry_conf} + \caption{Diagramme de transition de l'automate de configuration + des entr\'ees PDO} + \label{fig:fsm-pdo-entry-conf} +\end{figure} + +%------------------------------------------------------------------------------ + +\chapter{Impl\'ementation du protocole de bo\^ite aux lettres} + +\index{Mailbox} + +Le ma\^itre EtherCAT impl\'emente les protocoles de bo\^ite aux +lettres CANopen over EtherCAT (CoE), Ethernet over EtherCAT (EoE), +File-access over EtherCAT (FoE), Vendor-specific over EtherCAT (VoE) +et Servo Profile over EtherCAT (SoE). Voir les sections ci-dessous +pour les d\'etails. + +%------------------------------------------------------------------------------ + +\section{Ethernet over EtherCAT (EoE)} +\label{sec:eoe} +\index{EoE} + +Le ma\^itre EtherCAT impl\'emente le protocole de bo\^ite aux lettres +Ethernet over EtherCAT\nomenclature{EoE}{Ethernet over EtherCAT, + Mailbox Protocol}~\cite[sec.~5.7]{alspec} pour permettre le +tunnelage de trames Ethernet vers des esclaves sp\'eciaux, qui peuvent +soit avoir des ports physiques Ethernet ou avoir leur propre pile IP +pour recevoir les trames. + +\paragraph{Interfaces r\'eseaux virtuelles} + +Le ma\^itre cr\'ee une interface r\'eseau virtuelle EoE pour chaque +esclave compatible EoE. Ces interface sont nomm\'ees + +\begin{description} + +\item[eoeXsY] pour un esclave sans adresse alias (voir + \autoref{sec:ethercat-alias}), o\`u X est l'index du ma\^itre et Y + la position de l'esclave sur l'anneau. + +\item[eoeXaY] pour un esclave avec une adresse d'alias non-nulle, o\`u + X est l'index du ma\^itre et Y est l'adresse alias en d\'ecimal. + +\end{description} + +Les trames envoy\'ees vers ces interfaces sont transf\'er\'ees vers les +esclaves associ\'es par le ma\^itre. Les trames re\c{c}ues par les esclaves +sont r\'ecup\'er\'ees par le ma\^itre et transf\'er\'ees aux interfaces +virtuelles. + +Ceci apporte les avantages suivants: + +\begin{itemize} + +\item Flexibilit\'e: l'utilisateur peut d\'ecider comment les esclaves + compatibles EoE sont interconnect\'es avec le reste du monde. + +\item Les outils standards peuvent \^etre utilis\'es pour surveiller + l'activit\'e EoE et pour configurer les interfaces EoE. + +\item L'impl\'ementation du pontage de niveau 2 du noyau Linux (selon la + norme de pontage IEEE 802.1D MAC) peut \^etre utilis\'ee nativement pour + relier le trafic Ethernet entre les esclaves compatibles EoE. + +\item La pile r\'eseau du noyau Linux peut \^etre utilis\'ee pour router les + paquets entre les esclaves compatibles EoE et pour suivre les + probl\`emes de s\'ecurit\'e, comme avec une interface r\'eseau physique. + +\end{itemize} + +\paragraph{EoE Handlers} + +Les interface virtuelles EoE et les fonctionnalit\'es relatives sont +encapsul\'ees dans la classe \lstinline+ec_eoe_t+ class. Un objet de +cette classe est appel\'e ``gestionnaire EoE''. Par exemple, le ma\^itre +ne cr\'ee pas les interfaces r\'eseaux directement: ceci est fait \`a +l'int\'erieur du constructeur d'un gestionnaire EoE. Un gestionnaire +EoE contient \'egalement une file d'attente pour les trames. \`A chaque +fois que le noyau passe un nouveau tampon de socket pour l'envoyer via la +fonction de rappel \lstinline+hard_start_xmit()+ de l'interface, le +tampon de socket est mis en file d'attente pour la transmission via +l'automate EoE (voir ci-dessous). Si la file d'attente est pleine, le +passage des nouveaux tampons de socket est suspendu par un appel \`a +\lstinline+netif_stop_queue()+. + +\paragraph{Cr\'eation de gestionnaire EoE} + +Pendant l'analyse du bus (voir \autoref{sec:fsm-scan}), le ma\^itre +d\'etermine les protocoles de bo\^ite aux lettres support\'es par chaque +esclave. Ceci est fait en examinant le champ de bits ``Protocoles de +bo\^ite aux lettres support\'es'' au mot d'adresse 0x001C de la SII. Si le +bit 1 est d\'efini, alors l'esclave supporte le protocole EoE. Dans ce +cas, un gestionnaire EoE est cr\'e\'e pour cet esclave. + +\paragraph{Automate EoE} +\index{FSM!EoE} + +Chaque gestionnaire EoE poss\`ede son automate EoE, qui est utilis\'e pour +envoyer des trames \`a l'esclave correspondant et recevoir des trames +de celui-ci via les primitives de communication EoE. Cette automate +est pr\'esent\'e dans \autoref{fig:fsm-eoe}. + +\begin{figure}[htbp] + \centering + \includegraphics[width=.7\textwidth]{images/fsm-eoe} % FIXME + \caption{Diagramme de transition de l'automate EoE} + \label{fig:fsm-eoe} +\end{figure} + +% FIXME + +\begin{description} +\item[RX\_START] L'\'etat de d\'epart de l'automate EoE. Un datagramme de + v\'erification de la bo\^ite aux lettres est envoy\'e pour demander de + nouvelles trames \`a la bo\^ite aux lettres de + l'esclave. $\rightarrow$~RX\_CHECK + +\item[RX\_CHECK] Le datagramme de v\'erification de la bo\^ite aux lettres + est re\c{c}u. Si la bo\^ite aux lettres de l'esclave ne contenait pas de + donn\'ees, un cycle de transmission d\'ebute. $\rightarrow$~TX\_START + + S'il y a des nouvelles donn\'ees dans la bo\^ite aux lettres, un + datagramme est envoy\'e pour rapatrier les nouvelles donn\'ees. + $\rightarrow$~RX\_FETCH + +\item[RX\_FETCH] Le datagramme de rapatriement est re\c{c}u. Si la + donn\'ee dans la bo\^ite aux lettres ne contient pas de commande de + ``requ\^ete de fragment EoE'', les donn\'ees sont abandonn\'ees et une + s\'equence de transmission d\'emarre. $\rightarrow$~TX\_START + + Si la trame Ethernet re\c{c}ue est le premier fragment, un nouveau + tampon de socket est allou\'e. Sinon, les donn\'ees sont copi\'ees + \`a la bonne position dans le tampon de socket. + + Si le fragment est le dernier fragment, le tampon de socket est + envoy\'e \`a la pile r\'eseau et une s\'equence de transmission est + d\'emarr\'ee. $\rightarrow$~TX\_START + + Sinon, une nouvelle s\'equence de r\'eception est d\'emarr\'ee pour + rappatrier le prochain fragment. $\rightarrow$~RX\_\-START + +\item[TX\_START] L'\'etat de d\'emarrage de la s\'equence de + transmission. On v\'erifie si la file d'attente de la transmission + contient une trame \`a envoyer. Sinon, une s\'equence de r\'eception + est d\'emarr\'ee $\rightarrow$~RX\_START + + S'il y a une trame \`a envoyer, elle est retir\'ee de la file + d'attente. Si la file d'attente \'etait inactive auparavant (parce + qu'elle \'etait pleine), la file d'attente est r\'eveill\'ee par un + appel \`a \textit{netif\_wake\_queue()}. Le premier fragment de la + trame est envoy\'e. $\rightarrow$~TX\_SENT + +\item[TX\_SENT] On v\'erifie si le premier fragment a \'et\'e envoy\'e + avec succ\`es. Si la trame actuelle est constitu\'ee de fragments + suppl\'ementaires, le prochain est envoy\'e. $\rightarrow$~TX\_SENT + + Si le dernier fragment a \'et\'e envoy\'e, une nouvelle s\'equence + de r\'eception est d\'emarr\'ee. $\rightarrow$~RX\_START + +\end{description} + +\paragraph{Traitement EoE} + +Pour ex\'ecuter l'automate EoE de chaque gestionnaire EoE actif, il +doit y avoir un processus cyclique. La solution la plus simple serait +d'ex\'ecuter les automates EoE de mani\`ere synchrone avec l'automate +du ma\^itre (voir \autoref{sec:fsm-master}. Cette approche a les +inconv\'enients suivants: + +Un seul fragment EoE pourrait \^etre envoy\'e ou re\c{c}u tous les +quelques cycles. Le d\'ebit des donn\'ees serait tr\`es faible, parce +que les automates EoE ne seraient pas ex\'ecut\'es entre les cycles de +l'application. En outre, le d\'ebit d\'ependrait de la p\'eriode de +la t\^ache application. + +Pour surmonter ce probl\`eme, les automates EoE ont besoin de leur +propre processus cyclique pour s'ex\'ecuter. Pour cela, le ma\^itre +poss\`ede un timer noyau, qui est ex\'ecut\'e \`a chaque interruption +temporelle. Ceci garantie une bande passante constante, mais pose un +nouveau probl\`eme d'acc\`es concurrent au ma\^itre. Le m\'ecanisme +de verrouillage n\'ecessaire \`a cet effet est pr\'esent\'e dans +\autoref{sec:concurr}. + +\paragraph{Configuration automatique} + +Par d\'efaut, les esclaves sont laiss\'es dans l'\'etat PREOP si +aucune configuration n'est appliqu\'ee. Si le lien de l'interface EoE +est configur\'e \`a ``up'', l'\'etat de la couche application de +l'esclave concern\'e passe automatiquement \`a OP. + +%------------------------------------------------------------------------------ + +\section{CANopen over EtherCAT (CoE)} +\label{sec:coe} +\index{CoE} + +Le protocole CANopen over EtherCAT\nomenclature{CoE}{CANopen over + EtherCAT, Mailbox Protocol}~\cite[sec.~5.6]{alspec} permet de +configurer les esclaves et d'\'echanger des objets de donn\'ees au +niveau de l'application. + +% TODO +% +% Download / Upload +% Expedited / Normal +% Segmenting +% SDO Info Services +% + +\paragraph{Automate de t\'el\'echargement SDO} + +Le meilleur moment pour appliquer les configurations SDO est pendant +l'\'etat PREOP, parce que la communication par bo\^ite aux lettres est +d\'ej\`a possible et que l'application de l'esclave va d\'emarrer avec +la mise \`a jour des donn\'ees d'entr\'ees dans le prochain \'etat +SAFEOP. C'est pourquoi, la configuration SDO doit faire partie de +l'automate de configuration de l'esclave (voir +\autoref{sec:fsm-conf}): ceci est impl\'ement\'e via l'automate de +t\'el\'echargement SDO, qui est ex\'ecut\'e juste avant que l'esclave +entre dans l'\'etat SAFEOP. De cette mani\`ere, il est garanti que +les configurations SDO soient appliqu\'ees \`a chaque fois que l'esclave +est reconfigur\'e. + +Le diagramme de transition de l'automate de t\'el\'echargement SDO est +pr\'esent\'e dans \autoref{fig:fsm-coedown}. + +\begin{figure}[htbp] + \centering + \includegraphics[width=.9\textwidth]{images/fsm-coedown} % FIXME + \caption{Diagramme de transition de l'automate de t\'el\'echargement CoE} + \label{fig:fsm-coedown} +\end{figure} + +% FIXME + +\begin{description} +\item[START] L'\'etat de d\'epart de l'automate de t\'el\'echargement + CoE. La commande de bo\^ite aux lettres ``SDO Download + Normal Request'' est envoy\'ee. $\rightarrow$~REQUEST + +\item[REQUEST] On v\'erifie que l'esclave a re\c{c}u la requ\^ete de t\'el\'echargement CoE. Apr\`es cela, la commande de v\'erification de la bo\^ite aux lettres est \'emise et un minuteur est lanc\'e. $\rightarrow$~CHECK + +\item[CHECK] Si aucune donn\'ee n'est disponible + dans la bo\^ite aux lettres, le minuteur est v\'erifi\'e. + \begin{itemize} + \item S'il a expir\'e, le t\'el\'echargement SDO est interrompu. + $\rightarrow$~ERROR + \item Sinon la bo\^ite aux lettres est \`a nouveau interrog\'ee. + $\rightarrow$~CHECK + \end{itemize} + + Si la bo\^ite aux lettres contient des nouvelles donn\'ees, la + r\'eponse est rapatri\'ee. $\rightarrow$~RESPONSE + +\item[RESPONSE] Si la r\'eponse de la bo\^ite aux lettres ne peut pas + \^etre r\'ecup\'er\'ee, c'est que les donn\'ees sont invalides, ou + qu'on a re\c{c}u le mauvais protocole ou un ``Abort SDO Transfer + Request''. Alors on arr\^ete le t\'el\'echargement SDO. + $\rightarrow$~ERROR + + Si on re\c{c}oit l'accus\'e de r\'eception ``SDO Download Normal + Response'', le t\'el\'echargement SDO a r\'eussi. $\rightarrow$~END + +\item[END] Le t\'el\'echargement SDO a r\'eussi. + +\item[ERROR] Une erreur a arr\^et\'e le t\'el\'echargement SDO. + +\end{description} + +%------------------------------------------------------------------------------ + +\section{Vendor specific over EtherCAT (VoE)} +\label{sec:voe} +\index{VoE} + +Le protocole VoE permet d'impl\'ementer des protocoles de communication +par bo\^ite aux lettres sp\'ecifiques pour un fabricant. Les messages +VoE sont pr\'efix\'es par un ent\^ete VoE qui contient l'identit\'e du +fabricant (vendor ID) sur 32 bits et le type de fabricant +(vendor-type) sur 16 bit. Il n'y a aucune autre contrainte pour ce +protocole. + +Le ma\^itre EtherCAT autorise la cr\'eation multiple de gestionnaires +VoE pour les configurations d'esclaves via l'API (voir +\autoref{chap:api}). Ces gestionnaires contiennent les automates +n\'ecessaires \`a la communication via VoE.These + +Pour davantage d'information sur les gestionnaires VoE, voir +\autoref{sec:api-voe} ou les applications d'exemples dans le +sous-dossier \textit{examples/}. + +%------------------------------------------------------------------------------ + +\section{Servo Profile over EtherCAT (SoE)} +\label{sec:soe} +\index{SoE} + +Le protocole SoE impl\'emente la couche canal de service, +sp\'ecifi\'ee dans IEC 61800-7 \cite{soespec} via les bo\^ites aux +lettres EtherCAT. + +Le protocole SoE est tr\`es similaire au protocole CoE (vor +\autoref{sec:coe}). Mais \`a la place des index et sous-index SDO, des +num\'eros d'identification (IDNs) identifient les param\`etres. + +L'impl\'ementation couvre les primitives ``SCC Read'' et ``SCC Write'', +chacune est capable de fragmenter les donn\'ees. + +Il y a plusieurs mani\`eres d'utiliser l'impl\'ementation SoE: + +\begin{itemize} + +\item Lecture et \'ecriture des IDNs via l'outil en ligne de commande (voir +\autoref{sec:soeaccess}). + +\item Stocker des configuration pour des IDNs arbitraires via l'API + (voir \autoref{chap:api}, i.\,e.~\lstinline+ecrt_slave_config_idn()+). + Ces configurations sont \'ecrites dans l'esclave pendant la configuration + dans l'\'etat PREOP, avant de passer en SAFEOP. + +\item La biblioth\`eque en espace utilisateur (voir + \autoref{sec:userlib}), offre des fonctions pour lire/\'ecrire les + IDNs en mode bloquant (\lstinline+ecrt_master_read_idn()+, + \lstinline+ecrt_master_write_idn()+). + +\end{itemize} + +%------------------------------------------------------------------------------ + +\chapter{Interfaces dans l'espace utilisateur} +\label{sec:user} +\index{Userspace} + +Puisque le ma\^itre s'ex\'ecute en tant que module noyau, ses acc\`es +natifs se limitent \`a analyser les messages Syslog et \`a le +contr\^oler avec \textit{modutils}. + +Il \'etait donc n\'ecessaire d'impl\'ementer d'autres interface pour +faciliter l'acc\`es au ma\^itre depuis l'espace utilisateur et pour +permettre une influence plus fine. Il doit \^etre possible de voir et +de changer des param\`etres sp\'eciaux en cours d'ex\'ecution. + +La visualisation du bus est un autre point: dans un but de +d\'eveloppement et de d\'everminage, il est n\'ecessaire, par +exemple, de montrer les esclaves connect\'es (voir +\autoref{sec:tool}). + +L'API doit \^etre disponible depuis l'espace utilisateur pour +permettre aux programmes qui s'y trouvent d'utiliser les +fonctionnalit\'es EtherCAT. Ceci est impl\'ement\'e via un +p\'eriph\'erique en mode caract\`ere et une biblioth\`eque en espace +utilisateur (voir \autoref{sec:userlib}). + +Le d\'emarrage et la configuration automatique sont d'autres aspects. +Le ma\^itre doit \^etre capable de d\'emarrer automatiquement avec une +configuration persistante (voir \autoref{sec:system}). + +La surveillance des communications EtherCAT est un dernier point. +Dans un but de d\'everminage, il faut avoir un moyen d'analyser les +datagrammes EtherCAT. La meilleure solution serait d'utiliser un +analyseur r\'eseau populaire, tel que Wireshark \cite{wireshark} ou +d'autres (voir \autoref{sec:debug}). + +Ce chapitre couvre tous ces points et pr\'esente les interfaces et +outils qui les rendent possibles. + +%------------------------------------------------------------------------------ + +\section{Outil en ligne de commande} +\label{sec:tool} + +% TODO --master + +\subsection{P\'eriph\'eriques en mode caract\`eres} +\label{sec:cdev} + +Chaque instance de ma\^itre recoit un p\'eriph\'erique en mode +caract\`ere comme interface en espace utilisateur. +Les p\'eriph\'eriques sont nomm\'es \textit{/dev/EtherCATx}, +o\`u $x \in \{0 \ldots n\}$ est l'index du ma\^itre. + + +\paragraph{Cr\'eation des n\oe{}uds de p\'eriph\'eriques} +Les n\oe{}uds des p\'eriph\'eriques en mode caract\`eres sont +automatiquement cr\'e\'es si le paquet \lstinline+udev+ est +install\'e. Voir \autoref{sec:autonode} pour son installation et sa +configuration. + +%------------------------------------------------------------------------------ + +\subsection{Param\`etre d'alias d'adresse} +\label{sec:ethercat-alias} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_alias} + +%------------------------------------------------------------------------------ + +\subsection{Affichage de la configuration du bus} +\label{sec:ethercat-config} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_config} + +%------------------------------------------------------------------------------ + +\subsection{Sortie des informations PDO en langage C} +\label{sec:ethercat-cstruct} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_cstruct} + +%------------------------------------------------------------------------------ + +\subsection{Affichage des donn\'ees de processus} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_data} + +%------------------------------------------------------------------------------ + +\subsection{Configuration du niveau de d\'everminage d'un ma\^itre} +\label{sec:ethercat-debug} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_debug} + +%------------------------------------------------------------------------------ + +\subsection{Domaines configur\'es} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_domains} + +%------------------------------------------------------------------------------ + +\subsection{Acc\`es SDO} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_download} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_upload} + +%------------------------------------------------------------------------------ + +\subsection{Statistiques EoE} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_eoe} + +%------------------------------------------------------------------------------ + +\subsection{File-Access over EtherCAT} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_foe_read} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_foe_write} + +%------------------------------------------------------------------------------ + +\subsection{Cr\'eation de graphiques topologiques} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_graph} + +%------------------------------------------------------------------------------ + +\subsection{Ma\^itre et p\'eriph\'eriques Ethernet} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_master} + +%------------------------------------------------------------------------------ + +\subsection{Gestionnaires de synchronisation, PDOs et entr\'ees PDO} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_pdos} + +%------------------------------------------------------------------------------ + +\subsection{Registre d'acc\`es} +\label{sec:regaccess} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_reg_read} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_reg_write} + +%------------------------------------------------------------------------------ + +\subsection{Dictionnaire SDO} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_sdos} + +%------------------------------------------------------------------------------ + +\subsection{Acc\`es SSI} +\label{sec:siiaccess} +\index{SII!Access} + +Il est possible de lire ou \'ecrire directement tout le contenu SII +des esclaves. Ceci a \'et\'e ajout\'e pour les raisons ci-dessous: + +\begin{itemize} + +\item Le format des donn\'ees SII est encore en d\'eveloppement et des + cat\'egories peuvent \ \^etre ajout\'ees dans le futur. Avec les + acc\`es en lecture et \'ecriture, tout le contenu de la m\'emoire + peut \^etre facilement sauvegard\'e et restaur\'e. + +\item Certaines champs SII doivent \^etre alt\'er\'es (par exemple les + alias d'adresses). Une \'ecriture rapide est donc n\'ecessaire pour + cela. + +\item Au travers de l'acc\`es en lecture, l'analyse des cat\'egories + de donn\'ees doit \^etre possible depuis l'espace utilisateur. + +\end{itemize} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_sii_read} + +Le lecture des donn\'ees SII est aussi facile que les autres commandes. +Comme les donn\'ees sont au format binaire, +l'analyse est plus facile avec un outil tel que \textit{hexdump}: + +\begin{lstlisting} +$ `\textbf{ethercat sii\_read --position 3 | hexdump}` +0000000 0103 0000 0000 0000 0000 0000 0000 008c +0000010 0002 0000 3052 07f0 0000 0000 0000 0000 +0000020 0000 0000 0000 0000 0000 0000 0000 0000 +... +\end{lstlisting} + +La sauvegarde de la SII peut \^etre facilement faite avec une redirection: + +\begin{lstlisting} +$ `\textbf{ethercat sii\_read --position 3 > sii-of-slave3.bin}` +\end{lstlisting} + +Pour t\'el\'everser une SII dans un esclave, l'acc\`es en \'ecriture +au p\'eriph\'erique en mode caract\`ere du ma\^itre est n\'ecessaire +(voir \autoref{sec:cdev}). + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_sii_write} + +\begin{lstlisting} +# `\textbf{ethercat sii\_write --position 3 sii-of-slave3.bin}` +\end{lstlisting} + +La validit\'e du contenu de la SSI peut \^etre v\'erifi\'ee puis le +contenu est envoy\'e \`a l'esclave. L'op\'eration d'\'ecriture peut +prendre quelques secondes. + +%------------------------------------------------------------------------------ + +\subsection{Esclaves sur le bus} + +Les informations sur les esclaves peuvent \^etre collect\'ees avec la +sous-commande \lstinline+slaves+: + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_slaves} + +Voici par exemple une sortie typique: + +\begin{lstlisting} +$ `\textbf{ethercat slaves}` +0 0:0 PREOP + EK1100 Ethernet Kopplerklemme (2A E-Bus) +1 5555:0 PREOP + EL3162 2K. Ana. Eingang 0-10V +2 5555:1 PREOP + EL4102 2K. Ana. Ausgang 0-10V +3 5555:2 PREOP + EL2004 4K. Dig. Ausgang 24V, 0,5A +\end{lstlisting} + +%------------------------------------------------------------------------------ + +\subsection{Acc\`es IDN SoE} +\label{sec:soeaccess} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_soe_read} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_soe_write} + +%------------------------------------------------------------------------------ + +\subsection{Demande des \'etats de la couche application} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_states} + +%------------------------------------------------------------------------------ + +\subsection{Affichage de la version du ma\^itre} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_version} + +%------------------------------------------------------------------------------ + +\subsection{G\'en\'eration de la description de l'esclave au format XML} + +\lstinputlisting[basicstyle=\ttfamily\footnotesize]{external/ethercat_xml} + +%------------------------------------------------------------------------------ + +\section{Biblioth\`eque en espace utilisateur} +\label{sec:userlib} + +L'API native (voir \autoref{chap:api}) se trouve dans l'espace noyau +et n'est donc accessible que depuis le noyau. +Pour rendre l'API disponible aux programmes en espace utilisateur, +une biblioth\`eque en espace utilisateur a \'et\'e cr\'e\'ee, et elle +peut \^etre li\'ee \`a des programmes selon les termes et conditions +de la licence LGPL, version 2 \cite{lgpl}. + +La biblioth\`eque s'appelle \textit{libethercat}. Ses sources se +trouvent dans le sous-dossier \textit{lib/} et elles sont construites +par d\'efaut lorsqu'on utilise la commande \lstinline+make+. Elle est +install\'ee dans le sous-dossier \textit{lib/} en dessous du pr\'efixe +d'installation sous le nom \textit{libethercat.a} (pour la liaison +statique), \textit{libethercat.la} (pour utiliser avec +\textit{libtool}) et \textit{libethercat.so} (pour la liaison +dynamique). + +\subsection{Utilisation de la biblioth\`eque} + +Le fichier d'ent\^ete \textit{ecrt.h} de l'API peut \^etre utilis\'e +dans les deux contextes: utilisateur ou noyau. + +L'exemple minimal suivant montre comment construire un programme +EtherCAT. Un exemple complet se trouve dans le dossier \textit{examples/user/} +des sources du ma\^itre. + +\begin{lstlisting}[language=C] +#include + +int main(void) +{ + ec_master_t *master = ecrt_request_master(0); + + if (!master) + return 1; // error + + pause(); // wait for signal + return 0; +} +\end{lstlisting} + +Le programme peut \^etre compil\'e et dynamiquement li\'e \`a la +biblioth\`eque avec la commande ci-dessous: + +\begin{lstlisting}[caption=Commande de l'\'editeur de liens pour utiliser la biblioth\`eque + de l'espace utilisateur, +label=lst:linker-user] +gcc ethercat.c -o ectest -I/opt/etherlab/include \ + -L/opt/etherlab/lib -lethercat \ + -Wl,--rpath -Wl,/opt/etherlab/lib +\end{lstlisting} + +La biblioth\`eque peut aussi \^etre li\'ee statiquement au programme: + +\begin{lstlisting} +gcc -static ectest.c -o ectest -I/opt/etherlab/include \ + /opt/etherlab/lib/libethercat.a +\end{lstlisting} + +\subsection{Impl\'ementation} +\label{sec:userimp} + +Fondamentalement, l'API noyau a \'et\'e transfer\'ee dans l'espace +utilisateur via le p\'eriph\'erique en mode caract\'ere du ma\^itre +(voir \autoref{chap:arch}, \autoref{fig:arch} et \autoref{sec:cdev}). + +Les appels de fonction de l'API noyau sont projet\'es dans l'espace +utilisateur via l'interface \lstinline+ioctl()+. Les fonctions de +l'API en espace utilisateur partagent un ensemble d'appels +\lstinline+ioctl()+ g\'en\'eriques. La partie noyau des appels de +l'interface appelle directement les fonctions correspondantes de +l'API, ce qui ajoute un minimum de d\'elai suppl\'ementaire (voir +\autoref{sec:usertiming}). + +Pour des raisons de performance, les donn\'ees de processus r\'eels +(voir \autoref{sec:processdata}) ne sont pas copi\'ees entre la +m\'emoire du noyau et celle de l'utilisateur: \`a la place, les +donn\'ees sont projet\'ees en m\'emoire vers l'application en espace +utilisateur. Une fois que le ma\^itre est configur\'e et activ\'e, le +module ma\^itre cr\'ee une zone de m\'emoire de donn\'ees de processus +couvrant tous les domaines et la mappe dans l'espace utilisateur, de +sorte que l'application puisse acc\'eder directement aux donn\'ees de +processus. En cons\'equence, il n'y a pas de d\'elai suppl\'ementaire lors +de l'acc\`es aux donn\'ees de processus depuis l'espace utilisateur. + +\paragraph{Diff\'erence API noyau/utilisateur} +En raison de la projection en m\'emoire des donn\'ees de processus, la +m\'emoire est g\'er\'ee en interne par les fonctions de la biblioth\`eque. +Par cons\'equent, il est impossible de fournir de la m\'emoire externe +pour les domaines, comme pour l'API noyau. Les fonctions +correspondantes sont disponibles uniquement dans l'espace noyau. +C'est la seule diff\'erence lorsqu'on utilise l'API depuis l'espace +utilisateur. + +\subsection{Timing} +\label{sec:usertiming} + +Un aspect int\'eressant est la comparaison du timing des appels de la +biblioth\`eque en espace utilisateur avec ceux de l'API noyau. +\autoref{tab:usertiming} montre les dur\'ees des appels et l'\'ecart-type +des fonctions de l'API typiques (et critiques pour le temps) mesur\'ee +avec un processeur Intel Pentium 4 M avec \unit{2.2}{\giga\hertz} et +un noyau standard 2.6.26. + +\begin{table}[htbp] + \centering + \caption{Comparaison du timing des API} + \label{tab:usertiming} + \vspace{2mm} + \begin{tabular}{l|c|c|c|c} + + & + \multicolumn{2}{|c}{\textbf{Espace noyau}} & + \multicolumn{2}{|c}{\textbf{Espace utilisateur}} \\ + + \textbf{Fonction} & + $\mu(t)$ & + $\sigma(t)$ & + $\mu(t)$ & + $\sigma(t)$ \\ + \hline + + \lstinline+ecrt_master_receive()+ & + \unit{1.1}{\micro\second} & + \unit{0.3}{\micro\second} & + \unit{2.2}{\micro\second} & + \unit{0.5}{\micro\second} \\ + + \lstinline+ecrt_domain_process()+ & + \unit{<0.1}{\micro\second} & + \unit{<0.1}{\micro\second} & + \unit{1.0}{\micro\second} & + \unit{0.2}{\micro\second} \\ + + \lstinline+ecrt_domain_queue()+ & + \unit{<0.1}{\micro\second} & + \unit{<0.1}{\micro\second} & + \unit{1.0}{\micro\second} & + \unit{0.1}{\micro\second} \\ + + \lstinline+ecrt_master_send()+ & + \unit{1.8}{\micro\second} & + \unit{0.2}{\micro\second} & + \unit{2.5}{\micro\second} & + \unit{0.5}{\micro\second} \\ + + \end{tabular} +\end{table} + +Les r\'esultats des tests montrent que, dans cette configuration, l'API +en espace utilisateur rajoute un d\'elai suppl\'ementaire d'environ +\unit{1}{\micro\second} \`a chaque fonction, par rapport \`a l'API en +mode noyau. + +%------------------------------------------------------------------------------ + +\section{Interface RTDM} +\label{sec:rtdm} + +Lorsqu'on utilise les interfaces en espace utilisateur des extensions +temps r\'eels telles que Xenomai ou RTAI, il est d\'econseill\'e d'utiliser +\textit{ioctl()}, parce que \c{c}a peut perturber les op\'erations en +temps r\'eels. Pour y parvenir, le mod\`ele de p\'eriph\'erique temps r\'eel +(Real-Time Device Model = RTDM\cite{rtdm}) a \'et\'e d\'evelopp\'e. Le module +ma\^itre fourni une interface RTDM (voir \autoref{fig:arch}) en plus du +p\'eriph\'erique normal en mode caract\`ere, si les sources du ma\^itres sont +configur\'ees avec \lstinline+--enable-rtdm+ (voir +\autoref{sec:installation}). + +Pour forcer une application \`a utiliser l'interface RTDM au lieu du +p\'eriph\'erique normal en mode caract\`eres, elle doit \^etre li\'ee avec la +biblioth\`eque \textit{libethercat\_rtdm} au lieu de +\textit{libethercat}. L'utilisation de \textit{libethercat\_rtdm} est +transparente, par cons\'equent l'ent\^ete EtherCAT \textit{ecrt.h} peut +\^etre utilis\'e comme d'habitude avec l'API compl\`ete. + +Pour construire l'exemple dans \autoref{lst:linker-user} avec la +biblioth\`eque RTDM, la commande de l'\'editeur de lien doit \^etre modifi\'ee +comme ci-dessous: + +\begin{lstlisting} +gcc ethercat-with-rtdm.c -o ectest -I/opt/etherlab/include \ + -L/opt/etherlab/lib -lethercat_rtdm \ + -Wl,--rpath -Wl,/opt/etherlab/lib +\end{lstlisting} + +%------------------------------------------------------------------------------ + +\section{Int\'egration syst\`eme} +\label{sec:system} + +Pour int\'egrer le ma\^itre EtherCAT en tant que service dans un +syst\`eme en cours d'ex\'ecution, il vient avec un script +d'initialisation et un fichier sysconfig qui sont d\'ecrits +ci-dessous. Les syst\`emes plus modernes utilisent systemd +\cite{systemd}. L'int\'egration du ma\^itre avec systemd est +d\'ecrite dans \autoref{sec:systemd}. + +\subsection{Script d'initialisation} +\label{sec:init} +\index{Init script} + +Le script d'initialisation du ma\^itre EtherCAT est conforme aux +exigences de la ``Linux Standard Base'' ( (LSB\index{LSB}, \cite{lsb}) +). Le script est install\'e dans \textit{etc/init.d/ethercat} sous le +pr\'efixe d'installation et doit \^etre copi\'e (ou encore mieux: +li\'e) aux destinations appropri\'ees +(voir\autoref{sec:installation}), avant que le ma\^itre puisse \^etre +ins\'er\'e en tant que service. Veuillez noter, que ce script +d'initialisation d\'epend du fichier sysconfig d\'ecrit ci-dessous. + +Pour indiquer les d\'ependances du service (c'est-\`a-dire, quels +services doivent \^etre d\'emarr\'es avant les autres) \`a +l'int\'erieur du code du script d'initialisation, LSB d\'efinit un +bloc sp\'ecial de commentaires. Les outils syst\`emes peuvent +extraire cette information pour ins\'erer le script d'initialisation +EtherCAT \`a la bonne position dans la s\'equence de d\'emarrage: + +\lstinputlisting[firstline=38,lastline=48] + {../script/init.d/ethercat} + +\subsection{Fichier sysconfig} +\label{sec:sysconfig} +\index{Sysconfig file} + +Pour la configuration persistante, le script d'initialisation utilise +un fichier sysconfig install\'e dans \textit{etc/sysconfig/ethercat} +(sous le pr\'efixe d'installation), qui est obligatoire. Le fichier +sysconfig contient toutes les variables de configuration requises pour +op\'erer un ou plusieurs ma\^itres. La documentation se trouve dans le +fichier et elle est reproduite ci-dessous: + +\lstinputlisting[numbers=left,firstline=9,basicstyle=\ttfamily\scriptsize] + {../script/sysconfig/ethercat} + + Pour les syst\`emes g\'er\'es par systemd (voir \autoref{sec:systemd}), + le fichier sysconfig a \'et\'e d\'eplac\'e dans \lstinline+/etc/ethercat.conf+. + Les deux versions font parties des sources du ma\^itre et sont destin\'ees + \`a \^etre utilis\'ees en alternance. + +\subsection{D\'emarrage du ma\^itre comme service} +\label{sec:service} +\index{Service} + +Une fois que le script d'initialisation et le fichier sysconfig ont +\'et\'e install\'es au bon endroit, le ma\^itre EtherCAT peut \^etre +ins\'er\'e comme un service. Les diff\'erentes distributions Linux +offrent diff\'erentes fa\c{c}ons pour marquer un service pour le +d\'emarrage ou l'arr\^et dans certains runlevels. Par exemple, SUSE +Linux fournit la commande \textit{insserv}: + +\begin{lstlisting} +# `\textbf{insserv ethercat}` +\end{lstlisting} + +Le script d'initialisation peut aussi \^etre utilis\'e pour d\'emarrer +ou stopper manuellement le ma\^itre EtherCAT. + +Il doit \^etre ex\'ecut\'e avec un des param\`etres suivants: +\texttt{start}, \texttt{stop}, \texttt{restart} ou \texttt{status}. + +\begin{lstlisting}[gobble=2] + # `\textbf{/etc/init.d/ethercat restart}` + Shutting down EtherCAT master done + Starting EtherCAT master done +\end{lstlisting} + +\subsection{Int\'egration avec systemd} +\label{sec:systemd} +\index{systemd} + +Les distributions utilisant \textit{systemd} \`a la place du syst\`eme +d'initialisation SysV utilisent des fichiers de service pour d\'ecrire +comment un service doit \^etre maintenu. \autoref{lst:service} liste +le fichier de service du ma\^itre: + +\lstinputlisting[basicstyle=\ttfamily\footnotesize,caption=Service + file, label=lst:service]{../script/ethercat.service} + +La commande \textit{ethercatctl} est utilis\'ee pour charger et +d\'echarger le ma\^itre et les modules des pilotes r\'eseaux de la +m\^eme mani\`ere que l'ancien script d'initialisation +(\autoref{sec:init}). Puisqu'il est install\'e dans le dossier +\textit{sbin/}, il peut aussi \^etre utilis\'e s\'epar\'ement: + +\begin{lstlisting}[gobble=2] + # `\textbf{ethercatctl start}` +\end{lstlisting} + +Lorsqu'on utilise systemd et/ou la commande \textit{ethercatctl}, le +fichier de configuration du ma\^itre doit \^etre dans +\texttt{/etc/ethercat.conf} au lieu de +\texttt{/etc/sysconfig/ethercat}! Celui-ci est ignor\'e. Les options +de configurations sont exactement les m\^emes. + +%------------------------------------------------------------------------------ + +\section{Interfaces de d\'everminage} +\label{sec:debug} +\index{Debug Interfaces} + +Les bus EtherCAT peuvent toujours \^etre surveill\'es en ins\'erant un +commutateur entre le ma\^itre et l'esclave. Ceci permet de connecter +un autre PC avec un analyseur r\'eseau, par exemple +Wireshark~\cite{wireshark}. Il est aussi possible d'\'ecouter +directement sur les interfaces r\'eseaux locales de la machine +ex\'ecutant le ma\^itre EtherCAT. Si le pilote Ethernet g\'en\'erique +(voir \autoref{sec:generic-driver}) est utilis\'e, l'analyseur +r\'eseau peut \'ecouter directement sur l'interface r\'eseau +connect\'e au bus EtherCAT. + +Si on utilise les pilotes Ethernet natifs (voir +\autoref{sec:native-drivers}), il n'y a aucune interface r\'eseau +local pour \'ecouter, parce que les p\'eriph\'eriques Ethernet +utilis\'es pour EtherCAT ne sont par enregistr\'es dans la pile +r\'eseau. Dans ce cas, des ``interfaces de d\'everminage'' sont +support\'ees: ce sont des interfaces r\'eseaux virtuelles pour +permettre la capture du trafic EtherCAT avec un analyseur r\'eseau +(comme Wireshark ou tcpdump) s'ex\'ecutant sur la machine ma\^itresse +sans utiliser de mat\'eriel externe. Pour utiliser cette +fonctionnalit\'e, les sources du ma\^itre doivent avoir \'et\'e +configur\'ees avec l'option \lstinline+--enable-debug-if+ (voir +\autoref{sec:installation}). + +Chaque ma\^itre EtherCAT enregistre une interface r\'eseau en lecture +seule par p\'eriph\'erique Ethernet physique. Les interfaces +r\'eseaux sont nomm\'ees \textit{ecdbgmX} pour le p\'eriph\'erique +principal et \textit{ecdbgbX} pour le p\'eriph\'erique de secours, +o\`u X est l'index du ma\^itre. Le listing ci-dessous montre une +interface de d\'everminage parmi des interfaces r\'eseaux standards: + +\begin{lstlisting} +# `\textbf{ip link}` +1: lo: mtu 16436 qdisc noqueue + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 +4: eth0: mtu 1500 qdisc noop qlen 1000 + link/ether 00:13:46:3b:ad:d7 brd ff:ff:ff:ff:ff:ff +8: ecdbgm0: mtu 1500 qdisc pfifo_fast + qlen 1000 + link/ether 00:04:61:03:d1:01 brd ff:ff:ff:ff:ff:ff +\end{lstlisting} + +Lorsque l'interface de d\'everminage est activ\'ee, toutes les trames +envoy\'ees ou re\c{c}ues depuis ou vers le p\'eriph\'erique physique +sont aussi transmises \`a l'interface de d\'everminage par le ma\^itre +correspondant. Les interfaces r\'eseaux peuvent \^etre activ\'ees avec +la commande ci-dessous: + +\begin{lstlisting} +# `\textbf{ip link set dev ecdbgm0 up}` +\end{lstlisting} + +Veuillez noter, que la fr\'equence des trames peut \^etre tr\`es \'elev\'ee. +Avec une application connect\'ee, l'interface de d\'everminage +peut produire des milliers de trames par seconde. + +\paragraph{Attention} Les tampons de socket n\'ecessaires pour les interfaces +de d\'everminage doivent \^etre allou\'es dynamiquement. +Certaines extensions temps r\'eels pour Linux (comme RTAI) +ne l'autorisent pas un contexte temps r\'eel~! + +%------------------------------------------------------------------------------ + +\chapter{Aspects temporels} +\label{sec:timing} + +Bien que le timing EtherCAT soit hautement d\'eterministe et que par +cons\'equent les probl\`emes de timing soient rares, il y a quelques aspects +qui peuvent (et doivent) \^etre trait\'es. + +%------------------------------------------------------------------------------ + +\section{Profilage de l'interface de programmation applicative} +\label{sec:timing-profile} +\index{Profiling} +% FIXME + +Un des aspects de timing les plus important est le temps d'ex\'ecution +des fonctions de l'API, qui sont appel\'ees dans un contexte cyclique. +Ces fonctions prennent une part importante du timing d'ensemble de +l'application. +Pour mesurer le timing de ces fonctions, le code suivant a \'et\'e +utilis\'e: + +\begin{lstlisting}[gobble=2,language=C] + c0 = get_cycles(); + ecrt_master_receive(master); + c1 = get_cycles(); + ecrt_domain_process(domain1); + c2 = get_cycles(); + ecrt_master_run(master); + c3 = get_cycles(); + ecrt_master_send(master); + c4 = get_cycles(); +\end{lstlisting} + +Entre chaque appel d'une fonction de l'API, le compteur d'horodatage +d'estampille du microprocesseur est lu. Les diff\'erences des +compteurs sont converties en \micro\second\ au moyen de la variable +\lstinline+cpu_khz+, qui contient le nombre d'incr\'ements par +\milli\second. + +Pour la mesure r\'eelle, un syst\`eme avec un microprocesseur \`a +\unit{2.0}{\giga\hertz} a \'et\'e utilis\'e pour ex\'ecuter le code +ci-dessus dans un fil d'ex\'ecution RTAI avec une p\'eriode de +\unit{100}{\micro\second}. La mesure a \'et\'e r\'ep\'et\'ee $n = +100$ fois et les r\'esultats ont \'et\'e moyenn\'es. Ils sont visibles +dans \autoref{tab:profile}. + +\begin{table}[htpb] + \centering + \caption{Profilage d'un cycle d'application sur un processeur \`a \unit{2.0}{\giga\hertz}} + \label{tab:profile} + \vspace{2mm} + \begin{tabular}{l|r|r} + \'Element & Dur\'ee moyenne [\second] & D\'eviation standard [\micro\second] \\ + \hline + \textit{ecrt\_master\_receive()} & 8.04 & 0.48\\ + \textit{ecrt\_domain\_process()} & 0.14 & 0.03\\ + \textit{ecrt\_master\_run()} & 0.29 & 0.12\\ + \textit{ecrt\_master\_send()} & 2.18 & 0.17\\ \hline + Cycle complet & 10.65 & 0.69\\ \hline + \end{tabular} +\end{table} + +Il est \'evident, que les fonctions qui acc\`edent au mat\'eriel +prennent la part du lion. La fonction \textit{ec\_master\_receive()} +ex\'ecute la requ\^ete de service d'interruption (ISR) du p\'eriph\'erique +Ethernet, analyse les datagrammes et copie leurs contenus dans la +m\'emoire des objets datagrammes. La fonction +\textit{ec\_master\_send()} assemble une trame \`a partir des +datagrammes et la copie vers les tampons mat\'eriels. Il est +int\'eressant de noter, que ceci ne prend qu'un quart du temps de +r\'eception. + +Les fonctions qui op\`erent uniquement sur les structures de donn\'ees +internes des ma\^itres sont tr\`es rapides ($\Delta t < +\unit{1}{\micro\second}$). Il est int\'eressant de noter que +l'ex\'ecution de \textit{ec\_domain\_process()} a un petit \'ecart-type +par rapport \`a la moyenne, alors que le ratio est presque deux fois +plus grand pour \textit{ec\_master\_run()}: Cela vient probablement +des fonctions ult\'erieures qui doivent ex\'ecuter le code en fonction de +l'\'etat courant et les diff\'erentes fonctions d'\'etat sont plus ou moins +complexes. + +Pour un cycle en temps r\'eel qui repr\'esente environ +\unit{10}{\micro\second}, la fr\'equence th\'eorique peut atteindre +jusqu'\`a \unit{100}{\kilo\hertz}. Mais cette fr\'equence reste th\'eorique +pour deux raisons: + +\begin{enumerate} + +\item Le processeur doit continuer \`a ex\'ecuter le syst\`eme d'exploitation + entre les cycles temps r\'eels. + +\item Les trames EtherCAT doivent \^etre envoy\'ees et re\c{c}ues, avant que + le prochain cycle temps r\'eel commence. La d\'etermination du temps de + cycle du bus est difficile. Elle est couverte dans + \autoref{sec:timing-bus}. + +\end{enumerate} + +%------------------------------------------------------------------------------ + +\section{Mesure des cycles du bus} +\label{sec:timing-bus} +\index{Bus cycle} + +Pour mesurer le temps pendant lequel, la trame est ``sur le c\^able'', +deux horodatages sont n\'ecessaires: + +\begin{enumerate} + +\item Le premier quand le mat\'eriel Ethernet commence \`a envoyer physiquement + la trame. + +\item Le second quand la trame est compl\`etement re\c{c}ue par le mat\'eriel + Ethernet. + +\end{enumerate} + +Les deux instants sont difficiles \`a d\'eterminer. La premi\`ere +raison est que les interruptions sont d\'esactiv\'ees et le ma\^itre +n'est pas notifi\'e quand une trame est envoy\'ee ou re\c{c}ue (un +sondage fausserait les r\'esultats). La deuxi\`eme raison est que, +m\^eme avec les interruptions activ\'ees, la dur\'ee entre +l'\'ev\`enement et la notification est inconnue. C'est pourquoi, la +seule mani\`ere de d\'eterminer avec certitude le temps de cycle du +bus est une mesure \'electrique. + +De toute fa\c{c}on, la dur\'ee du cycle du bus est un facteur +important lors de la conception du code temps r\'eel, car il limite la +fr\'equence maximale pour la t\^ache cyclique de l'application. En +pratique, ces param\`etres de timing d\'ependent fortement du +mat\'eriel et une m\'ethode par essais et erreurs doit \^etre +utilis\'ee pour d\'eterminer les limites du syst\`eme. + +La question centrale est: Que se passe-t-il si la fr\'equence du cycle +est trop haute? La r\'eponse est que les trames EtherCAT qui ont +\'et\'e envoy\'ees \`a la fin du cycle ne sont pas encore re\c{c}ues +quand le prochain cycle d\'emarre. + +Ceci est notifi\'e en premier par \textit{ecrt\_domain\_process()}, +parce que le compteur de travail des datagrammes de donn\'ees de +processus n'est pas incr\'ement\'e. La fonction notifiera +l'utilisateur via Syslog\footnote{ Pour limiter la sortie de Syslog, + un m\'ecanisme a \'et\'e impl\'ement\'e pour g\'en\'erer une + notification r\'esum\'ee au maximum une fois par seconde.}. Dans ce +cas, les donn\'ees de processus sont conserv\'es identiques comme dans +le dernier cycle, parce qu'elles ne sont pas \'ecras\'ees par le +domaine. Quand les datagrammes du domaine sont \`a nouveau mis en +file d'attente, le ma\^itre s'aper\c{c}oit qu'ils ont d\'ej\`a \'et\'e +mis en file d'attente (et marqu\'es comme envoy\'es). Le ma\^itre les +marquera \`a nouveau comme non-envoy\'es et affichera un avertissement +que les datagrammes ont \'et\'e ``ignor\'es''. + +Sur le syst\`eme \`a \unit{2.0}{\giga\hertz} mentionn\'e, la +fr\'equence de cycle possible peut atteindre \unit{25}{\kilo\hertz} +sans perdre de trames. Cette valeur peut s\^urement \^etre +augment\'ee en choisissant un mat\'eriel plus rapide. En particulier +le mat\'eriel r\'eseau RealTek peut \^etre remplac\'e par un autre +plus rapide. En outre, la mise en oeuvre d'un ISR d\'edi\'e pour les +p\'eriph\'eriques EtherCAT contribuerait \'egalement \`a augmenter la +latence. Ces deux points sont la liste des choses encore \`a faire de +l'auteur. + +%------------------------------------------------------------------------------ + +\chapter{Installation} +\label{sec:installation} +\index{Master!Installation} + +\section{Obtention du logiciel} +\label{sec:getting} + +Il y a plusieurs mani\`eres d'obtenir le logiciel du ma\^itre: + +\begin{enumerate} + +\item Une version officielle (par exemple \masterversion) peut \^etre + t\'el\'echarg\'ee depuis le site web du + ma\^itre\footnote{\url{http://etherlab.org/en/ethercat/index.php}} + dans le projet EtherLab~\cite{etherlab} sous forme d'archive tar. + +\item La r\'evision de d\'eveloppement la plus r\'ecente (mais aussi + n'importe quelle autre r\'evision) peut \^etre obtenue via le + d\'ep\^ot Git~\cite{git} sur la page du projet sur + GitLab.com\footnote{\url{https://gitlab.com/etherlab.org/ethercat}}. + L'int\'egralit\'e du d\'epot peut \^etre clon\'ee avec la commande + +\begin{lstlisting}[breaklines=true] + git clone https://gitlab.com/etherlab.org/ethercat.git `\textit{local-dir}` +\end{lstlisting} + +\item Sans installation locale de Git, des archives tar de + r\'evisions arbitraires peuvent \^etre t\'el\'echarg\'ees via le + bouton ``Download`` sur GitLab. + +\end{enumerate} + +\section{Construction du logiciel} + +Apr\`es le t\'el\'echargement d'une archive tar ou le clonage du +d\'ep\^ot tel que d\'ecrit dans la \autoref{sec:getting}, les sources +doivent \^etre pr\'epar\'ees et configur\'ees pour le processus de +construction. + +Si une archive tar a \'et\'e t\'el\'echarg\'ee, elle doit \^etre +extraite avec les commandes suivantes: + +\begin{lstlisting}[gobble=2] + $ `\textbf{tar xjf ethercat-\masterversion.tar.bz2}` + $ `\textbf{cd ethercat-\masterversion/}` +\end{lstlisting} + +La configuration du logiciel est g\'er\'ee avec +Autoconf~\cite{autoconf} aussi les versions publi\'ees contiennent un +script shell \lstinline+configure+, qui doit \^etre +ex\'ecut\'e pour la configuration (voir ci-dessous). + + \paragraph{Amorcage} Lors d'un t\'el\'echargement ou clonage + direct du d\'ep\^ot, le script \lstinline+configure+ n'existe pas + encore. Il peut \^etre cr\'e\'e via le script + \lstinline+bootstrap.sh+ dans les sources du ma\^itre. Les paquets + autoconf et automake sont alors n\'ecessaires. + + \paragraph{Configuration et construction} La configuration + et le processus de construction suivent dans les commandes + ci-dessous: + +\begin{lstlisting}[gobble=2] + $ `\textbf{./configure}` + $ `\textbf{make}` + $ `\textbf{make modules}` +\end{lstlisting} + +\autoref{tab:config} liste les commutateurs importants de +configuration et les options: + +\begin{longtable}{l|p{.4\textwidth}|l} + \caption{Options de configuration}\rule[-5ex]{0mm}{0mm} + \label{tab:config}\\ + +\textbf{Option/Commutateur} & \textbf{Description} & +\textbf{D\'efaut}\\\hline \endfirsthead + +\textbf{Option/Commutateur} & \textbf{Description} & +\textbf{D\'efaut}\\\hline \endhead + +\lstinline+--prefix+ & Pr\'efixe d'installation & +\textit{/opt/etherlab}\\ + +\lstinline+--with-linux-dir+ & Sources du noyau Linux & Utilise le +noyau actuel \\ + +\lstinline+--with-module-dir+ & Sous-dossier dans l'arbre des modules +du noyau dans lequel les modules noyaux EtherCAT doivent \^etre +install\'es. & \textit{ethercat}\\ + +\hline + +\lstinline+--enable-generic+ & Construire le pilote Ethernet +g\'en\'erique (voir \autoref{sec:generic-driver}). & oui\\ + +\lstinline+--enable-8139too+ & Construire le pilote 8139too & oui\\ + +\lstinline+--with-8139too-kernel+ & noyau 8139too & $\dagger$\\ + +\lstinline+--enable-e100+ & Construire le pilote e100 driver & non\\ + +\lstinline+--with-e100-kernel+ & e100 noyau & $\dagger$\\ + +\lstinline+--enable-e1000+ & Activer le pilote e1000 & non\\ + +\lstinline+--with-e1000-kernel+ & noyau e1000 & $\dagger$\\ + +\lstinline+--enable-e1000e+ & Activer le pilote e1000e & non\\ + +\lstinline+--with-e1000e-kernel+ & noyau e1000e & $\dagger$\\ + +\lstinline+--enable-r8169+ & Activer le pilote r8169 & non\\ + +\lstinline+--with-r8169-kernel+ & noyau r8169 & $\dagger$\\ + +\lstinline+--enable-ccat+ & Activer le pilote ccat (ind\'ependant de +la version du noyau) & non\\ + +\lstinline+--enable-igb+ & Activer le pilote igb & non\\ + +\lstinline+--with-igb-kernel+ & noyau igb & $\dagger$\\ + +\hline + +\lstinline+--enable-kernel+ & Construire les modules noyau du ma\^itre +& oui\\ + +\lstinline+--enable-rtdm+ & Cr\'eer l'interface RTDM (Le dossier RTAI +ou Xenomai est requis, voir ci-dessous) & non\\ + +\lstinline+--with-rtai-dir+ & Chemin RTAI (pour les exemples RTAI et +interface RTDM) & \\ + +\lstinline+--with-xenomai-dir+ & Chemin Xenomai (pour les exemples +Xenomai et interface RTDM) & \\ + +\lstinline+--with-devices+ & Nombre de p\'eriph\'eriques Ethernet pour +l'op\'eration redondante ($>1$ commute la redondance) & 1\\ + +\lstinline+--enable-debug-if+ & Cr\'eer une interface de d\'everminage pour +chaque ma\^itre & non\\ + +\lstinline+--enable-debug-ring+ & Cr\'eer un anneau de d\'everminage pour +enregistrer les trames & non\\ + +\lstinline+--enable-eoe+ & Activer le support EoE & oui\\ + +\lstinline+--enable-cycles+ & Utiliser le compteur d'horodatage du +processeur. Activez ceci sur les architectures Intel pour un meilleur +calcul des timings. & non\\ + +\lstinline+--enable-hrtimer+ & Utiliser un minuteur haute-r\'esolution +pour laisser dormir l'automate du ma\^itre entre l'envoi des trames. & +non\\ + +\lstinline+--enable-regalias+ & Lire les alias d'adresses depuis le +registre & non\\ + +\lstinline+--enable-tool+ & Construire l'outil en ligne de commande +``ethercat'' (voir \autoref{sec:tool}) & oui\\ + +\lstinline+--enable-userlib+ & Construire la biblioth\`eque pour +l'espace utilisateur & oui\\ + +\lstinline+--enable-tty+ & Construire le pilote TTY & non\\ + +\lstinline+--enable-wildcards+ & Activer \textit{0xffffffff} pour \^etre +un jocker pour l'identifiant de fabricant et le code produit & non\\ + +\lstinline+--enable-sii-assign+ & Activer l'assignation de l'acc\`es SII +\`a la couche PDI pendant la configuration de l'esclave & non\\ + +\lstinline+--enable-rt-syslog+ & Activer les instructions syslog dans +le contexte temps r\'eel & yes\\ + +\hline + +\end{longtable} + +\begin{description} + +\item[$\dagger$] Si cette option n'est pas sp\'ecifi\'ee, la version du noyau + \`a utiliser est extraite des sources du noyau Linux. + +\end{description} + +\section{Construction de la documentation de l'interface} +\label{sec:gendoc} + +Le code source est document\'e avec +Doxygen~\cite{doxygen}. Pour construire la documentation HTML, +le logiciel the Doxygen doit \^etre install\'e. La commande ci-dessous +g\'en\`ere les documents dans le sous-dossier \textit{doxygen-output}: + +\begin{lstlisting} +$ `\textbf{make doc}` +\end{lstlisting} + +La documentation de l'interface peut \^etre consult\'ee en ouvrant avec +un navigateur web le fichier \textit{doxygen-output/html/index.html}. +Les fonctions et structures de donn\'ees de l'application sont couvertes +par leur propre module ``Application Interface''. + +\section{Installation du logiciel} + +Les commandes ci-dessous doivent \^etre entr\'ees en tant que +\textit{root}: la premi\`ere installe l'ent\^ete EtherCAT, le script +d'initialisation, le fichier sysconfig et l'outil en espace +utilisateur dans le chemin du pr\'efixe. La deuxi\`eme installe les +modules noyaux dans le dossier des modules du noyau. L'appel final +\`a \lstinline+depmod+ est n\'ecessaire pour inclure les modules +noyaux dans le fichier \textit{modules.dep} pour permettre de les +utiliser avec la commande \lstinline+modprobe+, qui se trouve dans le +script d'initialisation. + +\begin{lstlisting} +# `\textbf{make install}` +# `\textbf{make modules\_install}` +\end{lstlisting} + +Si le dossier de destination des modules noyaux ne se trouve dans +\textit{/lib/modules}, un dossier de destination diff\'erent peut \^etre +sp\'ecifi\'e avec la variable make \lstinline+DESTDIR+. Par exemple: + +\begin{lstlisting} +# `\textbf{make DESTDIR=/vol/nfs/root modules\_install}` +\end{lstlisting} + +Ce commande installe les modules noyaux compil\'es dans +\textit{/vol/nfs/root/lib/modules}, auquel on ajoute la version du +noyau. + +Si le ma\^itre EtherCAT doit s'ex\'ecuter en tant que +service\footnote{ m\^eme si le ma\^itre EtherCAT ne doit pas \^etre + charg\'e au d\'emarrage, l'utilisation du script d'initialisation + est recommand\'e pour le (d\'e-)chargement manuel.} (voir +\autoref{sec:system}), le script d'initialisation et le fichier +sysconfig (ou le fichier de service systemd, respectivement) doivent +\^etre copi\'es (ou li\'e) dans les emplacements appropri\'es. +L'exemple ci-dessous convient pour SUSE Linux. Il peut \^etre +diff\'erent pour les autres distributions. + +% FIXME relative ln -s? +\begin{lstlisting} +# `\textbf{cd /opt/etherlab}` +# `\textbf{cp etc/sysconfig/ethercat /etc/sysconfig/}` +# `\textbf{ln -s etc/init.d/ethercat /etc/init.d/}` +# `\textbf{insserv ethercat}` +\end{lstlisting} + +Maintenant le fichier de configuration +\texttt{/etc/sysconfig/ethercat} (voir \autoref{sec:sysconfig}) ou +\textit{/etc/ethercat.conf} si on utilise systemd, doit \^etre +personnalis\'e. La personnalisation minimale consiste \`a d\'efinir +la variable \lstinline+MASTER0_DEVICE+ avec l'adresse MAC du +p\'eriph\'erique Ethernet \`a utiliser (ou +\lstinline+ff:ff:ff:ff:ff:ff+ pour utiliser le premier +p\'eriph\'erique offert) et \`a s\'electionner le(s) pilote(s) \`a +charger via la variable \lstinline+DEVICE_MODULES+. + +Apr\`es que la d\'efinition de la configuration de base, le ma\^itre +peut \^etre d\'emarr\'e avec la commande ci-dessous: + +\begin{lstlisting} +# `\textbf{/etc/init.d/ethercat start}` +\end{lstlisting} + +Lorsqu'on utilise systemd, la commande suivante peut \^etre utilis\'ee +\`a la place: + +\begin{lstlisting} +# `\textbf{ethercatctl start}` +\end{lstlisting} + +A partir de cet instant, l'op\'eration du ma\^itre peut \^etre oberv\'ee +en consultant les messages Syslog\index{Syslog}, qui ressemblent \`a +ceux qui sont ci-dessous. Si des esclaves EtherCAT sont connect\'es +au p\'eriph\'erique du ma\^itre EtherCAT, les indicateurs d'activit\'e +devraient commencer \`a clignoter. + +\begin{lstlisting}[numbers=left] +EtherCAT: Master driver `\masterversion` +EtherCAT: 1 master waiting for devices. +EtherCAT Intel(R) PRO/1000 Network Driver - version 6.0.60-k2 +Copyright (c) 1999-2005 Intel Corporation. +PCI: Found IRQ 12 for device 0000:01:01.0 +PCI: Sharing IRQ 12 with 0000:00:1d.2 +PCI: Sharing IRQ 12 with 0000:00:1f.1 +EtherCAT: Accepting device 00:0E:0C:DA:A2:20 for master 0. +EtherCAT: Starting master thread. +ec_e1000: ec0: e1000_probe: Intel(R) PRO/1000 Network + Connection +ec_e1000: ec0: e1000_watchdog_task: NIC Link is Up 100 Mbps + Full Duplex +EtherCAT: Link state changed to UP. +EtherCAT: 7 slave(s) responding. +EtherCAT: Slave states: PREOP. +EtherCAT: Scanning bus. +EtherCAT: Bus scanning completed in 431 ms. +\end{lstlisting} + +\begin{description} + +\item[\linenum{1} -- \linenum{2}] Le module ma\^itre est en train de charger , et un ma\^itre est initialis\'e. + +\item[\linenum{3} -- \linenum{8}] Le pilote e1000 compatible EtherCAT + est en train de charger. Le ma\^itre accepte le p\'eriph\'erique avec + l'adresse \lstinline+00:0E:0C:DA:A2:20+. + +\item[\linenum{9} -- \linenum{16}] Le ma\^itre entre en phase de repos, + d\'emarre son automate et commence \`a analyser le bus. + +\end{description} + +\section{Cr\'eation automatique des n\oe{}uds de p\'eriph\'eriques} +\label{sec:autonode} + +L'outil en ligne de commande \lstinline+ethercat+ (voir +\autoref{sec:tool}) communique avec le ma\^itre via le +p\'eriph\'erique en mode caract\`ere. Les n\oe{}uds de +p\'eriph\'eriques correspondants sont cr\'e\'es automatiquement, si le +service udev est en cours de fonctionnement. Veuillez noter, que pour +certaines distributions, le paquet \lstinline+udev+ n'est pas +install\'e par d\'efaut. + +Les n\oe{}uds de p\'eriph\'eriques seront cr\'e\'es avec le mode +\lstinline+0660+ et le groupe \lstinline+root+ par d\'efaut. Si des +utilisateurs ``normaux'' doivent avoir un acc\`es en lecture, un +fichier de r\`egle udev (par exemple +\textit{/etc/udev/rules.d/99-EtherCAT.rules}) doit \^etre cr\'e\'e +avec le contenu suivant: + + +\begin{lstlisting} +KERNEL=="EtherCAT[0-9]*", MODE="0664" +\end{lstlisting} + +Apr\`es la cr\'eation du fichier de r\`egles udev et le red\'emarrage +du ma\^itre EtherCAT avec +\lstinline[breaklines=true]+/etc/init.d/ethercat restart+, le n\oe{}ud +de p\'eriph\'erique est automatiquement cr\'e\'e avec les bons droits: + +\begin{lstlisting} +# `\textbf{ls -l /dev/EtherCAT0}` +crw-rw-r-- 1 root root 252, 0 2008-09-03 16:19 /dev/EtherCAT0 +\end{lstlisting} + +Maintenant, l'outil \lstinline+ethercat+ peut \^etre utilis\'e (voir +\autoref{sec:tool}) par un utilisateur non-root. + +Si les utilisateurs non-root doivent avoir l'acc\`es en \'ecriture, on +peut utiliser la r\`egle udev suivante \`a la place: + +\begin{lstlisting} +KERNEL=="EtherCAT[0-9]*", MODE="0664", GROUP="users" +\end{lstlisting} + +%------------------------------------------------------------------------------ + +\begin{thebibliography}{99} + +\bibitem{etherlab} Ingenieurgemeinschaft IgH: EtherLab -- Open Source Toolkit +for rapid realtime code generation under Linux with Simulink/RTW and EtherCAT +technology. \url{http://etherlab.org/en}, 2008. + +\bibitem{dlspec} IEC 61158-4-12: Data-link Protocol Specification. +International Electrotechnical Commission (IEC), 2005. + +\bibitem{alspec} IEC 61158-6-12: Application Layer Protocol Specification. +International Electrotechnical Commission (IEC), 2005. + +\bibitem{gpl} GNU General Public License, Version 2. +\url{http://www.gnu.org/licenses/gpl-2.0.html}. October~15, 2008. + +\bibitem{lgpl} GNU Lesser General Public License, Version 2.1. +\url{http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html}. October~15, +2008. + +\bibitem{lsb} Linux Standard Base. +\url{http://www.linuxfoundation.org/en/LSB}. August~9, 2006. + +\bibitem{systemd} systemd System and Service Manager +\url{http://freedesktop.org/wiki/Software/systemd}. January~18, 2013. + +\bibitem{wireshark} Wireshark. \url{http://www.wireshark.org}. 2008. + +\bibitem{automata} {\it Hopcroft, J.\,E.\ / Ullman, J.\,D.}: Introduction to +Automata Theory, Languages and Computation. Adison-Wesley, Reading, +Mass.~1979. + +\bibitem{fsmmis} {\it Wagner, F.\ / Wolstenholme, P.}: State machine +misunderstandings. In: IEE journal ``Computing and Control Engineering'', +2004. + +\bibitem{rtai} RTAI. The RealTime Application Interface for Linux from DIAPM. +\url{https://www.rtai.org}, 2010. + +\bibitem{rt-preempt} RT PREEMPT HOWTO. +\url{http://rt.wiki.kernel.org/index.php/RT_PREEMPT_HOWTO}, 2010. + +\bibitem{doxygen} Doxygen. Source code documentation generator tool. +\url{http://www.stack.nl/~dimitri/doxygen}, 2008. + +\bibitem{git} Git SCM. \url{https://git-scm.com}, 2021. + +\bibitem{autoconf} Autoconf -- GNU Project -- Free Software Foundation (FSF). +\url{http://www.gnu.org/software/autoconf}, 2010. + +\bibitem{soespec} IEC 61800-7-304: Adjustable speed electrical power drive +systems - Part 7-300: Generic interface and use of profiles for power drive +systems - Mapping of profiles to network technologies. International +Electrotechnical Commission (IEC), 2007. + +\bibitem{rtdm} {\it J. Kiszka}: The Real-Time Driver Model and First +Applications. +\url{http://svn.gna.org/svn/xenomai/tags/v2.4.0/doc/nodist/pdf/RTDM-and-Applications.pdf}, +2013. + +\end{thebibliography} + +\printnomenclature +\addcontentsline{toc}{chapter}{\nomname} +\markleft{\nomname} + +\printindex +\markleft{Index} + +%------------------------------------------------------------------------------ + +\end{document} + +%------------------------------------------------------------------------------ From 1d65f6617fc0e02a4b0569c932485bfc798994f3 Mon Sep 17 00:00:00 2001 From: Nicola Fontana Date: Sat, 22 May 2021 07:22:57 +0200 Subject: [PATCH 12/14] Proper systemd support Follow the directions on integrating systemd with autotools provided by the systemd documentation itself: https://www.freedesktop.org/software/systemd/man/daemon.html#Installing%20systemd%20Service%20Files The snippet has been adapted to better match our coding style, e.g. directly use of `if` instead of `AS_IF`. --- Makefile.am | 3 +++ configure.ac | 30 ++++++++++++++++++++++++++++++ script/Makefile.am | 7 ++++--- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/Makefile.am b/Makefile.am index 8a8a8fcd..288f86ed 100644 --- a/Makefile.am +++ b/Makefile.am @@ -29,6 +29,9 @@ ACLOCAL_AMFLAGS = -I m4 +AM_DISTCHECK_CONFIGURE_FLAGS = \ + --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) + SUBDIRS = \ include \ script diff --git a/configure.ac b/configure.ac index e9517115..b19992cf 100644 --- a/configure.ac +++ b/configure.ac @@ -45,6 +45,7 @@ AM_INIT_AUTOMAKE([-Wall -Werror dist-bzip2 subdir-objects]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([config.h.in]) AC_CONFIG_MACRO_DIR([m4]) +PKG_PROG_PKG_CONFIG PKG_INSTALLDIR() #------------------------------------------------------------------------------ @@ -1078,6 +1079,35 @@ else AC_MSG_RESULT([no]) fi +#------------------------------------------------------------------------------ +# systemd service support +#------------------------------------------------------------------------------ + +AC_ARG_WITH([systemdsystemunitdir], + AS_HELP_STRING([--with-systemdsystemunitdir=DIR], + [Directory for systemd service files]), + , + [with_systemdsystemunitdir=auto] +) + +case "${with_systemdsystemunitdir}" in + yes) + with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd) + if test "x$with_systemdsystemunitdir" = "x"; then + AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package]) + fi + ;; + no) + with_systemdsystemunitdir= + ;; + auto) + with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd) + ;; +esac + +AM_CONDITIONAL(HAVE_SYSTEMD, test "x$with_systemdsystemunitdir" != "x") +AC_SUBST(systemdsystemunitdir,[$with_systemdsystemunitdir]) + #------------------------------------------------------------------------------ AC_CONFIG_FILES([ diff --git a/script/Makefile.am b/script/Makefile.am index 419a024f..b3483f15 100644 --- a/script/Makefile.am +++ b/script/Makefile.am @@ -35,9 +35,6 @@ SUBDIRS = init.d sysconfig sbin_SCRIPTS = ethercatctl -systemddir = $(libdir)/systemd/system -systemd_DATA = ethercat.service - dist_sysconf_DATA = ethercat.conf EXTRA_DIST = \ @@ -49,4 +46,8 @@ BUILT_SOURCES = \ ethercatctl \ ethercat.service +if HAVE_SYSTEMD +systemdsystemunit_DATA = ethercat.service +endif + #------------------------------------------------------------------------------ From 2a5529a8e91d1cdf1fb8bca07db2fd89286c9492 Mon Sep 17 00:00:00 2001 From: Nicola Fontana Date: Sat, 22 May 2021 07:37:10 +0200 Subject: [PATCH 13/14] Ignore generated libethercat.pc in git --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c0ebf884..0ab6798e 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ ethercat.spec examples/dc_user/ec_dc_user_example examples/user/ec_user_example lib/libethercat.la +lib/libethercat.pc libtool master/*.o.d script/ethercat.service From 301f3e34b1664219d328ad01697b0f47868e8895 Mon Sep 17 00:00:00 2001 From: Florian Pose Date: Tue, 25 May 2021 11:37:52 +0200 Subject: [PATCH 14/14] Added systemd directory switch to docs. --- documentation/ethercat_doc.tex | 4 ++++ documentation/ethercat_doc_fr.tex | 2 ++ 2 files changed, 6 insertions(+) diff --git a/documentation/ethercat_doc.tex b/documentation/ethercat_doc.tex index 2e10b0a0..cef4468d 100644 --- a/documentation/ethercat_doc.tex +++ b/documentation/ethercat_doc.tex @@ -3165,6 +3165,10 @@ interface) & \\ \lstinline+--with-devices+ & Number of Ethernet devices for redundant operation ($>1$ switches redundancy on) & 1\\ +\lstinline+--with-systemdsystemunitdir+ & Systemd unit directory ("no" +disables service file installation) +& auto \\ + \lstinline+--enable-debug-if+ & Create a debug interface for each master & no\\ \lstinline+--enable-debug-ring+ & Create a debug ring to record frames & no\\ diff --git a/documentation/ethercat_doc_fr.tex b/documentation/ethercat_doc_fr.tex index 9d19e7bd..d9126bf9 100644 --- a/documentation/ethercat_doc_fr.tex +++ b/documentation/ethercat_doc_fr.tex @@ -3577,6 +3577,8 @@ Xenomai et interface RTDM) & \\ \lstinline+--with-devices+ & Nombre de p\'eriph\'eriques Ethernet pour l'op\'eration redondante ($>1$ commute la redondance) & 1\\ +\lstinline+--with-systemdsystemunitdir+ & Chemin Systemd & auto \\ + \lstinline+--enable-debug-if+ & Cr\'eer une interface de d\'everminage pour chaque ma\^itre & non\\