Browse Source

mise a jour guide et code

PE Hladik 5 years ago
parent
commit
38f3f57f4e

+ 48
- 228
doc/sujets/tex/guide_compilation/guide.tex View File

102
 {\scriptsize Institut National des Sciences Appliquées de Toulouse}\\
102
 {\scriptsize Institut National des Sciences Appliquées de Toulouse}\\
103
 ---\\
103
 ---\\
104
 Guide des outils de développement \\
104
 Guide des outils de développement \\
105
-{\large Version 1.0.$\beta$ (\today)}\\
105
+{\large Version 1.0.1 (\today)}\\
106
 {\scriptsize Référent pédagogique : P.-E. Hladik (\texttt{pehladik@insa-toulouse.fr})}\\
106
 {\scriptsize Référent pédagogique : P.-E. Hladik (\texttt{pehladik@insa-toulouse.fr})}\\
107
 {\scriptsize Référents plateforme : S. Di Mercurio (\texttt{dimercur@insa-toulouse.fr})}\\
107
 {\scriptsize Référents plateforme : S. Di Mercurio (\texttt{dimercur@insa-toulouse.fr})}\\
108
 ---
108
 ---
120
 \label{sec:git}
120
 \label{sec:git}
121
 %%%%%%%%%%%%%%%%%%%%
121
 %%%%%%%%%%%%%%%%%%%%
122
 
122
 
