« SE4Binome2023-8 » : différence entre les versions
Ligne 210 : | Ligne 210 : | ||
Par le suite, nous avons configuré cette nouvelle interface avec la commande "ip address add 10.0.0.100/24 dev usb0" qui lui ajoute l'adresse 10.0.0.100 et un masque de classe C qui convient à nos besoins. A présent, nous pouvons faire un ping de l'adresse 10.0.0.2 pour voir si elle répond bien : | Par le suite, nous avons configuré cette nouvelle interface avec la commande "ip address add 10.0.0.100/24 dev usb0" qui lui ajoute l'adresse 10.0.0.100 et un masque de classe C qui convient à nos besoins. A présent, nous pouvons faire un ping de l'adresse 10.0.0.2 pour voir si elle répond bien : | ||
[[Fichier:Ping usb0 2.png|alt=Ping vers la carte RNDIS|centré|vignette|Ping vers la carte RNDIS]] | [[Fichier:Ping usb0 2.png|alt=Ping vers la carte RNDIS|centré|vignette|Ping vers la carte RNDIS]] | ||
Il faut maintenant recevoir les paquets envoyés et vérifiés leur bonne réception sur le terminal. Pour rendre compte des paquets envoyés/reçus, nous allumons une LED à chaque ping : | Il faut maintenant recevoir les paquets envoyés et vérifiés leur bonne réception sur le terminal. Nous avons alors utiliser l'outil "ether" afin d'observer les paquets reçues sur l'interface "usb0" créée. Pour rendre compte des paquets envoyés/reçus, nous allumons une LED à chaque ping : | ||
[[Fichier:Reception .mp4|centré|vignette]] | [[Fichier:Reception .mp4|centré|vignette|Réception de paquets IP ]]A ce moment-là, la carte allume bien les LEDs lors de la récéption des mêmes paquets que ceux implémentés dans la pile TCP/IP. Puisque l'on veut utiliser nos propres paquets avec notre protocole, nous devons ajouter dans cette pile le traitement de notre protocole. | ||
Tout d'abord, dans le fichier "EthernerProtocols.h", nous avons créer notre protocole. Le notre sera "0x0903"<syntaxhighlight lang="c"> | |||
#define ETHERTYPE_PICO 0x0903 | |||
</syntaxhighlight>Ensuite, il faut créer une structure représentant notre trame dans un fichier permettant son traitement. Ici, e fichier s'appelle "PICO.h". Nous avons alors choisi d'utiliser cette structure de trame : <syntaxhighlight lang="c"> | |||
/** Type define for a PICO header. */ | |||
typedef struct | |||
{ | |||
MAC_Address_t Destination_MAC; /**< MAC address of the packet recipient */ | |||
MAC_Address_t Source_MAC; /**< MAC address of the packet source */ | |||
IP_Address_t Destination_IP; /**< IP address of the packet recipient */ | |||
IP_Address_t Source_IP; /**< IP address of the packet source */ | |||
uint16_t PICOType; /**< PICO packet sub-protocol type*/ | |||
}PICO_Header_t; | |||
</syntaxhighlight>Dans le fichier c, il faut alors réaliser le traitement de cette trame pour créer la réponse : <syntaxhighlight lang="c"> | |||
int16_t PICO_ProcessPICOPacket(void* InDataStart, | |||
void* OutDataStart) | |||
{ | |||
PICO_Header_t* PICOHeaderIN = (PICO_Header_t*)InDataStart; | |||
PICO_Header_t* PICOHeaderOUT = (PICO_Header_t*)OutDataStart; | |||
/* Ensure that the PICO request is a PICO request packet */ | |||
if (SwapEndian_16(PICOHeaderIN->PICOType) == ETHERTYPE_PICO) | |||
{ | |||
if (IP_COMPARE(&PICOHeaderIN->Destination_IP, &ServerIPAddress)|| | |||
MAC_COMPARE(&PICOHeaderIN->Destination_MAC, &ServerMACAddress)) | |||
{ | |||
/* Fill out the PICO response header */ | |||
PICOHeaderOUT->Destination_MAC = PICOHeaderIN->Source_MAC; | |||
PICOHeaderOUT->Source_MAC = ServerMACAddress; | |||
PICOHeaderOUT->Destination_IP = PICOHeaderIN->Source_IP; | |||
PICOHeaderOUT->Source_IP = ServerIPAddress; | |||
PICOHeaderOUT->PICOType = PICOHeaderIN->PICOType; | |||
/* Blink the LED */ | |||
PORTC ^= 0x30; | |||
/* Return the size of the response so far */ | |||
return sizeof(PICO_Header_t); | |||
} | |||
} | |||
return NO_RESPONSE; | |||
} | |||
</syntaxhighlight>De cette façon, lorsqu'une trame respectant notre forme et utilisant notre protocole est envoyé sur l'interface, la LED de la carte devrait clignoter. | |||
Enfin, il faut aussi adapter le fichier "ProtocolsDecoders" afin que la LUFA arraive à décoder notre trame : <syntaxhighlight lang="c"> | |||
void DecodePICOFrameHeader(void* InDataStart) | |||
{ | |||
PICO_Header_t* PICOHeader = (PICO_Header_t*)InDataStart; | |||
printf_P(PSTR(" \\\r\n PICO\r\n")); | |||
if (!(IP_COMPARE(&PICOHeader->Destination_IP, &ServerIPAddress)) && | |||
!(IP_COMPARE(&PICOHeader->Destination_IP, &BroadcastIPAddress))) | |||
{ | |||
printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n")); | |||
return; | |||
} | |||
printf_P(PSTR(" + MAC Dest: %u:%u:%u:%u:%u:%u\r\n"), PICOHeader->Destination_MAC.Octets[0], | |||
PICOHeader->Destination_MAC.Octets[1], | |||
PICOHeader->Destination_MAC.Octets[2], | |||
PICOHeader->Destination_MAC.Octets[3], | |||
PICOHeader->Destination_MAC.Octets[4], | |||
PICOHeader->Destination_MAC.Octets[5]); | |||
printf_P(PSTR(" + MAC Source : %u:%u:%u:%u:%u:%u\r\n"), PICOHeader->Source_MAC.Octets[0], | |||
PICOHeader->Source_MAC.Octets[1], | |||
PICOHeader->Source_MAC.Octets[2], | |||
PICOHeader->Source_MAC.Octets[3], | |||
PICOHeader->Source_MAC.Octets[4], | |||
PICOHeader->Source_MAC.Octets[5]); | |||
printf_P(PSTR(" + IP Dest : %u:%u:%u:%u\r\n"), PICOHeader->Destination_IP.Octets[0], | |||
PICOHeader->Destination_IP.Octets[1], | |||
PICOHeader->Destination_IP.Octets[2], | |||
PICOHeader->Destination_IP.Octets[3]); | |||
printf_P(PSTR(" + IP Source : %u:%u:%u:%u\r\n"), PICOHeader->Source_IP.Octets[0], | |||
PICOHeader->Source_IP.Octets[1], | |||
PICOHeader->Source_IP.Octets[2], | |||
PICOHeader->Source_IP.Octets[3]); | |||
printf_P(PSTR(" + Protocol : %x\r\n"), SwapEndian_16(PICOHeader->PICOType)); | |||
} | |||
</syntaxhighlight>Après cela, nous pouvons envoyer une trame sur l'interface "usb0" utilisant notre protocole. Pour cela, nous avons modifié l'outil "ether" pour observer directement l'interface "usb0" et aussi pour que le filtre accepte notre protocole. En envoyant alors la trame, la LED s'allume bien correctement : | |||
[[Fichier:WhatsApp Video 2023-12-21 at 11.58.12.mp4|centré|vignette|Carte RNDIS réagissant à notre propre trame]] | |||
Cependant, on remarque que la LED s'allume, c'est-à-dire que la réponse est bien créée, mais elle n'est pas envoyée. En rem | |||
== Rendus : == | == Rendus : == | ||
Lien de notre GIT : https://archives.plil.fr/ncazin/Projet_Pico_SE4.git | Lien de notre GIT : https://archives.plil.fr/ncazin/Projet_Pico_SE4.git |
Version du 28 décembre 2023 à 11:37
Matériel :
Préparation de la carte Shield :
Pour la première séance de TP, nous avons dû souder des composants sur la carte Shield fournie. Nous nous sommes alors séparés, un qui faisait la soudure, et un autre préparant les câble reliant la carte Shield aux cartes filles.
Pour les câbles, nous avons comparé notre travail avec le câble de l'enseignant. Le plus dur était de savoir dans quel sens mettre les fiches HE10 femelle, un renfoncement permet heureusement de savoir le sens dans lequel insérer le câble. Après cela, le câble est un peu fragile si on tire dessus, nous avons donc replier le câble et mis un bloqueur pour augmenter sa résistance. Nous avons réalisé au total 3 câbles, donc un de plus que le nombre de base au cas où un des câbles ne fonctionne pas. Voici une photo des trois câbles :
Par la suite, nous avons dû souder une carte Shield pouvant être ajoutée à un Arduino Uno. Cette carte Shield était déjà partiellement soudée. De plus nous avons dû souder 2 connecteurs permettant la jonction avec les cartes . Voici une photo de la carte soudée :
Ordonnanceur
1) Clignotement de 2 LEDs
Nous avons commencé l'ordonnanceur avec l'objectif de faire clignoter dans un premier temps 2 LEDs, à l'aide de deux tâches statiques, avec des périodes différentes.
Pour cela, nous avons utilisé un ISR permettant de gérer plusieurs tâches en même temps. Avant cela, il y a des fonctions de gestion et de restitution des registres afin que l'ISR commence le programme avec tous les registres à 0. Nous avons utilisé le lien suivant pour nous aider : https://tvantroys.plil.fr/IMA4/system/Multitasking%20on%20an%20AVR.pdf. Ensuite, nous avons implémenté un "scheduler" avec tout d'abord une première version où nous utilisions des "_delay_ms_". Par la suite, une mise à jour de ce "scheduler" s'imposait afin de supprimer les _delay_ms_ pour que chaque tâche possède son propre délai.
void scheduler(void){
for(int i = 0; i < MAX_TASKS; i++){
if(tasks[i].state == SLEEPING && tasks[i].reason == DELAY){
uint16_t time = 20;
if(TCNT1 != 0){
time = TCNT1 * 200 / OCR1A / 10;
TCNT1 = 0;
}
tasks[i].duration = tasks[i].duration - time;
if(tasks[i].duration <= 0) { tasks[i].state = WORKING; }
}
}
do{
actuel++;
if(actuel == MAX_TASKS) { actuel = 0; }
} while(tasks[actuel].state == SLEEPING);
}
ISR(TIMER1_COMPA_vect,ISR_NAKED){
/* Sauvegarde du contexte de la tâche interrompue */
portSAVE_CONTEXT();
tasks[actuel].StackPointeur = SP;
/* Appel à l'ordonnanceur */
scheduler();
/* Récupération du contexte de la tâche ré-activée */
SP = tasks[actuel].StackPointeur;
portRESTORE_CONTEXT();
asm volatile ("reti");
}
Au final, nous arrivons à faire clignoter 2 LEDs avec deux périodes différentes :
2) Ecriture de caractères sur le port série
Tout d'abord, avant de commencer la tâche, nous savions que nous devions utiliser l'UART du microcontrolleur. De plus, la tâche suivante devait utiliser aussi l'UART. Puisque 2 tâches utilisent la même ressource, il faut implémenter un système pour savoir quelle tâche utilise la ressource. Nous avons alors utiliser une sémaphore pour chaque tâche, permettant ainsi de limiter l'accès temporairement à la ressources aux autres tâches :
void semaphore_write(int action){
if(action == TAKE_RESOURCE){
while(1){
cli();
/** Ressource Disponible */
if(sem_writing > 0){
sem_writing = 0;
sei();
break;
}
/** Ressource occupée */
else{
tasks[actuel].reason = WORKING;
tasks[actuel].state = SLEEPING;
TCNT1 = 0;
TIMER1_COMPA_vect();
}
sei();
while(sem_writing == 0);
}
}
if(action == DROP_RESOURCE){
cli();
sem_writing = 1;
sei();
}
}
Après avoir implémenté cette sémaphore, il fallait que nous comprenions comment utiliser l'UART du microcontrôlleur. Pour cela, il faut initialiser correctement l'UART pour pouvoir écrire et lire en série. La fonction suivante permet d'initialiser correctement l'UART :
void init_usart(long int speed){
UBRR0 = FREQUENCE/((unsigned long int)speed << 4) -1;
UCSR0B = (1 << TXEN0 | 1 << RXEN0);
UCSR0C = (1 << UCSZ01 | 1 << UCSZ00);
UCSR0A &= ~(1 << U2X0);
}
Enfin, une fois l'initialisation réalisée, nous pouvons réaliser la tâche utilisant les fonctions permettant d'écrire plusieurs caractères (ici "abc") sur le port série, que l'on peut observer grâce à la commande shell "minicom -D /dev/ttyUSB0 -b 9600". On utilise alors les fonctions suivantes pour écrire sur le port série :
void serial_send(unsigned char c){
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = c;
}
void serial_send_str(char chaine[]){
semaphore_write(TAKE_RESOURCE);
for(int i = 0; i < SIZE_CHAINE; i++){
serial_send(chaine[i]);
}
semaphore_write(DROP_RESOURCE);
}
On peut observer que la tâche fonctionne comme sur la vidéo suivante :
3) Lecture sur le port série
De la même façon que la tâche précédente, pour cette tâche nous devons lire les pressions de touches du clavier et les afficher sur le minicom. L'initialisation est déjà efféctuée et la sémaphore et la même que dans la partie précédente, nous ne la traiterons donc pas. On utilise alors les fonctions suivantes pour lire les pressions des touches sur le clavier, et la tâche les fait afficher ensuite :
unsigned char serial_read(void){
loop_until_bit_is_set(UCSR0A, RXC0);
return UDR0;
}
void serial_read_str(char chaine[]){
semaphore_read(TAKE_RESOURCE);
for(int i = 0; i < SIZE_CHAINE; i++){
chaine[i] = serial_read();
}
semaphore_read(DROP_RESOURCE);
}
On peut alors observer les résultats grâce à la vidéo suivante :
4) Matrice de LEDs
Dans cette partie, nous souhaitons gérer l'affichage d'une matrice de LEDs 8x8 grâce au SPI. Il faut alors réussir à initialiser le SPI correctement :
void SPI_MasterInit(void){
DDRB |= (1 << MOSI) | (1 << SCK) | (1 << SS);
DDRC |= (1 << CS);
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0);
}
Ensuite, nous avons rédiger un programme utilisé par notre tâche afin d'afficher différents caractères sur la matrice en allumant les LEDs voulues bit par bit :
void loop_matrix(char letter[8]){
int temp;
PORTC &= ~(1 << CS);
for(short int i = 0; i < 8; i++){
for(short int j = 0; j < 8; j++)
{
temp = letter[i] & (1 << j);
diplayLED(temp); //Envoir de chaque bit sur le SPI
}
}
PORTC |= (1 << CS);
}
Après vérification du bon fonctionnement de notre programme, nous avons ajouté la fonction principale dans notre fichier de gestion des tâches. Nous pouvons alors voir le changement des LEDs allumées lorsque l'on appuie sur un autre caractère grâce à la vidéo suivante :
5) Afficheur 7 segments
Pour le 7 segments, l'initialisation est différente. En effet, le 7 segments ne fonctionne qu'à une fréquence maximale de 250kHz, il faut alors modifier l'initialisation du SPI de la tâche pour le faire fonctionner en changeant le paramètre SPCR :
void SPI_MasterInit_segments(void){
DDRB |= (1 << MOSI) | (1 << SCK) | (1 << SS);
DDRC |= (1 << CS);
PORTB |= (1 << SS);
PORTC |= (1 << CS);
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0) | (1 << SPR1); //SPR1 & SPR0 à 1 pour une fréquence en dessous de 250kHz (fréquence de l'afficheur 7 segments)
}
En envoyant alors la lettre appuyée sur le clavier, le 7segments convertit (si c'est posible) la lettre en segments à allumer comme nous pouvons le voir sur la vidéo suivante :
Carte FPGA/VHDL :
Carte fille réseau RNDIS :
1) Création de la carte électronique RNDIS
Nous avons choisi de réaliser la carte réseau RNDIS car nous pensons que ce projet était aussi en lien avec nos cours de réseau et de système d'exploitation, cette carte était pour nous un moyen d'en apprendre plus sur ces aspects.
La première chose à faire était de réaliser la carte électronique. Pour cela, des informations nous sont fournies. On sait alors que le microcontrôleur a utiliser doit avoir des capacités USB et que l'on peut utiliser soit un ATMega16u2, un ATMega32u4 ou un AT90USB suivant la mémoire que l'on veut disposer. Nous avons choisi d'utiliser un ATMega16u2 car nous en avions déjà utiliser un lors de notre projet en SE3 et nous étions plus à l'aise avec.
Ensuite, nous avons commencé à faire le schéma électrique de la carte réseau. Nous avons commencé à mettre les composants pour faire fonctionner le microcontrôleur de la même façon que sur le projet de SE3. Après cela, nous avons commencé à faire les entrées et sorties. On sait que la carte va communiquer avec la carte mère via un connecteur HE10, des signaux MISO, MOSI, SCK et CS sont alors à connecter au microcontrôlleur. Nous avons choisi d'utiliser les ports suivants :
- SCK ==> PB1
- MOSI ==> PB2
- MISO ==> PB3
- CS ==> PB4
De cette façon, nous pouvons récupérer et envoyer simplement des informations depuis la carte mère. Nous avons aussi connecté des LEDs sur les ports PC4 à PC7. Les autres ports sont connectés à des testpoints. La communication RNDIS se faisant via le port USB, nous avons aussi implémenter un port USB communicant via D+ et D-. Par sécurité, nous avons aussi mis un AVR-ISP dans le cas où la programmation du microcontrôleur se fasse pas correctement. Voici alors le schéma électrique de notre carte RNDIS :
Après avoir réalisé le schéma électrique, nous avons fait le routage de la carte. Le routage était simple, nous avons commencé par router les parties USB et microcontôleur car nous savons comment elles doivent êtres disposées. Le plus difficile dans ce routage a été de mettre le capacités les plus proches du quartz et du microcontôleur car nous avons essayé de faire une carte compacte, et les testpoints prennent beaucoup de place sur la carte. Il fallait donc être précis sur la disposition des composants. Il fallait aussi faire attention à ce que les pistes D+ et D- soient les plus courtes et avec le moins de via possibles pour ne pas endommager les signaux que l'on souhaite envoyer. Nous avons fait le plan de masse de la carte et au final nous avons réussi à compacter la carte pour qu'elle fasse une taille de 33mm x 43mm. Voici alors le routage de notre carte RNDIS.
Voici donc une réprésentation 3D de notre carte RNDIS :
Nous avons alors routé notre carte, il fallait donc faire un fichier ZIP à partir de ces fichiers afin que la carte puisse être envoyée en production pour que l'on puisse souder les composants par la suite. Nous avons donc suivi les étapes de ce tutoriel : https://jlcpcb.com/help/article/16-How-to-generate-Gerber-and-Drill-files-in-KiCad-6.
2) Soudure de la carte électronique RNDIS
Durant deux séances, nous avons réalisé la soudure de la carte électronique sur laquelle nous avons été aidés pour souder le quartz ainsi que le port USB. A noter que sur la carte, deux diodes ont été enlevées au niveau de l'USB car il était impossible de la reconnaître par notre machine grâce à la commande "lsusb". Hormis les diodes à enlever, aucune difficulté n'a été relevée durant la soudure de la carte.
Au final, nous avons donc une carte électronique fonctionnelle et prête à être programmée.
Voici une photo de la carte soudée :
Au final, la carte est bien reconnue grâce à la commande "lsusb" :
Après cela, nous allons entamé la programmation pour avoir une communication RNDIS.
3) Programmation de la carte électronique RNDIS
Pour la programmation de la carte électronique RNDIS, nous avons utilisé une démonstration LUFA déjà existante qui implémente une pile TCP/IP. En faisant directement un "make", nous avons remarqué que l'espace mémoire était dépassée. En effet, notre microcontrôleur ATMega16u2 n'a que 2k de mémoire.
Pour réduire la taille du programme, nous avons déjà réduit la taille de la trame Ethernet qui est de 1500 octets à 100 octets. Ensuite nous avons réduit la pile TCP/IP en supprimant les fichiers UDP, TCP et Webserveur qui ne nous étaient pas utiles dans le fonctionnement de notre carte. Après la commande "make", un fichier hex est bien créé mais nous avons dû changer ce fichier Makefile en conséquence pour l'adapter à notre microcontrôleur.
Après un upload du programme sur notre carte, nous avons réussi à obtenir une nouvelle interface réseau nommée "usb0" que l'on a pu visualiser grâce à la commande "ip a".
Par le suite, nous avons configuré cette nouvelle interface avec la commande "ip address add 10.0.0.100/24 dev usb0" qui lui ajoute l'adresse 10.0.0.100 et un masque de classe C qui convient à nos besoins. A présent, nous pouvons faire un ping de l'adresse 10.0.0.2 pour voir si elle répond bien :
Il faut maintenant recevoir les paquets envoyés et vérifiés leur bonne réception sur le terminal. Nous avons alors utiliser l'outil "ether" afin d'observer les paquets reçues sur l'interface "usb0" créée. Pour rendre compte des paquets envoyés/reçus, nous allumons une LED à chaque ping :
A ce moment-là, la carte allume bien les LEDs lors de la récéption des mêmes paquets que ceux implémentés dans la pile TCP/IP. Puisque l'on veut utiliser nos propres paquets avec notre protocole, nous devons ajouter dans cette pile le traitement de notre protocole. Tout d'abord, dans le fichier "EthernerProtocols.h", nous avons créer notre protocole. Le notre sera "0x0903"
#define ETHERTYPE_PICO 0x0903
Ensuite, il faut créer une structure représentant notre trame dans un fichier permettant son traitement. Ici, e fichier s'appelle "PICO.h". Nous avons alors choisi d'utiliser cette structure de trame :
/** Type define for a PICO header. */
typedef struct
{
MAC_Address_t Destination_MAC; /**< MAC address of the packet recipient */
MAC_Address_t Source_MAC; /**< MAC address of the packet source */
IP_Address_t Destination_IP; /**< IP address of the packet recipient */
IP_Address_t Source_IP; /**< IP address of the packet source */
uint16_t PICOType; /**< PICO packet sub-protocol type*/
}PICO_Header_t;
Dans le fichier c, il faut alors réaliser le traitement de cette trame pour créer la réponse :
int16_t PICO_ProcessPICOPacket(void* InDataStart,
void* OutDataStart)
{
PICO_Header_t* PICOHeaderIN = (PICO_Header_t*)InDataStart;
PICO_Header_t* PICOHeaderOUT = (PICO_Header_t*)OutDataStart;
/* Ensure that the PICO request is a PICO request packet */
if (SwapEndian_16(PICOHeaderIN->PICOType) == ETHERTYPE_PICO)
{
if (IP_COMPARE(&PICOHeaderIN->Destination_IP, &ServerIPAddress)||
MAC_COMPARE(&PICOHeaderIN->Destination_MAC, &ServerMACAddress))
{
/* Fill out the PICO response header */
PICOHeaderOUT->Destination_MAC = PICOHeaderIN->Source_MAC;
PICOHeaderOUT->Source_MAC = ServerMACAddress;
PICOHeaderOUT->Destination_IP = PICOHeaderIN->Source_IP;
PICOHeaderOUT->Source_IP = ServerIPAddress;
PICOHeaderOUT->PICOType = PICOHeaderIN->PICOType;
/* Blink the LED */
PORTC ^= 0x30;
/* Return the size of the response so far */
return sizeof(PICO_Header_t);
}
}
return NO_RESPONSE;
}
De cette façon, lorsqu'une trame respectant notre forme et utilisant notre protocole est envoyé sur l'interface, la LED de la carte devrait clignoter. Enfin, il faut aussi adapter le fichier "ProtocolsDecoders" afin que la LUFA arraive à décoder notre trame :
void DecodePICOFrameHeader(void* InDataStart)
{
PICO_Header_t* PICOHeader = (PICO_Header_t*)InDataStart;
printf_P(PSTR(" \\\r\n PICO\r\n"));
if (!(IP_COMPARE(&PICOHeader->Destination_IP, &ServerIPAddress)) &&
!(IP_COMPARE(&PICOHeader->Destination_IP, &BroadcastIPAddress)))
{
printf_P(PSTR(" + NOT ADDRESSED TO DEVICE\r\n"));
return;
}
printf_P(PSTR(" + MAC Dest: %u:%u:%u:%u:%u:%u\r\n"), PICOHeader->Destination_MAC.Octets[0],
PICOHeader->Destination_MAC.Octets[1],
PICOHeader->Destination_MAC.Octets[2],
PICOHeader->Destination_MAC.Octets[3],
PICOHeader->Destination_MAC.Octets[4],
PICOHeader->Destination_MAC.Octets[5]);
printf_P(PSTR(" + MAC Source : %u:%u:%u:%u:%u:%u\r\n"), PICOHeader->Source_MAC.Octets[0],
PICOHeader->Source_MAC.Octets[1],
PICOHeader->Source_MAC.Octets[2],
PICOHeader->Source_MAC.Octets[3],
PICOHeader->Source_MAC.Octets[4],
PICOHeader->Source_MAC.Octets[5]);
printf_P(PSTR(" + IP Dest : %u:%u:%u:%u\r\n"), PICOHeader->Destination_IP.Octets[0],
PICOHeader->Destination_IP.Octets[1],
PICOHeader->Destination_IP.Octets[2],
PICOHeader->Destination_IP.Octets[3]);
printf_P(PSTR(" + IP Source : %u:%u:%u:%u\r\n"), PICOHeader->Source_IP.Octets[0],
PICOHeader->Source_IP.Octets[1],
PICOHeader->Source_IP.Octets[2],
PICOHeader->Source_IP.Octets[3]);
printf_P(PSTR(" + Protocol : %x\r\n"), SwapEndian_16(PICOHeader->PICOType));
}
Après cela, nous pouvons envoyer une trame sur l'interface "usb0" utilisant notre protocole. Pour cela, nous avons modifié l'outil "ether" pour observer directement l'interface "usb0" et aussi pour que le filtre accepte notre protocole. En envoyant alors la trame, la LED s'allume bien correctement :
Cependant, on remarque que la LED s'allume, c'est-à-dire que la réponse est bien créée, mais elle n'est pas envoyée. En rem
Rendus :
Lien de notre GIT : https://archives.plil.fr/ncazin/Projet_Pico_SE4.git