Reverse engineering hardware d’un drone Parrot (CPEFly)

Introduction

Dans le cadre de mes études d’ingénieurs, j’avais à réaliser en groupe un projet de conception dont le sujet pouvait être choisis par les étudiants (sous réserve de présenter un cahier des charges cohérent). Nous avons choisi de réaliser un drone dont le cahier des charges est décrit ci-dessous:

  • Le drone doit être en mesure de voler de manière horizontale.
  • Le drone doit pouvoir transmettre un flux vidéo vers une plateforme web.
  • Le drone doit fonctionner avec un code que nous avons nous même conçu, tournant sur une carte au choix : un 8051 ou un STM32.
  • Comme le budget est serré, nous devions le réaliser à partir de matériaux de récupération, c’est à dire un AR DRONE 2 de la marque Parrot, ce qui complique la tâche.

Mon rôle dans l’équipe était d’assurer le pilotage les moteurs de l’AR Drone à la vitesse souhaité via un STM32.

Le fruit de mes recherches est présenté dans une série de 4 articles:
– présentation du projet, recherche sur internet (cet article)
reverse engineering du firmware du drone
interactions avec les moteurs
stabilisation du drone – Capteurs et PID

Cet article est une étude préliminaire qui pour objectif d’obtenir quelques informations avant de passer aux choses sérieuses. C’est peut-être pas le point le plus intéressant de mon travail de recherche d’un point de vue technique, car je me contente de présenter des résultats issues de recherches sur internet en les accompagnant d’une brève analyse d’hardware, mais ça reste néanmoins nécessaire si on veut mener le reverse à bien afin d’avoir une vague idée du fonctionnement générale de notre système.

Analyse du matériel

Nous avions à notre disposition un drone Parrot AR DRONE 2 non fonctionnel gentiment fourni par les responsables de la majeur robotique.

La première étape a consisté à démonter les pièces du drone, afin d’en faire l’inventaire et de sélectionner les composants que l’on pourrait garder. Ils sont listé dans le tableau ci-dessous:

4 moteurs brushless avec contrôleur
(avec 4 hélices)
1 carte mère
1 châssis de drone
2 cameras
Une navboard et ses capteurs (accéléromètre et capteurs de distance)

Pour démonter le drone proprement, on a utilisé cette vidéo:

Etude de la carte mère

La carte mère est divisée en deux parties, comme on peut le voir sur les images ci-dessous:

On distingue plusieurs composants notables. Sur la première carte:
D9MBZ (documentation ici) LPDDR SRAM
NQ278 (documentation ici) Mémoire NAND Flash
TPS65921 (documentation ici) Power Management and USB Single Chip
AR6103G-BM2D-R Module 802.11b/g/n 2.4GHz 72200Kbps LGA (pour le point d’accès WIFI).
Sur la deuxième carte, la navboard intitulé « MYKONOS2_NAV_HW03 »:
PIC24HJ16GP304 (documentation ici) MicroController PIC24 16 bits
IMU-3000 de INVENSENSE (documentation ici) 3-AXIS MOTION SENSOR GYROSCOPE (I2C)

L’objectif étant de développer notre propre logiciel de contrôle du drone, la carte mère ne nous intéressait pas. On a conservé le reste des composants.

Etude des moteurs

Les motorboards de l’AR DRONE 2 sont les suivantes:

Ils ont été spécialement conçus pour l’AR Drone pour garantir des performances élevées et une longue durée de vie. Ils ont une puissance de 15 Watts et effectuent 28,000 tours par minute (RPM) en vol stationnaire, ce qui correspond à 3,300 RPM sur les hélices. Les gammes de moteurs commencent à 10,350 RPM et vont jusqu’à 41,400 RPM. Des microcontrôleurs 8 bits basse puissance et des ADC 10 bits contrôlent la vitesse des moteurs. (D’après les spécifications techniques trouvables sur internet).

Les moteurs sont accompagné d’un contrôleur (un Atmel ATMega8a) dont le rôle est de réguler la vitesse de ce dernier.

On note la présence sur la carte de 3 transistors MOSFETs c3021ld. On en déduit que l’ATMEGA pilote les MOSFET comme des interrupteurs, ce qui permet de générer le signal PMW qui est envoyé au moteur. On remarque également qu’il n’y a pas de capteurs (température et autre) au niveau de la motorboard, ce qui signifie qu’il y a très peu de chance que le moteur renvoie des informations vers la carte mère.
Au niveau des pins des motorboards, ils sont au nombre de 5 :

  • 11 V pour l’alimentation des moteurs
  • 5 V pour l’alimentation de l’ATMega
  • GND
  • TX+RX pour la communication UART
  • Un PIN que l’on a d’abord pensé être le récepteur d’un signal IRQ, qui sert à remonter les problèmes rencontrés par le drone à la carte mère (conformément au recherche que l’on a fait sur internet), mais qui est en réalité un PIN ENABLE qui a pour but d’activer la réception des données sur la motorboard (le signal va donc de la carte mère vers la motorboard et non l’inverse). Je tiens à remercier monsieur Massouri de nous avoir aidé à le comprendre. Malheureusement on aura compris cela à la fin du projet, c’est pourquoi, comme vous le verrez dans les articles qui suivent, notre solution n’est pas optimale (on utilise mal ce PIN).
Protocole de communication

