« I2L 2022 Groupe2 » : différence entre les versions
(Ajout capture terminal) |
|||
(6 versions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 11 : | Ligne 11 : | ||
[[Fichier:I2L-2022-G2-schema.pdf|thumb|400px|left|Schéma]] | [[Fichier:I2L-2022-G2-schema.pdf|thumb|400px|left|Schéma]] | ||
[[Fichier:I2L-2022-G2-PCB.pdf|thumb|400px|right|Carte]] | [[Fichier:I2L-2022-G2-PCB.pdf|thumb|400px|right|Carte]] | ||
[[Fichier:I2L-2022-G2-carte-soudée.jpg|thumb|600px|center|Carte soudée]] | |||
=Fonctionnement du système embarqué= | |||
Le projet consiste en un périphérique USB qui intègre un mot de passe et des LEDs. Lorsqu'il est connecté à un ordinateur, on lance un programme, demandant à l'utilisateur de saisir un mot de passe. L'utilisateur dispose de quatre essais pour entrer le mot de passe correct. Chaque essai infructueux allume une LED rouge. Si le mot de passe est correct, les LEDs s'allument en vert pour signaler une authentification réussie. Si les quatre essais échouent, toutes les LEDs rouges clignotent rapidement, et empêche toute tentative supplémentaire d'entrer un mot de passe. | |||
=Programmes= | |||
Lien du projet GitHub : https://github.com/hisakiyo/systeme-embarque | |||
[[ | Première version (test de l'allumage des leds à l'aide des boutons) : [[File:Projet embarqué V1.zip]] | ||
Version finale : [[File:Projet embarqué V2.zip]] | |||
=Démonstration du fonctionnement= | |||
Voici une vidéo où nous entrons plusieurs 3 mots de passe incorrects puis le bon mot de passe. | |||
[[Fichier:Démonstration du fonctionnement.mp4|thumb|600px|center|Démonstration du fonctionnement]] | |||
= Extraits de code = | |||
Le projet comportant pas mal de fichiers, nous allons nous concentrer sur l'essentiel. | |||
== Partie périphérique USB == | |||
Au sein du fichier Input/Echo.c, nous gérons l'allumage des LEDs dans la partie IN : | |||
On peut y voir les binaires pour les LEDs, la variable try pour les 4 essais ainsi que la variable present qui est un booléen permettant de savoir si il y a déjà eu une lecture (partie OUT) | |||
<syntaxhighlight lang="c" line="1"> | |||
/* Select the IN Endpoint */ | |||
Endpoint_SelectEndpoint(ECHO_IN_EPADDR); | |||
/* Check if IN Endpoint Ready for Read/Write */ | |||
if (Endpoint_IsReadWriteAllowed() && present) | |||
{ | |||
if (strncmp(EP_Data, token, 10) == 0) | |||
{ | |||
PORTB &= 0b10000000; | |||
PORTB |= 0b00101010; | |||
try = 0; | |||
} | |||
else | |||
{ | |||
if(try == 0) | |||
{ | |||
try++; | |||
PORTB &= 0b10000000; | |||
PORTB |= 0b00000001; | |||
} | |||
else if(try == 1) | |||
{ | |||
try++; | |||
PORTB &= 0b10000000; | |||
PORTB |= 0b00000101; | |||
} | |||
else if(try == 2) | |||
{ | |||
try++; | |||
PORTB &= 0b10000000; | |||
PORTB |= 0b00010101; | |||
} | |||
else | |||
{ | |||
while(1) { | |||
PORTB &= 0b10000000; | |||
PORTB |= 0b00010101; | |||
_delay_ms(1000); | |||
PORTB &= 0b10000000; | |||
_delay_ms(1000); | |||
} | |||
} | |||
} | |||
/* Finalize the stream transfer to send the last packet */ | |||
Endpoint_ClearIN(); | |||
present = 0; | |||
} | |||
</syntaxhighlight> | |||
Dans la partie OUT, on lit les caractères reçus : | |||
<syntaxhighlight lang="c" line="1"> | |||
/* Select the OUT Endpoint */ | |||
Endpoint_SelectEndpoint(ECHO_OUT_EPADDR); | |||
/* Check if Endpoint contains a packet */ | |||
if (Endpoint_IsOUTReceived()) | |||
{ | |||
/* Check to see if the packet contains data */ | |||
if (Endpoint_IsReadWriteAllowed()) | |||
{ | |||
/* Read in the LED report from the host */ | |||
// Envoi du mdp | |||
for (int i = 0; i < 10; i++) | |||
{ | |||
EP_Data[i] = Endpoint_Read_8(); | |||
} | |||
present = 1; | |||
} | |||
/* Handshake the OUT Endpoint - clear endpoint */ | |||
Endpoint_ClearOUT(); | |||
} | |||
</syntaxhighlight> | |||
== Partie ordinateur == | |||
Au sein du fichier Output/proj_echo.c : | |||
On gère le prompt demandant d'entrer un mot de passe, on récupère les caractères et on gère la fin de l'entrée. Nous avons délibérément laisser les print de début permettant de voir ce que l'on envoi et ce que l'on reçoit. | |||
<syntaxhighlight lang="c" line="1"> | |||
printf("Enter password: "); | |||
fflush(stdin); | |||
fgets((char*)token, EP_OUTSIZE+2, stdin); | |||
token[strlen(token)] = 0; | |||
ressnd=libusb_interrupt_transfer(devices[0].handle,out,token,EP_OUTSIZE,&size,DEFAULT_TIMEOUT); | |||
printf("Résultat envoi=%d taille envoyée=%d\n",ressnd,size); | |||
for(i=0;i<EP_OUTSIZE;i++) printf("%02x ",token[i]); | |||
printf("\n"); | |||
sleep(1); | |||
resrcv=libusb_interrupt_transfer(devices[0].handle,in|LIBUSB_ENDPOINT_IN,bytes,EP_INSIZE,&size,DEFAULT_TIMEOUT); | |||
printf("Résultat réception=%d taille réception=%d\n",resrcv,size); | |||
for(i=0;i<EP_INSIZE;i++) printf("%02x ",bytes[i]); | |||
printf("\n"); | |||
sleep(1); | |||
</syntaxhighlight> | |||
=Compilation= | |||
'''Utilitaires''' | |||
* <code>gcc-avr</code> | |||
* <code>avr-libs</code> | |||
* <code>libusb-1.0-0-dev</code> | |||
* <code>lufa-LUFA-210130</code> | |||
'''Commandes nécessaires''' | |||
Au sein du dossier Input, compiler le programme présent sur la carte | |||
<syntaxhighlight lang="shell"> | |||
make && make download | |||
</syntaxhighlight> | |||
Au sein du dossier Output, compiler le programme tournant sur le PC | |||
Lors du make, le projet génère un exécutable sous le nom '''proj_echo''' | |||
<syntaxhighlight lang="shell"> | |||
make && ./proj_echo | |||
</syntaxhighlight> | |||
=Conclusion= | |||
Sceptiques au départ quant au module, nous avons été agréablement surpris par notre intérêt envers celui-ci. Nous avons appris de nouvelles choses, qui ne nous serons pas forcément utile en entreprise mais où il était intéressant de voir le fonctionnement avec la partie périphérique et la partie PC, les librairies, la communication entre les deux. | |||
==Historique des travaux== | |||
'''<u>TP du Lundi 22 mai :</u>''' | '''<u>TP du Lundi 22 mai :</u>''' | ||
Programmation en C dans le but de faire clignoter la LED, en précisant un timing précis et en utilisant l'horloge ajouté sur la carte. En fin de séance, nous étions occupés à allumer la LED uniquement lorsque nous appuyons sur un bouton. | Programmation en C dans le but de faire clignoter la LED, en précisant un timing précis et en utilisant l'horloge ajouté sur la carte. En fin de séance, nous étions occupés à allumer la LED uniquement lorsque nous appuyons sur un bouton. | ||
'''<u>TP du Jeudi 25 mai :</u>''' | '''<u>TP du Jeudi 25 mai :</u>''' | ||
Ligne 29 : | Ligne 174 : | ||
Suite à ça nous avons pris en main un projet LUFA en y ajoutant la base "Minimal", avec <code>lsusb -vvv</code> nous vérifions si notre périphérique USB contient bien une interface, ce qui n'est pas le cas pour l'instant. | Suite à ça nous avons pris en main un projet LUFA en y ajoutant la base "Minimal", avec <code>lsusb -vvv</code> nous vérifions si notre périphérique USB contient bien une interface, ce qui n'est pas le cas pour l'instant. | ||
'''<u>TP du Lundi 12 juin :</u>''' | '''<u>TP du Lundi 12 juin :</u>''' | ||
Ligne 42 : | Ligne 186 : | ||
[[Fichier:Capture terminal.png|thumb|600px|center|Envoi d'un mot de passe de 10 caractères, le périphérique renvoi 01 ce qui veut dire que le mot de passe n'est pas bon]] | [[Fichier:Capture terminal.png|thumb|600px|center|Envoi d'un mot de passe de 10 caractères, le périphérique renvoi 01 ce qui veut dire que le mot de passe n'est pas bon]] | ||
'''<u>TP du Jeudi 15 juin :</u>''' | |||
Finalisation du développement sur la comparaison de mot de passe ainsi que du Wiki. L'utilisateur a 4 essais au sein d'un prompt, la carte contient le mot de passe et les leds indique si le mot de passe est ok ou non. | |||
=Fichiers= | =Fichiers= | ||
Version actuelle datée du 16 juin 2023 à 12:13
Proposition de système
Nous proposons un vérificateur de mot de passe. La carte comporterait 3 LED correspondant à 3 essais, si l'essai est mauvais la led est rouge et on passe à un nouvel essai, si l'essai est bon ça passe au vert et ensuite l'état est remis à 0. Au bout de 3 essais ratés tout est au rouge et est remis à 0 ensuite.
Contre-proposition
Pas de difficulté sur la programmation de la carte. Le code doit être programmé dans le périphérique USB. Ce périphérique USB doit comporter une interface avec un point d'accès IN et un point d'accès OUT. Le point d'accès OUT est utilisée pour envoyer le code proposé vers la carte, le point d'accès IN est utilisée pour lire la réponse de la carte (code correct ou non). Le programme sur PC utilisera la bibliothèque libusb-1.0.
Carte
Fonctionnement du système embarqué
Le projet consiste en un périphérique USB qui intègre un mot de passe et des LEDs. Lorsqu'il est connecté à un ordinateur, on lance un programme, demandant à l'utilisateur de saisir un mot de passe. L'utilisateur dispose de quatre essais pour entrer le mot de passe correct. Chaque essai infructueux allume une LED rouge. Si le mot de passe est correct, les LEDs s'allument en vert pour signaler une authentification réussie. Si les quatre essais échouent, toutes les LEDs rouges clignotent rapidement, et empêche toute tentative supplémentaire d'entrer un mot de passe.
Programmes
Lien du projet GitHub : https://github.com/hisakiyo/systeme-embarque
Première version (test de l'allumage des leds à l'aide des boutons) : Fichier:Projet embarqué V1.zip
Version finale : Fichier:Projet embarqué V2.zip
Démonstration du fonctionnement
Voici une vidéo où nous entrons plusieurs 3 mots de passe incorrects puis le bon mot de passe.
Extraits de code
Le projet comportant pas mal de fichiers, nous allons nous concentrer sur l'essentiel.
Partie périphérique USB
Au sein du fichier Input/Echo.c, nous gérons l'allumage des LEDs dans la partie IN :
On peut y voir les binaires pour les LEDs, la variable try pour les 4 essais ainsi que la variable present qui est un booléen permettant de savoir si il y a déjà eu une lecture (partie OUT)
/* Select the IN Endpoint */
Endpoint_SelectEndpoint(ECHO_IN_EPADDR);
/* Check if IN Endpoint Ready for Read/Write */
if (Endpoint_IsReadWriteAllowed() && present)
{
if (strncmp(EP_Data, token, 10) == 0)
{
PORTB &= 0b10000000;
PORTB |= 0b00101010;
try = 0;
}
else
{
if(try == 0)
{
try++;
PORTB &= 0b10000000;
PORTB |= 0b00000001;
}
else if(try == 1)
{
try++;
PORTB &= 0b10000000;
PORTB |= 0b00000101;
}
else if(try == 2)
{
try++;
PORTB &= 0b10000000;
PORTB |= 0b00010101;
}
else
{
while(1) {
PORTB &= 0b10000000;
PORTB |= 0b00010101;
_delay_ms(1000);
PORTB &= 0b10000000;
_delay_ms(1000);
}
}
}
/* Finalize the stream transfer to send the last packet */
Endpoint_ClearIN();
present = 0;
}
Dans la partie OUT, on lit les caractères reçus :
/* Select the OUT Endpoint */
Endpoint_SelectEndpoint(ECHO_OUT_EPADDR);
/* Check if Endpoint contains a packet */
if (Endpoint_IsOUTReceived())
{
/* Check to see if the packet contains data */
if (Endpoint_IsReadWriteAllowed())
{
/* Read in the LED report from the host */
// Envoi du mdp
for (int i = 0; i < 10; i++)
{
EP_Data[i] = Endpoint_Read_8();
}
present = 1;
}
/* Handshake the OUT Endpoint - clear endpoint */
Endpoint_ClearOUT();
}
Partie ordinateur
Au sein du fichier Output/proj_echo.c :
On gère le prompt demandant d'entrer un mot de passe, on récupère les caractères et on gère la fin de l'entrée. Nous avons délibérément laisser les print de début permettant de voir ce que l'on envoi et ce que l'on reçoit.
printf("Enter password: ");
fflush(stdin);
fgets((char*)token, EP_OUTSIZE+2, stdin);
token[strlen(token)] = 0;
ressnd=libusb_interrupt_transfer(devices[0].handle,out,token,EP_OUTSIZE,&size,DEFAULT_TIMEOUT);
printf("Résultat envoi=%d taille envoyée=%d\n",ressnd,size);
for(i=0;i<EP_OUTSIZE;i++) printf("%02x ",token[i]);
printf("\n");
sleep(1);
resrcv=libusb_interrupt_transfer(devices[0].handle,in|LIBUSB_ENDPOINT_IN,bytes,EP_INSIZE,&size,DEFAULT_TIMEOUT);
printf("Résultat réception=%d taille réception=%d\n",resrcv,size);
for(i=0;i<EP_INSIZE;i++) printf("%02x ",bytes[i]);
printf("\n");
sleep(1);
Compilation
Utilitaires
gcc-avr
avr-libs
libusb-1.0-0-dev
lufa-LUFA-210130
Commandes nécessaires
Au sein du dossier Input, compiler le programme présent sur la carte
make && make download
Au sein du dossier Output, compiler le programme tournant sur le PC
Lors du make, le projet génère un exécutable sous le nom proj_echo
make && ./proj_echo
Conclusion
Sceptiques au départ quant au module, nous avons été agréablement surpris par notre intérêt envers celui-ci. Nous avons appris de nouvelles choses, qui ne nous serons pas forcément utile en entreprise mais où il était intéressant de voir le fonctionnement avec la partie périphérique et la partie PC, les librairies, la communication entre les deux.
Historique des travaux
TP du Lundi 22 mai :
Programmation en C dans le but de faire clignoter la LED, en précisant un timing précis et en utilisant l'horloge ajouté sur la carte. En fin de séance, nous étions occupés à allumer la LED uniquement lorsque nous appuyons sur un bouton.
TP du Jeudi 25 mai :
Notre carte contient désormais 7 leds (3 rouges, 3 vertes et une bleue) ainsi que 2 boutons. Dans un premier temps, nous avons programmé en C un programme qui : par défaut maintient les leds éteintes, sur l'appui du bouton gauche on allume les leds rouges et bleue et sur le bouton droit on allume les vertes.
Suite à ça nous avons pris en main un projet LUFA en y ajoutant la base "Minimal", avec lsusb -vvv
nous vérifions si notre périphérique USB contient bien une interface, ce qui n'est pas le cas pour l'instant.
TP du Lundi 12 juin :
En début de projet, nous avons récupéré une base LUFA ainsi qu'une base utilisant la librairie libusb. Après avoir testé ces deux programmes, nous avons bien une interface de renseigné et le IN/OUT fonctionnel.
Nous avons rencontré un problème avec le code erreur -7 qui provenait du stockage (uint8_t EP_Data;), en ajoutant "volatile" devant le typage, cela a réglé le soucis.
Pour finir, nous avons réunis les deux projets en un seul pour plus de facilité lors de nos programmations, ce projet est disponible sur le lien GitHub dans les fichiers. Nous avons démarré la programmation de la lecture d'un mot de passe, en commençant par envoyer 10 caractères et en vérifiant la bonne réception sur le premier caractère.
En fin de séance, nous avons démarré la programmation sur la comparaison de mot de passe.
TP du Jeudi 15 juin :
Finalisation du développement sur la comparaison de mot de passe ainsi que du Wiki. L'utilisateur a 4 essais au sein d'un prompt, la carte contient le mot de passe et les leds indique si le mot de passe est ok ou non.
Fichiers
Projet KiCAD : Fichier:I2L-2022-CLAIRET-MARETTE.zip
Projet LUFA "écho" : Fichier:I2L-2022-LUFA-echo.zip
Programme libusb-1.0 "écho" : Fichier:I2L-2022-libusb-echo.zip
Projet GitHub réunissant la partie périphérique et la partie PC : https://github.com/hisakiyo/systeme-embarque
Pour compiler le programme "libusb" il faut juste avoir installé un compilateur C et la bibliothèque libusb-1.0-0-dev
.
Pour compiler le projet LUFA, il faut commencer par récupérer la bibliothèque lufa-LUFA-210130
. Il faut ensuite placer le répertoire de l'archive dans un nouveau répertoire I2L créé dans le répertoire de la bibliothèque : lufa-LUFA-210130/I2L/Echo
. Un simple make
compile le projet et un make dfu
télécharge le binaire dans le périphérique USB.