Master SIAME | Université Toulouse 3

Internet of things and System on Chip

Master SIAME | Université Toulouse 3

Internet of things and System on Chip

User Tools


Vérification des proprités temporelles

Le projet temps-réel se déroulera en coopération avec le projet de code embarqué. Vous allez analyser dans OTAWA, et ensuite chercher à optimiser, le code que vous allez développer pour le pilotage de quadcopter. L’analyse temporelle sera fait sur les parties du code qui traitent les données acquises par les capteurs pour décider à la prochaine commande à envoyer aux contrôleurs.

D’ailleurs, pendant le projet de code embarqué, il est fortement conseillé de penser à écrire du code “analysable”. L’analyse dans OTAWA est faite à la granularité d’une fonction. Il vous donc faudra séparer les parties du code qui font le traitement des données, et de mettre chacune dans une fonction séparée.

Structure d'une application temps-réel

Pour piloter les quadcopter, vous aurez à réaliser une application temps-réel strict pour une application critique : les quadcopters, malgré leur petite taille, peuvent réellement faire des dégâts sur le matériel ou sur les personnes !

Pour ce faire, l'application est généralement découpée en tâches ayant les caractéristiques suivantes :

  • une fonction d'exécution de la tâche,
  • une période (en ms) au bout laquelle la fonction de tâche est appelée,
  • un WCET déterminant le maximum du temps d'exécution d'une tâche particulière.

Pour appeler les tâches selon leurs périodes, le programme principal est organisé sous forme d'une boucle infinie contenant :

  • un séquenceur qui pour chaque instant de l'application choisit les tâches dont les fonctions doivent être appelés,
  • une attente (si possible non active) qui attend la date de la prochaine tâche à activer.

En général, cette boucle va à la vitesse de la période la plus courte, P. Pour que notre système temps-réel strict soit ordonnaçable et, par conséquent, qu'il assure que les échéances de chaque tâche soit respectée, il faut s'arrurer qu'à tout moment, la somme des WCET des tâches activée est inférieure à P. Quand cette condition n'est pas vérifié, on a plusieurs possibilités :

  • modifier et optimiser le code pour que le WCET soit moins important,
  • augmenter la période de certaines tâches (ce qui va dégrader la réactivité du système),
  • découper les tâches dont les périodes sont longues en sous-tâches activées tour à tour,
  • constater que le matériel n'est pas assez puissant et changer de matériel.

Contraintes d'analysibilité (OTAWA)

Pour ces fonctions, il faut faire attention à :

  • langage imposé : le C
  • compiler le code avec l'option “-static”
  • ne pas faire usage de l’allocation dynamique de mémoire,
  • éviter la structure “switch/case” ⇒ utiliser if/else pour faciliter l'analyse,
  • ne pas avoir d’entrée/sortie ⇒ si vous voulez afficher/stocker des infos de débogage, vous pouvez utiliser la compilation conditionnelle pour exclure les entrées/sorties de la code de production.

Linux et le temps-réel

Sous Linux, il ne sera possible de faire des entrée-sorties non gérées par le noyau que par scrutation. Ceci étant, une gestion d'entrée-sortie par scrutation est une tâche comme une autre : il suffit de déterminer la période utile.

Certaines extensions de Linux permettent vraiment de faire du temps-réel strict mais ce n'est pas le cas de notre installation, Angstrom Linux, qui est surtout intéressant pour sa légèreté. Cependant, notre application n'a pas un niveau critique très élevé et les expérimentations ont montré que le noyau (si aucun autre code ne tourne en même temps) est d'une grande régularité.

De manière générale, le noyau de BeagleBone permet une fréquence minimale de 10ms qui devrait être suffisante pour nos quadcopters.

Pour la précision, il est important de travailler avec des dates constatées (plutôt que les dates prévues). Cela permet d'adapter les calculs au temps réel constaté entre deux activations et à possible “gigue” de ce temps. Pour ce faire, on peut utiliser la fonction gettimeofday(). Elle donne le temps en us (même si on peut constater que la précision est un peu moindre).

Une manière intéressante d'éviter les attentes actives peut être l'utilisation des signaux Unix. Les fonctions suivantes peuvent être intéressantes :

  • signal() permet d'installer un gestionnaire de signaux par exemple sur le signal SIGALRM.
  • sigaction() est beaucoup plus intéressant et permet de mieux contrôler les gestionnaires de signaux.
  • setitimer() permet de mettre en place un timer périodique et de déclencher un signal.

Problèmes à traiter

Pour pouvoir calculer le temps d'exécution, vous devez au moins traiter les problèmes suivants :

  • limites de boucle des fonctions d'émulation (division entière, opérations flottantes, etc),
  • déterminer du temps pour des appels système,
  • temps consommé par le séquenceur lui-même.