mirror of
https://gitlab.com/etherlab.org/ethercat.git
synced 2025-12-10 01:41:10 +08:00
3865 lines
151 KiB
TeX
3865 lines
151 KiB
TeX
%------------------------------------------------------------------------------
|
|
%
|
|
% IgH EtherCAT Master Documentation (French version)
|
|
%
|
|
% vi: spell spelllang=fr tw=78
|
|
%
|
|
%------------------------------------------------------------------------------
|
|
|
|
\documentclass[a4paper,12pt,BCOR=6mm,bibtotoc,idxtotoc]{scrbook}
|
|
|
|
\usepackage[utf8]{inputenc}
|
|
\usepackage[automark,headsepline]{scrlayer-scrpage}
|
|
\usepackage[french]{babel}
|
|
\usepackage{graphicx}
|
|
\usepackage{makeidx}
|
|
\usepackage[refpage]{nomencl}
|
|
\usepackage{listings}
|
|
\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}{\subsubsectionnumdepth}
|
|
|
|
\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}}}
|
|
|
|
\input{git}
|
|
|
|
\newcommand{\masterversion}{1.5.2}
|
|
\newcommand{\linenum}[1]{\normalfont\textcircled{\tiny #1}}
|
|
|
|
\makeindex
|
|
\makenomenclature
|
|
|
|
% Revision and date on inner footer
|
|
\ifoot[\scriptsize\gitversion, \today]
|
|
{\scriptsize\gitversion, \today}
|
|
|
|
%------------------------------------------------------------------------------
|
|
|
|
\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, \today\\[1ex]
|
|
R\'evision \gitversion}
|
|
|
|
\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 <ecrt.h>
|
|
|
|
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: <LOOPBACK,UP> mtu 16436 qdisc noqueue
|
|
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
|
|
4: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
|
|
link/ether 00:13:46:3b:ad:d7 brd ff:ff:ff:ff:ff:ff
|
|
8: ecdbgm0: <BROADCAST,MULTICAST> 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{https://etherlab.org/ethercat}}
|
|
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+--with-systemdsystemunitdir+ & Chemin Systemd & auto \\
|
|
|
|
\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{https://etherlab.org}, 2024.
|
|
|
|
\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}
|
|
|
|
%------------------------------------------------------------------------------
|