Nous l’avons vite compris, le protocole de communication entre la carte mère et les moteurs est un protocole propriétaire Parrot non documenté, se transmettant par liaison UART avec un baudrate de 115200. Comme notre carcasse de drone ne fonctionnait pas, il nous était impossible de réaliser des captures des échanges entre la carte mère et les moteurs pour les analyser et comprendre le protocole. A ce moment là conserver les moteurs du drone pour notre projet semblait compromis. Par chance, nous sommes tombé sur une série de discussion sur internet présentant et interprétant des captures réalisés sur le même modèle de drone. Voilà un bref résumé de ce que nous avons appris.
NB: Pour réaliser l’enregistrement, l’outil interceptty a été utilisé.

Le moteur peut recevoir deux grands types de commandes : des commandes unicast (à destination d’un moteur) et multicast (à destination de tous les moteurs). Les commandes unicast servent à configurer le programme du contrôleur de chaque moteur, tandis que les commandes multicast permettent de paramétrer la vitesse d’un moteur.

commande unicast

L’ensemble des commandes unicast est décrite dans le tableau ci-dessous:

Nom de la commandeValeurDescriptionValeur de retour
Récupérer le statut du moteurE0Récupère le statut du moteur00 : ok
50 : besoin de flash la mémoire
Ecrire dans la mémoire du contrôleur du moteur71 XX…XX 70Ecris dans la mémoire le programme du moteur. Le programme doit faire 64 octets, représenté par les XX…XX dans la commande00
Récupérer le checksum de la mémoire91Demande de récupérer le checksum du moteur.120 octets, correspondant au checksum de la mémoire
Fixer le statut comme étant okA1Fixe le statut du moteur comme étant ok.A0 FF
Assigner un moteur comme étant le moteur 1,2,3 ou 401 ou 02 ou 03 ou 04Assigner un moteur comme étant le moteur 1,2,3 ou 400
Récupérer la version du moteur11Récupérer la version du moteur sous la forme de 11 octets. Exemple : 01 0b 03 00 01 01 0a 0a 1a 0a 0a = soft version 1.11, hard version 3.0, supplier 1.1, lot number 10/10, FVT1 26/10/1011 octets
Attention : Comme on le verra par la suite, pas toutes ces commandes sont correctes.
Commande multicast

L’ensemble des commandes multicast est décrite pas le tableau ci-dessous:

Nom de la commandeValeurDescriptionValeur de retour
Démarrer une communication multicast.A0 A0 A0 A0 A0 A0Démarrer une communication multicast. Tout les échanges qui suivent seront à destination de tous les moteurs.00
Fixe la vitesse de rotation des moteurs2x xx xx xx xx 00
Vérifie si les moteurs sont encore opérationnels89 ou 8A ou 8B ou 8C89 : moteur 1, 8A : moteur 2, 8B : moteur 3, 8C : moteur 428 2F
Fixe la couleur de la LED des moteurs6x xx ou 7x xx (commence par les bits 011…)Bit n°5 à 1 : LED rouge moteur arrière gauche
Bit n°6 à 1 : LED verte moteur arrière gauche
Bit n°7 à 1 : LED rouge moteur arrière droit
Bit n°8 à 1 : LED verte moteur arrière droit
Bit n°9 à 1 : LED rouge moteur avant droit
Bit n°10 à 1 : LED verte moteur avant droit
Bit n°11 à 1 : LED rouge moteur avant gauche
Bit n°12 à 1 : LED verte moteur avant gauche
C’est à dire de la forme : 011grgrg rgrxxxx
(ça aurait changé pour l’ARDRONE 2: 011rrrrx xxxggggx)
00
Attention : Comme on le verra par la suite, pas toutes ces commandes sont correctes.
Spécificité de la liaison série

Comme les deux lignes de communications sont regroupés en une seule ligne (RX+TX), il faut mettre en place un multiplexeur qui connectera la ligne TX+RX du moteur :

  • vers la ligne TX de la carte mère lors de la transmission.
  • vers la ligne RX de la carte mère lors de la réception.

De cette manière on pourra capturer, et surtout interpréter le retour de chaque chaque commande.

Exemple d’un échange

Exemple d’une capture réalisé par wiredrat disponible ici. Ce qui suit un < est une commande envoyée par la carte mère vers le moteur. Ce qui suit un > est le résultat de la commande envoyé par le moteur vers la carte mère.

< 0xe0           RST?
> 	0xe0
> 	0x00
< 0x01           MOTOR 1
> 	0x01
< 0x40 (@)       GET INFO
> 	0x40 (@)      
> 	0x01
> 	0x0b
> 	0x03
> 	0x00
> 	0x01
> 	0x01
> 	0x09
> 	0x0a
> 	0x07
> 	0x0a
> 	0x0a

Pour la suite

Nous avons maintenant une première idée du fonctionnement du protocole de communication BLC. Seulement, comme les sources sont relativement anciennes et que nous n’avons aucune preuve de leur véracité, j’ai décidé de réalisé le reverse engineering du firmware du drone, disponible sur internet. Je vous explique tout ici.

Petit message du futur : analyse à la sonde logique

Comme vous le verrez par la suite, j’ai, au final, acheté un deuxième drone pour des besoins techniques, et sur celui-ci la carte mère fonctionne. J’ai donc pour lancer une capture des données transitant sur le PIN TX+RX de la motorboard lors de l’initialisation. On obtient les données ci-dessous:

0xE0 [20ms] 0x50 [480us]
0x71 [440us] /64 octets séparés par 9.6us/ [8.38ms] 0x70 [440us]
0x71 [442us] /64 octets séparés par 9.6us/ [8.38ms] 0x70 [440us]

0x71 [442us] /64 octets séparés par 9.6us/ [8.38ms] 0x70 [558us]
0x91 [80us] /120 octets séparés par 70-80us/ [503us]
0xA1 [19ms] 0xA0 [180ms] 0x03 [446us]
0x40 [23us] /11 octets séparés par 22us/

Références


Publié

dans

par