Browse Source

mise a jour guide et code

PE Hladik 2 years ago
parent
commit
38f3f57f4e

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

@@ -102,7 +102,7 @@
102 102
 {\scriptsize Institut National des Sciences Appliquées de Toulouse}\\
103 103
 ---\\
104 104
 Guide des outils de développement \\
105
-{\large Version 1.0.$\beta$ (\today)}\\
105
+{\large Version 1.0.1 (\today)}\\
106 106
 {\scriptsize Référent pédagogique : P.-E. Hladik (\texttt{pehladik@insa-toulouse.fr})}\\
107 107
 {\scriptsize Référents plateforme : S. Di Mercurio (\texttt{dimercur@insa-toulouse.fr})}\\
108 108
 ---
@@ -120,172 +120,33 @@ Guide des outils de développement \\
120 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 125
 Tout le code relatif au projet est disponible, cependant vous n'aurez besoin que des codes présents dans les répertoires :
128 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 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 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 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 150
 \begin{enumerate}
290 151
 \item Cliquez droit sur le projet et choisir {\tt Properties},
291 152
 \item Allez dans l'onglet {\tt Build},
@@ -304,101 +165,60 @@ Vous pouvez supprimer tous les autres répertoires du projet (clique droit sur l
304 165
 \item Cliquez {\tt OK}.
305 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 224
 \end{document}

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

@@ -40,13 +40,6 @@ int main(int argc, char **argv) {
40 40
     tasks.Run();
41 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 43
     tasks.Stop();
51 44
     
52 45
     //tasks.Run();

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

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

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

@@ -39,33 +39,37 @@ using namespace std;
39 39
 class Tasks {
40 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 44
     void Init();
46 45
 
47 46
     /**
48
-     * @brief Démarrage des tâches
47
+     * @brief Starts tasks
49 48
      */
50 49
     void Run();
51 50
 
52 51
     /**
53
-     * @brief Arrêt des tâches
52
+     * @brief Stops tasks
54 53
      */
55 54
     void Stop();
56 55
     
57 56
     /**
57
+     * @brief Suspends main thread
58 58
      */
59 59
     void Join();
60 60
     
61
-
62
-    
63 61
 private:
62
+    /**********************************************************************/
63
+    /* Shared data                                                        */
64
+    /**********************************************************************/
64 65
     ComMonitor monitor;
65 66
     ComRobot robot;
66 67
     int robotStarted;
67 68
     int move = MESSAGE_ROBOT_STOP;
68
-        
69
+    
70
+    /**********************************************************************/
71
+    /* Tasks                                                              */
72
+    /**********************************************************************/
69 73
     RT_TASK th_server;
70 74
     RT_TASK th_sendToMon;
71 75
     RT_TASK th_receiveFromMon;
@@ -73,36 +77,31 @@ private:
73 77
     RT_TASK th_startRobot;
74 78
     RT_TASK th_move;
75 79
     
80
+    /**********************************************************************/
81
+    /* Mutex                                                              */
82
+    /**********************************************************************/
76 83
     RT_MUTEX mutex_monitor;
77 84
     RT_MUTEX mutex_robot;
78 85
     RT_MUTEX mutex_robotStarted;
79 86
     RT_MUTEX mutex_move;
80 87
 
88
+    /**********************************************************************/
89
+    /* Semaphores                                                         */
90
+    /**********************************************************************/
81 91
     RT_SEM sem_barrier;
82 92
     RT_SEM sem_openComRobot;
83 93
     RT_SEM sem_serverOk;
84 94
     RT_SEM sem_startRobot;
85 95
 
86
-    RT_QUEUE q_messageToMon;
87
-
96
+    /**********************************************************************/
97
+    /* Message queues                                                     */
98
+    /**********************************************************************/
88 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 106
      * @brief Thread handling server communication with the monitor.
108 107
      */
@@ -123,17 +122,32 @@ private:
123 122
      */
124 123
     void OpenComRobot(void *arg);
125 124
 
126
-    
127 125
     /**
128 126
      * @brief Thread starting the communication with the robot.
129 127
      */
130 128
     void StartRobotTask(void *arg);
131 129
     
132
-        
133 130
     /**
134 131
      * @brief Thread handling control of the robot.
135 132
      */
136 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