123
-Le code du projet est disponible sur un dépôt git hébergé sur GitHub. Pour le récupérer, placer vous le répertoire cible et exécuter la commande\\ \indent\indent {\tt git clone https://github.com/INSA-GEI/dumber.git}
123
+Le code du projet est disponible sur un dépôt git hébergé sur GitHub. Pour le récupérer, placer vous le répertoire cible et exécuter la commande\\ \indent\indent {\tt git clone https://github.com/INSA-GEI/dumber.git}\\
124
 
124
 
125
-Il vous faut ensuite changer de branche, pour cela allez dans le répertoire {\tt dumber} puis exécuter la commande\\ \indent\indent {\tt git checkout stable}
126
- 
127
 Tout le code relatif au projet est disponible, cependant vous n'aurez besoin que des codes présents dans les répertoires :
125
 Tout le code relatif au projet est disponible, cependant vous n'aurez besoin que des codes présents dans les répertoires :
128
 \begin{itemize}
126
 \begin{itemize}
129
-	\item {\tt ./dumber/software/raspberry}
130
-	\item {\tt ./dumber/software/monitor/monitor}
131
-\end{itemize}
132
-
133
- \todo[inline]{Mettre à jour la suite en fonction du projet initial}
134
-  
135
- Vous aurez alors un répertoire {\tt ./dumber/software} dans lequel vous trouverez les répertoires:
136
- \begin{itemize}
137
-\item {\tt /src} avec le codes des librairies du projet,
138
-\item {\tt /destijl\_init} avec le codes correspondant au projet initial,
139
-\item {\tt /example} avec des codes d'exemple pour utiliser les librairies (attention ce n'est pas à jour).\\
127
+	\item {\tt ./dumber/software/raspberry/superviseur-robot} : ce répertoire contient un projet Netbeans avec l'ensemble du code source pour le projet initial,
128
+	\item {\tt ./dumber/software/monitor/monitor} : ce répertoire contient un projet Mono contenant l'ensemble du code source pour le moniteur.\\
140
 \end{itemize}
129
 \end{itemize}
141
 
130
 
142
-
143
-Le code du projet initial est constitué des fichiers suivants :
131
+Le répertoire {\tt superviseur-robot} est constitué des fichiers suivants :
144
 \begin{itemize}
132
 \begin{itemize}
145
-\item {\tt /destijl\_init/main.cpp} qui contient le main de l'application et les fonctions de création des objets (tâches, sémaphores, mutex, etc.) de l'architecture logicielle,
146
-\item {\tt /destijl\_init/src/functions.cpp} qui contient l'implémentation des fonctions,
147
-\item {\tt /destijl\_init/src/functions.h} qui contient l'entête des différentes fonctions.\\
133
+\item {\tt /destijl\_init/main.cpp} qui contient le main de l'application et lance la création des objets et leur exécution,
134
+\item {\tt /destijl\_init/src/tasks.h} qui contient l'entête des différentes fonctions,
135
+\item {\tt /destijl\_init/src/tasks.cpp} qui contient l'implémentation des fonctions de création des objets (tâches, sémaphores, mutex, etc.) ainsi que les fonction de traitement.
148
 \end{itemize}
136
 \end{itemize}
149
 
137
 
150
-A cela s'ajoute un fichier {\tt Makefile} disponible dans {\tt /destijl\_init} qui permet de compiler le projet initial sur une \raspi.
151
-
152
-
153
-%%%%%%%%%%%%%%%%%%%%
154
-\section{Mise en place d'un terminal distant sur la \raspi}
155
-\label{sec:ssh}
156
-%%%%%%%%%%%%%%%%%%%%
157
-
158
-Pour se connecter à la \raspi, vous aurez besoin de créer un accès via ssh. Pour cela, depuis un PC d'une salle informatique utilisez la commande :\\ \indent\indent{\tt ssh pi@10.105.1.x}\\
159
-avec {\tt x} le numéro sur le boitier de la \raspi.
160
-
161
-Le mot de passe est : insa.
162
-
163
-%%%%%%%%%%%%%%%%%%%%
164
-\section{Exécution du superviseur}
165
-\label{sec:utilisation}
166
-%%%%%%%%%%%%%%%%%%%%
167
-
168
-Pour exécuter l'application sur le superviseur, il faut après avoir mis en place un terminal distant puis démarrer l'exécution avec la commande {\tt sudo ./path/app} où {\tt path} est le chemin du répertoire où se trouve l'application et {\tt app} est le nom de votre application. Attention les droits {\tt sudo} sont nécessaires pour des questions d'accès à certains services Xenomai de gestion de la mémoire.
169
 
138
 
170
-%%%%%%%%%%%%%%%%%%%%
171
-\section{Exécution du moniteur}
172
-\label{sec:utilisation}
173
-%%%%%%%%%%%%%%%%%%%%
174
-
175
-L'exécution du moniteur se fait...
176
-\todo[inline]{Faire cette partie}
177
 
139
 
178
 
140
 
179
 %%%%%%%%%%%%%%%%%%%%
141
 %%%%%%%%%%%%%%%%%%%%
180
-\section{Développement d'une application distante}
142
+\section{Compilation d'une application distante}
181
 %%%%%%%%%%%%%%%%%%%%
143
 %%%%%%%%%%%%%%%%%%%%
182
 
144
 
183
-L'application étant sur une \raspi, il vous faut compiler le programme pour cette architecture. Pour faire cela, le plus simple est de compiler le code directement sur la cible à l'aide du {\tt Makefile}. Le problème est alors de choisir comment vous allez éditer le code. Il y a trois solutions envisagées :
184
-\begin{enumerate}
185
-\item édition locale et compilation distante manuelle : fatigant à la longue, il vaut mieux faire de scripts pour automatiser tout cela,
186
-\item édition locale et compilation distante avec netbeans : un peu laborieux à configurer, mais agréable ensuite,
187
-\item édition et compilation distante : mauvaise idée.
188
-\end{enumerate}
189
-Toutes ces solutions sont détaillées dans la suite.
190
-
191
-%%%%%%%%%%%%%%%%%%%%
192
-\subsection{Développement d'une application distante : édition locale et compilation distante manuelle}
193
-%%%%%%%%%%%%%%%%%%%%
194
-
195
-Cette solution consiste à éditer le code en local sur un PC et de faire la compilation distante sur la \raspi. Cela suppose donc de copier le code du PC sur la \raspi avant chaque compilation, puis de lancer la compilation (figure~\ref{fig:edition2}).
196
-
197
-\begin{figure}[htbp]
198
-\begin{center}
199
-\includegraphics[scale=0.5]{./figures-pdf/edition2}
200
-\caption{Edition locale et compilation distante}
201
-\label{fig:edition2}
202
-\end{center}
203
-\end{figure}
204
-
205
-Les étapes à suivre sont alors :
206
-\begin{enumerate}
207
-\item récupérer le code du dépôt (voir section~\ref{sec:git}) sur le PC,
208
- \item éditer le code avec l'outil que vous préférez,
209
- \item copier le code du PC vers la \raspi en utilisant la commande {\tt sftp} (voir ci-dessous),
210
-\item se connecter de manière distante à la \raspi via ssh (voir section~\ref{sec:ssh}),
211
- \item compiler avec la commande {\tt make} à l'aide du {\tt Makefile} (qu'il faudra aussi avoir copié sur la \raspi),
212
- \item lancer l'exécutable par la commande {\tt sudo ./superviseur} (voir section ~\ref{sec:utilisation}).
213
- \end{enumerate}
214
-
215
-
216
-\paragraph{Copie distante de fichiers :}
217
-Il est possible d'utiliser {\tt sftp} pour copier un fichier d'une machine sur une autre. Pour cela, en se plaçant dans le répertoire où se trouve le fichier à copier, il faut exécuter les commandes suivantes :
218
-\\ \indent\indent{\tt sftp pi@10.105.1.x} avec {\tt x} le numéro de la \raspi (mot de passe {\tt insa}),
219
-\\ \indent\indent{\tt sftp > put file} avec {\tt file} le nom du fichier à copier,
220
-\\ \indent\indent{\tt sftp > bye} pour quitter sftp.
221
-
222
-
223
-%%%%%%%%%%%%%%%%%%%%
224
-\subsection{Développement d'une application distante : édition locale et compilation distante (version Netbeans)}
225
-%%%%%%%%%%%%%%%%%%%%
226
-
227
-Cette deuxième solution applique le même schéma que précédemment (édition locale du code et compilation distante) mais en utilisant Netbeans comme IDE (figure~\ref{fig:edition2b}).
228
-
229
-\begin{figure}[htbp]
230
-\begin{center}
231
-\includegraphics[scale=0.5]{./figures-pdf/edition2b}
232
-\caption{Edition locale et compilation distante avec Netbeans}
233
-\label{fig:edition2b}
234
-\end{center}
235
-\end{figure}
236
-
237
-Cette solution peut sembler longue, mais une fois la configuration réalisée il en restera plus qu'à lancer les éléments automatiquement.
238
-
239
-Les principales étapes sont :
240
-\begin{enumerate}
241
-\item éditer le code sur Netbeans,
242
-\item lancer la compilation distante depuis Netbeans qui se chargera de copier les fichiers distants et de les compiler,
243
-\item lancer un terminal depuis Netbeans,
244
-\item exécuter le programme.
245
-\end{enumerate}
246
-
247
-\subsubsection{Récupérer le code}
248
-
249
-Copiez localement (sur le PC) le dépôt git (voir section~\ref{sec:git}).
250
-
251
-\todo[inline]{Mettre à jour en fonction du dépot}
252
-
253
-\framebox[\textwidth]{
254
-\begin{minipage}{0.9\textwidth}
255
-Le projet initial est livré avec un projet Netbeans déjà configuré. Vous pouvez simplement l'ouvrir depuis... Il vous faudra ensuite simplement reconfigurer la cible en suivant les étapes présentées dans la section~\ref{sec:cible}.
256
-\end{minipage}
257
-}
258
-
259
-
260
-\subsubsection{Créer un projet Netbeans}
261
-
262
-\begin{enumerate}
263
-\item Lancez Netbeans,
264
-\item Allez dans {\tt File->new project},
265
-\item Choisir {\tt C/C++} pour {\tt categories}, puis {\tt C/C++ Application},
266
-\item Cliquez Next
267
-\item Donner un nom au projet (ce sera par défaut le nom de votre exécutable),
268
-\item Décocher {\tt Create main file},
269
-\item cliquez sur  {\tt Finish},
270
-\end{enumerate}
271
-
272
-\subsubsection{Importer le code dans le projet}
273
-
274
-\begin{enumerate}
275
-\item Cliquez droit sur votre projet et choisissez {\tt Add existing items from Folders...},
276
-\item puis {\tt Add Folder... } et allez chercher les répertoires que vous avez importé depuis github :
277
-\begin{itemize}
278
-\item {\tt superviseur\_robot/destijl\_init},
279
-\item {\tt superviseur\_robot/src},
280
-\end{itemize}
281
-\item Cliquez {\tt Add}.
282
-\end{enumerate}
283
-
284
-Vous pouvez supprimer tous les autres répertoires du projet (clique droit sur les répertoires).
145
+L'application étant sur une \raspi, il vous faut compiler le programme pour cette architecture. Nous vous proposons d'utiliser Netbeans pour écrire votre code et faire la compilation distante. Cela signifie que votre code est stocké sur votre compte INSA, que vous éditer le code sur la machine de TP, que ce code est ensuite automatiquement chargé sur la \raspi puis compilé (Netbeans permet de faire tout cela).
285
 
146
 
286
-\subsubsection{Configurer une compilation distante}
287
-\label{sec:cible}
147
+Pour commencer lancer Netbeans et ouvrez le projet {\tt superviseur-robot}.
288
 
148
 
149
+Avant de compiler, il vous faut configurer la cible sur laquelle la compilation va se faire:
289
 \begin{enumerate}
150
 \begin{enumerate}
290
 \item Cliquez droit sur le projet et choisir {\tt Properties},
151
 \item Cliquez droit sur le projet et choisir {\tt Properties},
291
 \item Allez dans l'onglet {\tt Build},
152
 \item Allez dans l'onglet {\tt Build},
304
 \item Cliquez {\tt OK}.
165
 \item Cliquez {\tt OK}.
305
 \end{enumerate}
166
 \end{enumerate}
306
 
167
 
307
-\subsubsection{Configurer la compilation}
308
-
309
-\begin{enumerate}
310
-\item Cliquez droit sur le projet et choisir {\tt Properties},
311
-\item Allez dans l'onglet {\tt Build->C++ Compiler},
312
-\item Choisir {\tt ...} pour {\tt Additional Options},
313
-\item Copier dans le champ {\tt -D\_GNU\_SOURCE -D\_REENTRANT -fasynchronous-unwind-tables -D\_\_MERCURY\_\_ -I/usr/xenomai/include/alchemy -g -D\_WITH\_TRACE\_ 
314
-
315
--I/usr/xenomai/include/ -I/usr/xenomai/include/mercury -MMD -MP} 
316
-\item Cliquez {\tt OK},
317
-\item Allez dans l'onglet {\tt Build->Linker},
318
-\item Choisir {\tt ...} pour {\tt Additional Options},
319
-\item Copier dans le champ {\tt  -D\_GNU\_SOURCE -D\_REENTRANT -fasynchronous-unwind-tables -D\_\_MERCURY\_\_ -I/usr/xenomai/include/alchemy -L/usr/xenomai/lib -lalchemy 
168
+Pour compiler, il suffit ensuite de cliquer sur l'icône en forme de marteau. Vous pourrez voir dans le terminal les étapes de compilation qui commence par le transfert des fichiers suivi de la compilation proprement dite.
320
 
169
 
321
--lcopperplate -lmercury -L/opt/vc/lib -I/usr/local/include -lopencv\_highgui -lopencv\_core -lopencv\_imgproc -Wl,{-}{-}no-as-needed -lalchemy -lcopperplate 
170
+{\bf Remarque} : la première compilation est un peu longue, mais devrait ensuite se fluidifier avec la compilation incrémentale.
322
 
171
 
323
-/usr/xenomai/lib/xenomai/bootstrap.o -Wl,{-}{-}wrap=main 
324
 
172
 
325
--Wl,{-}{-}dynamic-list=/usr/xenomai/lib/dynlist.ld -L/usr/xenomai/lib -lmercury 
173
+%%%%%%%%%%%%%%%%%%%%
174
+\section{Exécution du superviseur}
175
+\label{sec:utilisation}
176
+%%%%%%%%%%%%%%%%%%%%
326
 
177
 
327
--lpthread -lrt -Wl,-rpath /usr/xenomai/lib -lopencv\_highgui -lopencv\_core 
178
+Pour exécuter l'application sur le superviseur, il faut après avoir mis en place un terminal distant (voir ci-dessous) puis démarrer l'exécution avec la commande {\tt sudo ./path/app} où {\tt path} est le chemin du répertoire où se trouve l'application et {\tt app} est le nom de votre application. Attention les droits {\tt sudo} sont nécessaires pour des questions d'accès à certains services Xenomai de gestion de la mémoire.
328
 
179
 
329
--lopencv\_imgcodecs -lraspicam\_cv -lopencv\_imgproc -lpthread} 
330
-\item Cliquez {\tt OK},
331
-\item Cliquez {\tt Apply},
332
-\item Cliquez {\tt OK}.
333
-\end{enumerate}
180
+Si vous utilisez Netbeans, le répertoire dans lequel est compilée l'application se trouve dans l'arboressence commençant par {\tt .netbeans} (attention au "." au début). Il faut descendre dans cette arboressence jusqu'à une bifurcation, puis choisir le répertoire {\tt dist} et aller jusqu'au bout. L'application se trouve au bout de cette branche.
334
 
181
 
335
-\subsubsection{Tester la compilation}
336
 
182
 
337
-\begin{enumerate}
338
-\item Cliquez sur l'icone \og Marteau \fg ou allez dans {\tt Run->Build Project}.
339
-\end{enumerate}
183
+%%%%%%%%%%%%%%%%%%%%
184
+\section{Mise en place d'un terminal distant avec la \raspi}
185
+\label{sec:ssh}
186
+%%%%%%%%%%%%%%%%%%%%
340
 
187
 
341
-\subsubsection{Configurer l'exécution}
188
+Pour se connecter à la \raspi, vous aurez besoin de créer un accès via ssh. Pour cela, depuis un PC d'une salle informatique utilisez la commande :\\ \indent\indent{\tt ssh pi@10.105.1.x}\\
189
+avec {\tt x} le numéro sur le boitier de la \raspi.
342
 
190
 
343
-\begin{enumerate}
344
-\item Cliquez droit sur le projet et choisir {\tt Properties},
345
-\item Allez dans l'onglet {\tt Run},
346
-\item Remplir le champ {\tt Run Command} avec {\tt sudo "\$\{OUTPUT\_PATH\}"},
347
-\item Remplir le champ {\tt Console Type} avec {\tt Standard Output}.
348
-\end{enumerate}
191
+Le mot de passe est : insa.
349
 
192
 
350
-\subsubsection{Exécuter l'application (directement depuis Netbeans)}
351
-\begin{enumerate}
352
-\item Cliquez sur l'icone \og Play \fg ou allez dans {\tt Run->Build Project}.
353
-\end{enumerate}
354
 
193
 
355
-\subsubsection{Exécuter l'application (avec un terminal)}
356
-\begin{enumerate}
357
-\item Cliquez sur l'icone \og Terminal \fg dans la fenêtre de le console (ou lancer un terminal),
358
-\item Connectez via ssh à la \raspi,
359
-\item allez dans {\tt .netbeans/.../dist/...} avec la commande {\tt cd} pour trouver le résultat de la compilation,
360
-\item lancez l'exécution via {\tt sudo ./app} avec {\tt app} le nom de votre application.
361
-\end{enumerate}
194
+%%%%%%%%%%%%%%%%%%%%
195
+\section{Exécution du moniteur}
196
+\label{sec:utilisation}
197
+%%%%%%%%%%%%%%%%%%%%
362
 
198
 
363
-\subsubsection{Ajouter les header dans le projet Netbeans}
199
+Pour exécuter le moniteur, il suffit depuis votre PC de travail de se placer dans le répertoire {\tt ./dumber/software/monitor/monitor} et de lancer {\tt ./monitor}.
364
 
200
 
365
-\begin{enumerate}
366
-\item Téléchargez les entêtes des services Xenomai depuis \href{https://moodle.insa-toulouse.fr/mod/resource/view.php?id=37439}{moodle},
367
-\item Décompresser l'archive,
368
-\item Cliquez droit sur le projet et choisir {\tt Properties},
369
-\item Allez dans l'onglet {\tt Build->C++ Compiler},
370
-\item Choisir {\tt ...} pour {\tt Include Headers},
371
-\item Cliquez sur {\tt Add},
372
-\item Sélectionner tous les fichiers {\tt .h} de l'archive chargée ({\tt ./include\_xenomai/include}),
373
-\item Cliquez {\tt OK},
374
-\item Cliquez {\tt Apply},
375
-\item Cliquez {\tt OK}.
376
-\end{enumerate}
201
+{\bf Attention} : avant de lancer la première fois l'application, il vous faut ouvrir l'environnement de développement MonoDevelop et ouvrir le projet {\tt ./dumber/software/monitor/monitor}  et l'exécuter (cela recompile le projet et permet de faire les liens avec les librairies de votre PC). Cette étape ne sera plus à faire par la suite.
377
 
202
 
378
-Le service {\tt rt\_task\_create} n'est pas reconnu suite à cette manipulation car il est déclaré à travers une macro qui masque à Netbeans son existence. Le service restera donc souligné en rouge.
379
 
203
 
380
 %%%%%%%%%%%%%%%%%%%%
204
 %%%%%%%%%%%%%%%%%%%%
381
-\subsection{Développement d'une application distante : édition et compilation distantes}
205
+\section{Comprendre la structuration du code}
206
+\label{sec:code}
382
 %%%%%%%%%%%%%%%%%%%%
207
 %%%%%%%%%%%%%%%%%%%%
208
+ L'ensemble du code du projet initial est contenu dans le répertorie {\tt superviseur-robot}. Les bibliothèques de traitement sont disponibles dans le repertoire {\tt lib}. Vous n'aurez pas à modifier ces bibliothèques, par contre vous devrez les utiliser. La documentation est directement écrite dans le code source.
209
+ 
210
+ Les seuls fichiers que vous allez avoir à modifier sont les fichiers {\tt tasks.h} et {\tt tasks.cpp}. La classe {\tt Tasks} a pour attributs privés l'ensemble des structures constituant l'application (tâches, mutex, sémarphores, ressources, etc.). Les fonctions de traitement associées aux tâches sont déclarées comme des méthodes privées de {\tt Tasks}.
211
+ 
212
+ La classe {\tt Tasks} propose quatre méthodes publics :
213
+ \begin{itemize}
214
+ 	\item {\tt Init()} qui crée les structures de l'application,
215
+	\item {\tt Run()} qui lance les tâches,
216
+	\item {\tt Stop()} qui termine les tâches,
217
+	\item {\tt Join()} qui suspend l'exécution du {\tt main}.\\
218
+ \end{itemize}
383
 
219
 
384
-Cette dernière solution est à éviter. Elle consiste à éditer le code directement sur la \raspi et d'y lancer la compilation via un terminal (figure~\ref{fig:edition1}).
385
-
386
-\begin{figure}[htbp]
387
-\begin{center}
388
-\includegraphics[scale=0.45]{./figures-pdf/edition1}
389
-\caption{Edition et compilation distante}
390
-\label{fig:edition1}
391
-\end{center}
392
-\end{figure}
393
-
394
-Les étapes à suivre sont alors :
395
-\begin{enumerate}
396
-\item se connecter de manière distante à la \raspi via ssh (voir section~\ref{sec:ssh}),
397
- \item éditer à distance (par ex. avec {\tt nano}) le code,
398
- \item compiler avec la commande {\tt make} à l'aide du {\tt Makefile} du répertoire {\tt /destijl\_init},
399
- \item lancer l'exécutable par la commande {\tt sudo ./superviseur} (voir section ~\ref{sec:utilisation})\\
400
-\end{enumerate}
220
+Pour ajoutez des structures à l'application, il suffit de les déclarer dans le fichier {\tt tasks.h} puis de s'assurer qu'elles sont bien instanciées dans les méthodes adéquates de {\tt tasks.cpp}. Pour une tâche, il faut en plus déclarer une nouvelle méthode privée dans {tasks.h} et fournir son implémentation dans {tasks.cpp}. Cette nouvelle méthode sera le point d'entrée de la tâche.
401
 
221
 
402
-Vous pouvez ensuite lancer le moniteur (voir section~\ref{sec:utilisation}) pour interragir avec l'application.
222
+Toute la documentation de Xenomai se trouve en ligne (attention c'est Xenomai 3) et nous utilisons l'\href{https://xenomai.org/documentation/xenomai-3/html/xeno3prm/group__alchemy.html}{API alchemy}.
403
 
223
 
404
 \end{document}
224
 \end{document}

+ 0
- 7
software/raspberry/superviseur-robot/main.cpp View File

40
     tasks.Run();
40
     tasks.Run();
41
     tasks.Join();
41
     tasks.Join();
42
     
42
     
43
-    /*if (tasks.AcceptClient()) {
44
-        cout << "Rock'n'Roll baby, client accepted!"<<endl<<flush;
45
-        tasks.Run();
46
-        
47
-        tasks.Join();
48
-    }*/
49
-    
50
     tasks.Stop();
43
     tasks.Stop();
51
     
44
     
52
     //tasks.Run();
45
     //tasks.Run();

+ 41
- 16
software/raspberry/superviseur-robot/tasks.cpp View File

147
         cerr << "Error task start: " << strerror(-err) << endl << flush;
147
         cerr << "Error task start: " << strerror(-err) << endl << flush;
148
         exit(EXIT_FAILURE);
148
         exit(EXIT_FAILURE);
149
     }
149
     }
150
-    /**/if (err = rt_task_start(&th_sendToMon, (void(*)(void*)) & Tasks::SendToMonTask, this)) {
150
+    if (err = rt_task_start(&th_sendToMon, (void(*)(void*)) & Tasks::SendToMonTask, this)) {
151
         cerr << "Error task start: " << strerror(-err) << endl << flush;
151
         cerr << "Error task start: " << strerror(-err) << endl << flush;
152
         exit(EXIT_FAILURE);
152
         exit(EXIT_FAILURE);
153
-    }/**/
154
-    /**/if (err = rt_task_start(&th_receiveFromMon, (void(*)(void*)) & Tasks::ReceiveFromMonTask, this)) {
153
+    }
154
+    if (err = rt_task_start(&th_receiveFromMon, (void(*)(void*)) & Tasks::ReceiveFromMonTask, this)) {
155
         cerr << "Error task start: " << strerror(-err) << endl << flush;
155
         cerr << "Error task start: " << strerror(-err) << endl << flush;
156
         exit(EXIT_FAILURE);
156
         exit(EXIT_FAILURE);
157
-    }/**/
158
-    /**/if (err = rt_task_start(&th_openComRobot, (void(*)(void*)) & Tasks::OpenComRobot, this)) {
157
+    }
158
+    if (err = rt_task_start(&th_openComRobot, (void(*)(void*)) & Tasks::OpenComRobot, this)) {
159
         cerr << "Error task start: " << strerror(-err) << endl << flush;
159
         cerr << "Error task start: " << strerror(-err) << endl << flush;
160
         exit(EXIT_FAILURE);
160
         exit(EXIT_FAILURE);
161
-    }/**/
161
+    }
162
     if (err = rt_task_start(&th_startRobot, (void(*)(void*)) & Tasks::StartRobotTask, this)) {
162
     if (err = rt_task_start(&th_startRobot, (void(*)(void*)) & Tasks::StartRobotTask, this)) {
163
         cerr << "Error task start: " << strerror(-err) << endl << flush;
163
         cerr << "Error task start: " << strerror(-err) << endl << flush;
164
         exit(EXIT_FAILURE);
164
         exit(EXIT_FAILURE);
191
  * @brief Thread handling server communication with the monitor.
191
  * @brief Thread handling server communication with the monitor.
192
  */
192
  */
193
 void Tasks::ServerTask(void *arg) {
193
 void Tasks::ServerTask(void *arg) {
194
+    int status;
195
+    
194
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
196
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
195
     // Synchronization barrier (waiting that all tasks are started)
197
     // Synchronization barrier (waiting that all tasks are started)
196
     rt_sem_p(&sem_barrier, TM_INFINITE);
198
     rt_sem_p(&sem_barrier, TM_INFINITE);
197
 
199
 
200
+    /**************************************************************************************/
201
+    /* The task server starts here                                                        */
202
+    /**************************************************************************************/
198
     rt_mutex_acquire(&mutex_monitor, TM_INFINITE);
203
     rt_mutex_acquire(&mutex_monitor, TM_INFINITE);
199
-    int status = monitor.Open(SERVER_PORT);
204
+    status = monitor.Open(SERVER_PORT);
200
     rt_mutex_release(&mutex_monitor);
205
     rt_mutex_release(&mutex_monitor);
201
 
206
 
202
     cout << "Open server on port " << (SERVER_PORT) << " (" << status << ")" << endl;
207
     cout << "Open server on port " << (SERVER_PORT) << " (" << status << ")" << endl;
213
  * @brief Thread sending data to monitor.
218
  * @brief Thread sending data to monitor.
214
  */
219
  */
215
 void Tasks::SendToMonTask(void* arg) {
220
 void Tasks::SendToMonTask(void* arg) {
221
+    Message *msg;
222
+    
216
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
223
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
217
     // Synchronization barrier (waiting that all tasks are starting)
224
     // Synchronization barrier (waiting that all tasks are starting)
218
     rt_sem_p(&sem_barrier, TM_INFINITE);
225
     rt_sem_p(&sem_barrier, TM_INFINITE);
219
 
226
 
227
+    /**************************************************************************************/
228
+    /* The task sendToMon starts here                                                     */
229
+    /**************************************************************************************/
220
     rt_sem_p(&sem_serverOk, TM_INFINITE);
230
     rt_sem_p(&sem_serverOk, TM_INFINITE);
221
 
231
 
222
     while (1) {
232
     while (1) {
223
         cout << "wait msg to send" << endl << flush;
233
         cout << "wait msg to send" << endl << flush;
224
-        Message *msg = ReadInQueue(&q_messageToMon);
234
+        msg = ReadInQueue(&q_messageToMon);
225
         cout << "Send msg to mon: " << msg->ToString() << endl << flush;
235
         cout << "Send msg to mon: " << msg->ToString() << endl << flush;
226
         rt_mutex_acquire(&mutex_monitor, TM_INFINITE);
236
         rt_mutex_acquire(&mutex_monitor, TM_INFINITE);
227
-        monitor.Write(msg);
237
+        monitor.Write(msg); // The message is deleted with the Write
228
         rt_mutex_release(&mutex_monitor);
238
         rt_mutex_release(&mutex_monitor);
229
     }
239
     }
230
 }
240
 }
233
  * @brief Thread receiving data from monitor.
243
  * @brief Thread receiving data from monitor.
234
  */
244
  */
235
 void Tasks::ReceiveFromMonTask(void *arg) {
245
 void Tasks::ReceiveFromMonTask(void *arg) {
246
+    Message *msgRcv;
247
+    
236
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
248
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
237
     // Synchronization barrier (waiting that all tasks are starting)
249
     // Synchronization barrier (waiting that all tasks are starting)
238
     rt_sem_p(&sem_barrier, TM_INFINITE);
250
     rt_sem_p(&sem_barrier, TM_INFINITE);
239
-
251
+    
252
+    /**************************************************************************************/
253
+    /* The task receiveFromMon starts here                                                */
254
+    /**************************************************************************************/
240
     rt_sem_p(&sem_serverOk, TM_INFINITE);
255
     rt_sem_p(&sem_serverOk, TM_INFINITE);
241
     cout << "Received message from monitor activated" << endl << flush;
256
     cout << "Received message from monitor activated" << endl << flush;
242
 
257
 
243
     while (1) {
258
     while (1) {
244
-        Message *msgRcv;
245
         msgRcv = monitor.Read();
259
         msgRcv = monitor.Read();
246
         cout << "Rcv <= " << msgRcv->ToString() << endl << flush;
260
         cout << "Rcv <= " << msgRcv->ToString() << endl << flush;
247
 
261
 
262
             move = msgRcv->GetID();
276
             move = msgRcv->GetID();
263
             rt_mutex_release(&mutex_move);
277
             rt_mutex_release(&mutex_move);
264
         }
278
         }
265
-        delete msgRcv; // mus be deleted manually, no consumer
279
+        delete(msgRcv); // mus be deleted manually, no consumer
266
     }
280
     }
267
 }
281
 }
268
 
282
 
276
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
290
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
277
     // Synchronization barrier (waiting that all tasks are starting)
291
     // Synchronization barrier (waiting that all tasks are starting)
278
     rt_sem_p(&sem_barrier, TM_INFINITE);
292
     rt_sem_p(&sem_barrier, TM_INFINITE);
279
-
293
+    
294
+    /**************************************************************************************/
295
+    /* The task openComRobot starts here                                                  */
296
+    /**************************************************************************************/
280
     while (1) {
297
     while (1) {
281
         rt_sem_p(&sem_openComRobot, TM_INFINITE);
298
         rt_sem_p(&sem_openComRobot, TM_INFINITE);
282
         cout << "Open serial com (";
299
         cout << "Open serial com (";
292
         } else {
309
         } else {
293
             msgSend = new Message(MESSAGE_ANSWER_ACK);
310
             msgSend = new Message(MESSAGE_ANSWER_ACK);
294
         }
311
         }
295
-        WriteInQueue(&q_messageToMon, msgSend);
312
+        WriteInQueue(&q_messageToMon, msgSend); // msgSend will be deleted by sendToMon
296
     }
313
     }
297
 }
314
 }
298
 
315
 
303
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
320
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
304
     // Synchronization barrier (waiting that all tasks are starting)
321
     // Synchronization barrier (waiting that all tasks are starting)
305
     rt_sem_p(&sem_barrier, TM_INFINITE);
322
     rt_sem_p(&sem_barrier, TM_INFINITE);
306
-
323
+    
324
+    /**************************************************************************************/
325
+    /* The task startRobot starts here                                                    */
326
+    /**************************************************************************************/
307
     while (1) {
327
     while (1) {
308
 
328
 
309
         Message * msgSend;
329
         Message * msgSend;
316
         cout << ")" << endl;
336
         cout << ")" << endl;
317
 
337
 
318
         cout << "Movement answer: " << msgSend->ToString() << endl << flush;
338
         cout << "Movement answer: " << msgSend->ToString() << endl << flush;
319
-        WriteInQueue(&q_messageToMon, msgSend);
339
+        WriteInQueue(&q_messageToMon, msgSend);  // msgSend will be deleted by sendToMon
320
 
340
 
321
         if (msgSend->GetID() == MESSAGE_ANSWER_ACK) {
341
         if (msgSend->GetID() == MESSAGE_ANSWER_ACK) {
322
             rt_mutex_acquire(&mutex_robotStarted, TM_INFINITE);
342
             rt_mutex_acquire(&mutex_robotStarted, TM_INFINITE);
332
 void Tasks::MoveTask(void *arg) {
352
 void Tasks::MoveTask(void *arg) {
333
     int rs;
353
     int rs;
334
     int cpMove;
354
     int cpMove;
355
+    
335
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
356
     cout << "Start " << __PRETTY_FUNCTION__ << endl << flush;
336
     // Synchronization barrier (waiting that all tasks are starting)
357
     // Synchronization barrier (waiting that all tasks are starting)
337
     rt_sem_p(&sem_barrier, TM_INFINITE);
358
     rt_sem_p(&sem_barrier, TM_INFINITE);
359
+    
360
+    /**************************************************************************************/
361
+    /* The task starts here                                                               */
362
+    /**************************************************************************************/
338
     rt_task_set_periodic(NULL, TM_NOW, 100000000);
363
     rt_task_set_periodic(NULL, TM_NOW, 100000000);
339
 
364
 
340
     while (1) {
365
     while (1) {

+ 41
- 27
software/raspberry/superviseur-robot/tasks.h View File

39
 class Tasks {
39
 class Tasks {
40
 public:
40
 public:
41
     /**
41
     /**
42
-     * @brief Initialisation des structures de l'application (tâches, mutex, 
43
-     * semaphore, etc.)
42
+     * @brief Initializes main structures (semaphores, tasks, mutex, etc.)
44
      */
43
      */
45
     void Init();
44
     void Init();
46
 
45
 
47
     /**
46
     /**
48
-     * @brief Démarrage des tâches
47
+     * @brief Starts tasks
49
      */
48
      */
50
     void Run();
49
     void Run();
51
 
50
 
52
     /**
51
     /**
53
-     * @brief Arrêt des tâches
52
+     * @brief Stops tasks
54
      */
53
      */
55
     void Stop();
54
     void Stop();
56
     
55
     
57
     /**
56
     /**
57
+     * @brief Suspends main thread
58
      */
58
      */
59
     void Join();
59
     void Join();
60
     
60
     
61
-
62
-    
63
 private:
61
 private:
62
+    /**********************************************************************/
63
+    /* Shared data                                                        */
64
+    /**********************************************************************/
64
     ComMonitor monitor;
65
     ComMonitor monitor;
65
     ComRobot robot;
66
     ComRobot robot;
66
     int robotStarted;
67
     int robotStarted;
67
     int move = MESSAGE_ROBOT_STOP;
68
     int move = MESSAGE_ROBOT_STOP;
68
-        
69
+    
70
+    /**********************************************************************/
71
+    /* Tasks                                                              */
72
+    /**********************************************************************/
69
     RT_TASK th_server;
73
     RT_TASK th_server;
70
     RT_TASK th_sendToMon;
74
     RT_TASK th_sendToMon;
71
     RT_TASK th_receiveFromMon;
75
     RT_TASK th_receiveFromMon;
73
     RT_TASK th_startRobot;
77
     RT_TASK th_startRobot;
74
     RT_TASK th_move;
78
     RT_TASK th_move;
75
     
79
     
80
+    /**********************************************************************/
81
+    /* Mutex                                                              */
82
+    /**********************************************************************/
76
     RT_MUTEX mutex_monitor;
83
     RT_MUTEX mutex_monitor;
77
     RT_MUTEX mutex_robot;
84
     RT_MUTEX mutex_robot;
78
     RT_MUTEX mutex_robotStarted;
85
     RT_MUTEX mutex_robotStarted;
79
     RT_MUTEX mutex_move;
86
     RT_MUTEX mutex_move;
80
 
87
 
88
+    /**********************************************************************/
89
+    /* Semaphores                                                         */
90
+    /**********************************************************************/
81
     RT_SEM sem_barrier;
91
     RT_SEM sem_barrier;
82
     RT_SEM sem_openComRobot;
92
     RT_SEM sem_openComRobot;
83
     RT_SEM sem_serverOk;
93
     RT_SEM sem_serverOk;
84
     RT_SEM sem_startRobot;
94
     RT_SEM sem_startRobot;
85
 
95
 
86
-    RT_QUEUE q_messageToMon;
87
-
96
+    /**********************************************************************/
97
+    /* Message queues                                                     */
98
+    /**********************************************************************/
88
     int MSG_QUEUE_SIZE;
99
     int MSG_QUEUE_SIZE;
89
-
90
-    char mode_start;
100
+    RT_QUEUE q_messageToMon;
91
     
101
     
92
-    /**
93
-     * Write a message in a given queue
94
-     * @param queue Queue identifier
95
-     * @param msg Message to be stored
96
-     */
97
-    void WriteInQueue(RT_QUEUE *queue, Message *msg);
98
-
99
-    /**
100
-     * Read a message from a given queue, block if empty
101
-     * @param queue Queue identifier
102
-     * @return Message read
103
-     */
104
-    Message *ReadInQueue(RT_QUEUE *queue);
105
-
102
+    /**********************************************************************/
103
+    /* Tasks' functions                                                   */
104
+    /**********************************************************************/
106
     /**
105
     /**
107
      * @brief Thread handling server communication with the monitor.
106
      * @brief Thread handling server communication with the monitor.
108
      */
107
      */
123
      */
122
      */
124
     void OpenComRobot(void *arg);
123
     void OpenComRobot(void *arg);
125
 
124
 
126
-    
127
     /**
125
     /**
128
      * @brief Thread starting the communication with the robot.
126
      * @brief Thread starting the communication with the robot.
129
      */
127
      */
130
     void StartRobotTask(void *arg);
128
     void StartRobotTask(void *arg);
131
     
129
     
132
-        
133
     /**
130
     /**
134
      * @brief Thread handling control of the robot.
131
      * @brief Thread handling control of the robot.
135
      */
132
      */
136
     void MoveTask(void *arg);
133
     void MoveTask(void *arg);
134
+    
135
+    /**********************************************************************/
136
+    /* Queue services                                                     */
137
+    /**********************************************************************/
138
+    /**
139
+     * Write a message in a given queue
140
+     * @param queue Queue identifier
141
+     * @param msg Message to be stored
142
+     */
143
+    void WriteInQueue(RT_QUEUE *queue, Message *msg);
144
+    
145
+    /**
146
+     * Read a message from a given queue, block if empty
147
+     * @param queue Queue identifier
148
+     * @return Message read
149
+     */
150
+    Message *ReadInQueue(RT_QUEUE *queue);
137
 
151
 
138
 };
152
 };
139
 
153
 

Loading…
Cancel
Save