<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://projets-se.plil.fr/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jwacquet</id>
	<title>projets-se.plil.fr - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="https://projets-se.plil.fr/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jwacquet"/>
	<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php/Sp%C3%A9cial:Contributions/Jwacquet"/>
	<updated>2026-09-20T13:33:19Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.39.1</generator>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=7396</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=7396"/>
		<updated>2025-01-26T17:03:11Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Protocole: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test carte SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier si le lecteur est fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segments pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause du défaut de conception, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une exécution en parallèle des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les LEDs lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des LEDs en 5 programmes, 1 pour chaque LED. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi fait une fonction d'initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, on veut pouvoir endormir des tâches pendant une durée définie. Ces tâches doivent être ignorées par le scheduler.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons rajouté une durée d'endormissement dans la structure tab_process et un programme qui réduit le temps de sommeil à chaque interruption puis un programme qui endort la tâche ciblée.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define TIME_INTERRUPT 20&lt;br /&gt;
&lt;br /&gt;
void DecreaseSleep(void)&lt;br /&gt;
{&lt;br /&gt;
   int nb_sleep = 0;&lt;br /&gt;
   for (uint8_t i=1;i&amp;lt;NB_PROCESS-1;i++)&lt;br /&gt;
   {&lt;br /&gt;
     if (tab_process[i].sleep &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        tab_process[i].sleep -= TIME_INTERRUPT;&lt;br /&gt;
        nb_sleep++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setTimeDelay(uint16_t time, uint8_t process)&lt;br /&gt;
{&lt;br /&gt;
  tab_process[process].sleep=time;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi modifié le scheduler :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On a rajouté une condition au passage à la tâche suivante : si la prochaine tâche est endormie, on l'ignore et on regarde l'état de la prochaine jusqu'à avoir une tache éveillée.&lt;br /&gt;
&lt;br /&gt;
On peut repérer un problème : que se passe-t-il si toutes les tâches sont endormies ? On pourrait faire confiance à l'utilisateur en priant pour qu'il n'endorme pas tout le monde mais nous avons préféré ne pas lui faire confiance.&lt;br /&gt;
&lt;br /&gt;
Nous avons donc crée un processus qui est naturellement endormi mais qui se réveille lorsque tout le monde dort, pour éviter une boucle infinie.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Anti_sleep_boucle(void)&lt;br /&gt;
{&lt;br /&gt;
  while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ajoute à setup&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[NB_PROCESS-1].process_add = Anti_sleep_boucle;&lt;br /&gt;
    tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
    tab_process[NB_PROCESS-1].StackPointer = 0x3ff;&lt;br /&gt;
    tab_process[NB_PROCESS-1].state = 1;&lt;br /&gt;
}&lt;br /&gt;
 // ajoute à DecreaseSleep &lt;br /&gt;
&lt;br /&gt;
if (nb_sleep ==  NB_PROCESS-2)&lt;br /&gt;
   {&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On accorde les autres programmes à Anti_sleep_boucle, on a décidé qu'il sera le dernier processus par soucis de simplicité.[[Fichier:Video des LEDs ordonnancé.mp4|vignette&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Video des LEDs ordonnancées|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bonus :&lt;br /&gt;
&lt;br /&gt;
Nous avons amélioré le makefile donné par Mr Boé l'année dernière :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// modification pour un nettoyer plus efficace&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f *.o&lt;br /&gt;
	rm -f *.hex&lt;br /&gt;
	rm -f *.elf&lt;br /&gt;
// modification pour pouvoir upload directement les modfications sur la carte&lt;br /&gt;
upload: $(TARGET).hex&lt;br /&gt;
	stty -F $(TERM) hupcl # reset&lt;br /&gt;
	avrdude -p atmega328p -c arduino -P /dev/ttyUSB0 \ -b 115200 -D -U flash:w:ordonnanceur.hex:i&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;br /&gt;
&lt;br /&gt;
=== Brasure ===&lt;br /&gt;
Le PCB de la Pipelette v1 est arrivée, on peut donc aller braser sans plus tarder.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:PCB nu.jpg|vignette|PCB en manque de composants.|centré|275x275px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
La brasure se passe bien sauf au moment où l'on a remarqué qu'on a confondu l'empreinte du jumper avec celle d'un connecteur de batterie... On a rattrapé l'erreur en brasant un interupteur à l'arrière de la carte.&lt;br /&gt;
[[Fichier:Interrupteur surprise.jpg|vignette|Interrupteur remplacant le jumper à l'arrière.|centré|232x232px]]&lt;br /&gt;
Mise à part ce soucis, tout est en ordre et la carte est brasée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Pico brase.jpg|vignette|PCB plus en manque de composants.|centré|337x337px]]&lt;br /&gt;
&lt;br /&gt;
=== Programmation de la carte ===&lt;br /&gt;
Cette section est dédiée à la programmation de la carte. Tout d'abord, en utilisant les codes RNDIS de la LUFA, notre carte est détectée comme on peut le voir avec un lsusb.&lt;br /&gt;
[[Fichier:LSUSB RNDIS.jpg|vignette|Lsusb qui détecte la carte.|centré|1094x1094px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ensuite, on lui a attribué une adresse IP 10.0.0.1 qui est l'IP client défini dans l'exemple LUFA.&lt;br /&gt;
&lt;br /&gt;
Enfin, avec un ip a, on remarque qu'elle a son interface usb0 et qu'elle est DOWN. Avec un ip link set usb0 up, la carte est prête à communiquer.&lt;br /&gt;
[[Fichier:Ipa2.png|centré|vignette|854x854px|ip a où l'on voit la carte (interface usb0)]]&lt;br /&gt;
En effet elle est belle est bien prête à communiquer car on arrive à la ping comme le montre la vidéo.&lt;br /&gt;
[[Fichier:Ping2.mp4|centré|vignette|Ping de la carte (et la LED qui clignote lorsqu'elle reçoit le ping)]]&lt;br /&gt;
Le ping fonctionne par usb donc on peut communiquer avec l'extérieur, maintenant il faut le faire aussi par port SPI pour communiquer avec la carte mère.&lt;br /&gt;
[[Fichier:Pong.mp4|centré|vignette|Vidéo test de communication par SPI]]&lt;br /&gt;
[[Fichier:Pongscreen.png|centré|vignette|Pong]]&lt;br /&gt;
Pour cela, on a pris le code pong.c fourni par Mr Redon qui permet de tester la communication par SPI. Le premier essai s'avère être un échec. Le problème venait d'une erreur de conception du shield. On a eu le même problème que le binôme 7 donc on a fait la même manipulation et la communication par SPI fonctionne ! On arrive donc à communiquer avec l'Arduino.&lt;br /&gt;
&lt;br /&gt;
=== Protocole: ===&lt;br /&gt;
Pour envoyer et recevoir des paquets Ethernet avec le PC et la carte, on doit développer notre propre protocole. On a développé un premier protocole test appelé GPOAT (Greatest Protocol Of All Time) qui est composé de la manière suivante:&lt;br /&gt;
[[Fichier:Gpoat.png|centré|vignette|504x504px|Structure d'un paquet GPOAT]]&lt;br /&gt;
Le but de ce paquet est de recevoir 2 nombres de 16 octets et y effectuer une opération qui dépend du bit de point faible de Operation.&lt;br /&gt;
&lt;br /&gt;
Pour reconnaitre ce protocole, on a fait un nouvel Ether Type &amp;quot;GPOAT&amp;quot; référencé à 0x2706 qu'on déclare dans le fichier EthernetProtocole.h.&lt;br /&gt;
&lt;br /&gt;
La fonction de traitement du code et tiré de celle du protocole ARP .&lt;br /&gt;
&lt;br /&gt;
Voici comment est traité le paquet et comment la réponse est forgée:&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
GPOATHeaderOUT-&amp;gt;TMA = GPOATHeaderIN-&amp;gt;SMA;&lt;br /&gt;
			GPOATHeaderOUT-&amp;gt;TIA = GPOATHeaderIN-&amp;gt;SIA;&lt;br /&gt;
&lt;br /&gt;
			/* Copy over the new sender MAC/IP - MAC and IP addresses of the virtual webserver */&lt;br /&gt;
			GPOATHeaderOUT-&amp;gt;SMA = ServerMACAddress;&lt;br /&gt;
			GPOATHeaderOUT-&amp;gt;SIA = ServerIPAddress;&lt;br /&gt;
			/*Compute the result of the equation */&lt;br /&gt;
			uint32_t tmp_d1 = 0;&lt;br /&gt;
			uint32_t tmp_d2 = 0; //j'utilise des tampons 2 fois plus grand pour éviter l'overflow lors des calculs&lt;br /&gt;
			tmp_d1 |=GPOATHeaderIN-&amp;gt;Data1;&lt;br /&gt;
			tmp_d2 |=GPOATHeaderIN-&amp;gt;Data2;&lt;br /&gt;
			switch(GPOATHeaderIN-&amp;gt;Operation)&lt;br /&gt;
			{&lt;br /&gt;
				case 0x01:/*addition */&lt;br /&gt;
					GPOATHeaderOUT-&amp;gt;Data1 = SwapEndian_16((tmp_d1 + tmp_d2) &amp;gt;&amp;gt; 16);//on garde la moitié &amp;quot;gauche&amp;quot;&lt;br /&gt;
					GPOATHeaderOUT-&amp;gt;Data2 = (tmp_d1 + tmp_d2) &amp;amp; 0xffff;//on garde la moitié &amp;quot;droite&amp;quot;&lt;br /&gt;
					break;&lt;br /&gt;
				case 0x02:/*soustraction*/&lt;br /&gt;
					GPOATHeaderOUT-&amp;gt;Data1 = SwapEndian_16((tmp_d1 - tmp_d2) &amp;gt;&amp;gt; 16);//on garde la moitié &amp;quot;gauche&amp;quot;&lt;br /&gt;
					GPOATHeaderOUT-&amp;gt;Data2 = SwapEndian_16((tmp_d1 - tmp_d2) &amp;amp; 0xffff);//on garde la moitié &amp;quot;droite&amp;quot;&lt;br /&gt;
					break;&lt;br /&gt;
				case 0x03:/*multiple*/&lt;br /&gt;
					GPOATHeaderOUT-&amp;gt;Data1 = SwapEndian_16((tmp_d1 * tmp_d2) &amp;gt;&amp;gt; 16);//on garde la moitié &amp;quot;gauche&amp;quot;&lt;br /&gt;
					GPOATHeaderOUT-&amp;gt;Data2 = SwapEndian_16((tmp_d1 * tmp_d2) &amp;amp; 0xffff);//on garde la moitié &amp;quot;droite&amp;quot;&lt;br /&gt;
					break;&lt;br /&gt;
				case 0x04:/*division*/&lt;br /&gt;
					GPOATHeaderOUT-&amp;gt;Data1 = SwapEndian_16((tmp_d1 / tmp_d2) &amp;gt;&amp;gt; 16);  //on garde la moitié &amp;quot;gauche&amp;quot;&lt;br /&gt;
					GPOATHeaderOUT-&amp;gt;Data2 = SwapEndian_16((tmp_d1 / tmp_d2) &amp;amp; 0xffff);//on garde la moitié &amp;quot;droite&amp;quot;&lt;br /&gt;
					break;&lt;br /&gt;
			}&lt;br /&gt;
			GPOATHeaderOUT-&amp;gt;Operation = GPOATHeaderIN-&amp;gt;Operation | 0x10;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
On inverse les adresses sources et destinataires, après on vérifie qu'on a une question. Puis on fait les calculs en passant par un tampon et on indique qu'on fait une réponse.Dans l'exemple ci dessous, la carte reçoit 2 valeurs qui sont &amp;quot;ff ff&amp;quot; et il lui est demandé de les diviser entre eux, ce à quoi la carte répond avec comme valeur &amp;quot;1&amp;quot;.&lt;br /&gt;
[[Fichier:Gpoat test.png|centré|vignette|401x401px|Test d'envoi et réception d'un GPOAT (le premier est le paquet envoyé par le PC et le 2ème est la réponse de la carte)]]&lt;br /&gt;
&lt;br /&gt;
Si vous voulez tester le protocole, il y a un dossier GPOAT qui génère un paquet GPOAT. (Il faudra juste changer les data à la main.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que l'on sait comment créer un protocole, on peut créer un protocole qui va envoyer les commandes de la carte mère à un dépot distant ( un pc ) et qui va récupérer la réponse deu pc : le protocole KIFF. référencer par l'Ethertype 0x2911.&lt;br /&gt;
&lt;br /&gt;
Malheureusement, nous n'avons pas pu tester ce protocole.&lt;br /&gt;
&lt;br /&gt;
Voici la structure du protocole&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct&lt;br /&gt;
		{&lt;br /&gt;
			MAC_Address_t SMA; /**&amp;lt; Sender's Mac address */&lt;br /&gt;
			MAC_Address_t TMA; /**&amp;lt; Target's Mac address */&lt;br /&gt;
			uint8_t Operation; /* Reception 0x01 ou Envoi 0x00 */&lt;br /&gt;
			uint8_t Message; // Bit de point faible = 1 : ls, 2 = récuperer un fichier, 3 = envoyer un fichier&lt;br /&gt;
			uint8_t Data; /* Pour la réponse ( en uint8_t car la réponse va être envoyé par SPI à la carte mere)*/&lt;br /&gt;
		} KIFF_Header_t;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Avec la structure, on peut maintenant écrire la fonction de traitement des paquets :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
	KIFF_Header_t* KIFFHeaderIN  = (KIFF_Header_t*)InDataStart;&lt;br /&gt;
	KIFF_Header_t* KIFFHeaderOUT = (KIFF_Header_t*)OutDataStart;&lt;br /&gt;
		/* Ensure that the KIFF request is a request packet */&lt;br /&gt;
	if ((KIFFHeaderIN-&amp;gt;Operation) == KIFF_OPERATION_REPLY)&lt;br /&gt;
	{&lt;br /&gt;
		// Fonction qui envoit la data a la carte Mere&lt;br /&gt;
		SPDR = KIFFHeaderIN-&amp;gt;data;&lt;br /&gt;
&lt;br /&gt;
			return sizeof(KIFF_Header_t);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Cette fois au lieu de reformuler une réponse, on récupère les données et on l'envoie sur le bus SPI. &lt;br /&gt;
&lt;br /&gt;
== Ether : ==&lt;br /&gt;
Maintenant que l'on a un protocole qui sert à faire la communication entre la carte mère et le PC, il faut que le PC puisse interpréter le paquet et reformuler la réponse à la carte mère.&lt;br /&gt;
&lt;br /&gt;
Dans un premier temps on va stocker  les paquets que l'utilitaire ether va afficher.&lt;br /&gt;
&lt;br /&gt;
Tout d'abord, il faut que ether affiche nos paquets, pour cela on ajoute les protocoles dans le filtre de bpf.c :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
machineLanguage filterProgram[]={&lt;br /&gt;
 &lt;br /&gt;
 {NULL,      MLCOND_ANY,&lt;br /&gt;
	      BPF_LD|BPF_H|BPF_ABS, NULL, NULL, &amp;quot;12&amp;quot;},&lt;br /&gt;
  {NULL,      MLCOND_ANY,&lt;br /&gt;
	      BPF_JMP|BPF_JEQ,      &amp;quot;srcaddr&amp;quot;, &amp;quot;ipv6&amp;quot;, &amp;quot;0x800&amp;quot;},&lt;br /&gt;
  {&amp;quot;ipv6&amp;quot;,    MLCOND_ANY,&lt;br /&gt;
	      BPF_JMP|BPF_JEQ,      &amp;quot;srcaddr&amp;quot;, &amp;quot;gpoat&amp;quot;, &amp;quot;0x2706&amp;quot;},&lt;br /&gt;
  {&amp;quot;gpoat&amp;quot;,    MLCOND_ANY,&lt;br /&gt;
	      BPF_JMP|BPF_JEQ,      &amp;quot;srcaddr&amp;quot;, &amp;quot;arp&amp;quot;, &amp;quot;0x86dd&amp;quot;},&lt;br /&gt;
  {&amp;quot;arp&amp;quot;,     MLCOND_ANY, ....&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Puis lors de l'affiche des paquets, on en profite pour envoyer les paquets dans un fichier de traitements :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void displayPacket(FILE *stream,char *packet,int size){&lt;br /&gt;
  int i,count=MAX_COLUMNS;&lt;br /&gt;
  FILE * fichier = fopen(FICHIERPATH,&amp;quot;w&amp;quot;);&lt;br /&gt;
  for(i=0;i&amp;lt;size;i++){&lt;br /&gt;
    fprintf(stream,&amp;quot;%2.2x &amp;quot;,(unsigned char)packet[i]);&lt;br /&gt;
    fprintf(fichier,&amp;quot;%2.2x &amp;quot;,(unsigned char) packet[i]);&lt;br /&gt;
    count--;&lt;br /&gt;
    if(count&amp;lt;=0){ fprintf(stream,&amp;quot;\n&amp;quot;); count=MAX_COLUMNS; }&lt;br /&gt;
    }&lt;br /&gt;
  fclose(fichier);&lt;br /&gt;
  if(count!=MAX_COLUMNS) fprintf(stream,&amp;quot;\n&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malheureusement nous avons pas pu aller plus loin.&lt;br /&gt;
&lt;br /&gt;
==Bilan :==&lt;br /&gt;
Nous avons conçu un shield arduino sur lequel nous avons programmé un programme d'ordonnancement, qui peut exécuter en tourniquet plusieurs dont des tâches de communiquer par minicom.&lt;br /&gt;
Nous avons aussi conçu une carte fille réseau RNDIS et utilisé la lib LUFA pour la programmer.&lt;br /&gt;
Cette carte peut répondre au paquet classique ( ARP, IP, ... ) mais aussi à un protocole que l'on a crée.&lt;br /&gt;
&lt;br /&gt;
Par la suite, nous aurions pu faire un deuxième protocole, que transmet les infos qu'il reçoit à la carte mère via SPI, une fonction qui reçoit les commandes de la carte mère qu'elle envoie dans un paquet ethernet au dépot distant ( un pc ), une application sur le pc qui lors de la réception d'un paquet du protocole renvoie un paquet avec les données demandées.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=7388</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=7388"/>
		<updated>2025-01-26T16:39:19Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test carte SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier si le lecteur est fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segments pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause du défaut de conception, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une exécution en parallèle des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les LEDs lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des LEDs en 5 programmes, 1 pour chaque LED. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi fait une fonction d'initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, on veut pouvoir endormir des tâches pendant une durée définie. Ces tâches doivent être ignorées par le scheduler.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons rajouté une durée d'endormissement dans la structure tab_process et un programme qui réduit le temps de sommeil à chaque interruption puis un programme qui endort la tâche ciblée.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define TIME_INTERRUPT 20&lt;br /&gt;
&lt;br /&gt;
void DecreaseSleep(void)&lt;br /&gt;
{&lt;br /&gt;
   int nb_sleep = 0;&lt;br /&gt;
   for (uint8_t i=1;i&amp;lt;NB_PROCESS-1;i++)&lt;br /&gt;
   {&lt;br /&gt;
     if (tab_process[i].sleep &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        tab_process[i].sleep -= TIME_INTERRUPT;&lt;br /&gt;
        nb_sleep++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setTimeDelay(uint16_t time, uint8_t process)&lt;br /&gt;
{&lt;br /&gt;
  tab_process[process].sleep=time;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi modifié le scheduler :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On a rajouté une condition au passage à la tâche suivante : si la prochaine tâche est endormie, on l'ignore et on regarde l'état de la prochaine jusqu'à avoir une tache éveillée.&lt;br /&gt;
&lt;br /&gt;
On peut repérer un problème : que se passe-t-il si toutes les tâches sont endormies ? On pourrait faire confiance à l'utilisateur en priant pour qu'il n'endorme pas tout le monde mais nous avons préféré ne pas lui faire confiance.&lt;br /&gt;
&lt;br /&gt;
Nous avons donc crée un processus qui est naturellement endormi mais qui se réveille lorsque tout le monde dort, pour éviter une boucle infinie.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Anti_sleep_boucle(void)&lt;br /&gt;
{&lt;br /&gt;
  while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ajoute à setup&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[NB_PROCESS-1].process_add = Anti_sleep_boucle;&lt;br /&gt;
    tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
    tab_process[NB_PROCESS-1].StackPointer = 0x3ff;&lt;br /&gt;
    tab_process[NB_PROCESS-1].state = 1;&lt;br /&gt;
}&lt;br /&gt;
 // ajoute à DecreaseSleep &lt;br /&gt;
&lt;br /&gt;
if (nb_sleep ==  NB_PROCESS-2)&lt;br /&gt;
   {&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On accorde les autres programmes à Anti_sleep_boucle, on a décidé qu'il sera le dernier processus par soucis de simplicité.[[Fichier:Video des LEDs ordonnancé.mp4|vignette&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Video des LEDs ordonnancées|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bonus :&lt;br /&gt;
&lt;br /&gt;
Nous avons amélioré le makefile donné par Mr Boé l'année dernière :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// modification pour un nettoyer plus efficace&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f *.o&lt;br /&gt;
	rm -f *.hex&lt;br /&gt;
	rm -f *.elf&lt;br /&gt;
// modification pour pouvoir upload directement les modfications sur la carte&lt;br /&gt;
upload: $(TARGET).hex&lt;br /&gt;
	stty -F $(TERM) hupcl # reset&lt;br /&gt;
	avrdude -p atmega328p -c arduino -P /dev/ttyUSB0 \ -b 115200 -D -U flash:w:ordonnanceur.hex:i&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;br /&gt;
&lt;br /&gt;
=== Brasure ===&lt;br /&gt;
Le PCB de la Pipelette v1 est arrivée, on peut donc aller braser sans plus tarder.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:PCB nu.jpg|vignette|PCB en manque de composants.|centré|275x275px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
La brasure se passe bien sauf au moment où l'on a remarqué qu'on a confondu l'empreinte du jumper avec celle d'un connecteur de batterie... On a rattrapé l'erreur en brasant un interupteur à l'arrière de la carte.&lt;br /&gt;
[[Fichier:Interrupteur surprise.jpg|vignette|Interrupteur remplacant le jumper à l'arrière.|centré|232x232px]]&lt;br /&gt;
Mise à part ce soucis, tout est en ordre et la carte est brasée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Pico brase.jpg|vignette|PCB plus en manque de composants.|centré|337x337px]]&lt;br /&gt;
&lt;br /&gt;
=== Programmation de la carte ===&lt;br /&gt;
Cette section est dédiée à la programmation de la carte. Tout d'abord, en utilisant les codes RNDIS de la LUFA, notre carte est détectée comme on peut le voir avec un lsusb.&lt;br /&gt;
[[Fichier:LSUSB RNDIS.jpg|vignette|Lsusb qui détecte la carte.|centré|1094x1094px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ensuite, on lui a attribué une adresse IP 10.0.0.1 qui est l'IP client défini dans l'exemple LUFA.&lt;br /&gt;
&lt;br /&gt;
Enfin, avec un ip a, on remarque qu'elle a son interface usb0 et qu'elle est DOWN. Avec un ip link set usb0 up, la carte est prête à communiquer.&lt;br /&gt;
[[Fichier:Ipa2.png|centré|vignette|854x854px|ip a où l'on voit la carte (interface usb0)]]&lt;br /&gt;
En effet elle est belle est bien prête à communiquer car on arrive à la ping comme le montre la vidéo.&lt;br /&gt;
[[Fichier:Ping2.mp4|centré|vignette|Ping de la carte (et la LED qui clignote lorsqu'elle reçoit le ping)]]&lt;br /&gt;
Le ping fonctionne par usb donc on peut communiquer avec l'extérieur, maintenant il faut le faire aussi par port SPI pour communiquer avec la carte mère.&lt;br /&gt;
[[Fichier:Pong.mp4|centré|vignette|Vidéo test de communication par SPI]]&lt;br /&gt;
[[Fichier:Pongscreen.png|centré|vignette|Pong]]&lt;br /&gt;
Pour cela, on a pris le code pong.c fourni par Mr Redon qui permet de tester la communication par SPI. Le premier essai s'avère être un échec. Le problème venait d'une erreur de conception du shield. On a eu le même problème que le binôme 7 donc on a fait la même manipulation et la communication par SPI fonctionne ! On arrive donc à communiquer avec l'Arduino.&lt;br /&gt;
&lt;br /&gt;
=== Protocole: ===&lt;br /&gt;
Pour envoyer et recevoir des paquets Ethernet avec le PC et la carte, on doit développer notre propre protocole. On a développé un premier protocole test appelé GPOAT (Greatest Protocol Of All Time) qui est composé de la manière suivante:&lt;br /&gt;
[[Fichier:Gpoat.png|centré|vignette|504x504px|Structure d'un paquet GPOAT]]&lt;br /&gt;
Le but de ce paquet est de recevoir 2 nombres de 16 octets et y effectuer une opération qui dépend du bit de point faible de Operation.&lt;br /&gt;
&lt;br /&gt;
Pour reconnaitre ce protocole, on a fait un nouvel Ether Type &amp;quot;GPOAT&amp;quot; référencé à 0x2706.&lt;br /&gt;
&lt;br /&gt;
Ce protocole est intéressant car il permet de montrer que le PC peut envoyer un paquet à la carte, la carte réalise une action qui est l'opération demandé puis renvoie un paquet qui contient la réponse.&lt;br /&gt;
&lt;br /&gt;
Voici comment est traité le paquet et comment la réponse est forgée:&lt;br /&gt;
[[Fichier:Traitement.png|centré|vignette|752x752px|Traitement des données GPOAT]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l'exemple ci dessous, la carte reçoit 2 valeurs qui sont &amp;quot;ff ff&amp;quot; et il lui est demandé de les diviser entre eux, ce à quoi la carte répond avec comme valeur &amp;quot;1&amp;quot;.&lt;br /&gt;
[[Fichier:Gpoat test.png|centré|vignette|401x401px|Test d'envoi et réception d'un GPOAT (le premier est le paquet envoyé par le PC et le 2ème est la réponse de la carte)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Bilan :==&lt;br /&gt;
Nous avons conçu un shield arduino sur lequel nous avons programmé un programme d'ordonnancement, qui peut exécuter en tourniquet plusieurs dont des tâches de communiquer par minicom.&lt;br /&gt;
Nous avons aussi conçu une carte fille réseau RNDIS et utilisé la lib LUFA pour la programmer.&lt;br /&gt;
Cette carte peut répondre au paquet classique ( ARP, IP, ... ) mais aussi à un protocole que l'on a crée.&lt;br /&gt;
&lt;br /&gt;
Par la suite, nous aurions pu faire un deuxième protocole, que transmet les infos qu'il reçoit à la carte mère via SPI, une fonction qui reçoit les commandes de la carte mère qu'elle envoie dans un paquet ethernet au dépot distant ( un pc ), une application sur le pc qui lors de la réception d'un paquet du protocole renvoie un paquet avec les données demandées.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=7386</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=7386"/>
		<updated>2025-01-26T16:38:54Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test carte SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier si le lecteur est fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segments pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause du défaut de conception, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une exécution en parallèle des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les LEDs lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des LEDs en 5 programmes, 1 pour chaque LED. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi fait une fonction d'initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, on veut pouvoir endormir des tâches pendant une durée définie. Ces tâches doivent être ignorées par le scheduler.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons rajouté une durée d'endormissement dans la structure tab_process et un programme qui réduit le temps de sommeil à chaque interruption puis un programme qui endort la tâche ciblée.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define TIME_INTERRUPT 20&lt;br /&gt;
&lt;br /&gt;
void DecreaseSleep(void)&lt;br /&gt;
{&lt;br /&gt;
   int nb_sleep = 0;&lt;br /&gt;
   for (uint8_t i=1;i&amp;lt;NB_PROCESS-1;i++)&lt;br /&gt;
   {&lt;br /&gt;
     if (tab_process[i].sleep &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        tab_process[i].sleep -= TIME_INTERRUPT;&lt;br /&gt;
        nb_sleep++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setTimeDelay(uint16_t time, uint8_t process)&lt;br /&gt;
{&lt;br /&gt;
  tab_process[process].sleep=time;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi modifié le scheduler :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On a rajouté une condition au passage à la tâche suivante : si la prochaine tâche est endormie, on l'ignore et on regarde l'état de la prochaine jusqu'à avoir une tache éveillée.&lt;br /&gt;
&lt;br /&gt;
On peut repérer un problème : que se passe-t-il si toutes les tâches sont endormies ? On pourrait faire confiance à l'utilisateur en priant pour qu'il n'endorme pas tout le monde mais nous avons préféré ne pas lui faire confiance.&lt;br /&gt;
&lt;br /&gt;
Nous avons donc crée un processus qui est naturellement endormi mais qui se réveille lorsque tout le monde dort, pour éviter une boucle infinie.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Anti_sleep_boucle(void)&lt;br /&gt;
{&lt;br /&gt;
  while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ajoute à setup&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[NB_PROCESS-1].process_add = Anti_sleep_boucle;&lt;br /&gt;
    tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
    tab_process[NB_PROCESS-1].StackPointer = 0x3ff;&lt;br /&gt;
    tab_process[NB_PROCESS-1].state = 1;&lt;br /&gt;
}&lt;br /&gt;
 // ajoute à DecreaseSleep &lt;br /&gt;
&lt;br /&gt;
if (nb_sleep ==  NB_PROCESS-2)&lt;br /&gt;
   {&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On accorde les autres programmes à Anti_sleep_boucle, on a décidé qu'il sera le dernier processus par soucis de simplicité.[[Fichier:Video des LEDs ordonnancé.mp4|vignette&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Video des LEDs ordonnancées|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bonus :&lt;br /&gt;
&lt;br /&gt;
Nous avons amélioré le makefile donné par Mr Boé l'année dernière :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// modification pour un nettoyer plus efficace&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f *.o&lt;br /&gt;
	rm -f *.hex&lt;br /&gt;
	rm -f *.elf&lt;br /&gt;
// modification pour pouvoir upload directement les modfications sur la carte&lt;br /&gt;
upload: $(TARGET).hex&lt;br /&gt;
	stty -F $(TERM) hupcl # reset&lt;br /&gt;
	avrdude -p atmega328p -c arduino -P /dev/ttyUSB0 \ -b 115200 -D -U flash:w:ordonnanceur.hex:i&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;br /&gt;
&lt;br /&gt;
=== Brasure ===&lt;br /&gt;
Le PCB de la Pipelette v1 est arrivée, on peut donc aller braser sans plus tarder.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:PCB nu.jpg|vignette|PCB en manque de composants.|centré|275x275px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
La brasure se passe bien sauf au moment où l'on a remarqué qu'on a confondu l'empreinte du jumper avec celle d'un connecteur de batterie... On a rattrapé l'erreur en brasant un interupteur à l'arrière de la carte.&lt;br /&gt;
[[Fichier:Interrupteur surprise.jpg|vignette|Interrupteur remplacant le jumper à l'arrière.|centré|232x232px]]&lt;br /&gt;
Mise à part ce soucis, tout est en ordre et la carte est brasée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Pico brase.jpg|vignette|PCB plus en manque de composants.|centré|337x337px]]&lt;br /&gt;
&lt;br /&gt;
=== Programmation de la carte ===&lt;br /&gt;
Cette section est dédiée à la programmation de la carte. Tout d'abord, en utilisant les codes RNDIS de la LUFA, notre carte est détectée comme on peut le voir avec un lsusb.&lt;br /&gt;
[[Fichier:LSUSB RNDIS.jpg|vignette|Lsusb qui détecte la carte.|centré|1094x1094px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ensuite, on lui a attribué une adresse IP 10.0.0.1 qui est l'IP client défini dans l'exemple LUFA.&lt;br /&gt;
&lt;br /&gt;
Enfin, avec un ip a, on remarque qu'elle a son interface usb0 et qu'elle est DOWN. Avec un ip link set usb0 up, la carte est prête à communiquer.&lt;br /&gt;
[[Fichier:Ipa2.png|centré|vignette|854x854px|ip a où l'on voit la carte (interface usb0)]]&lt;br /&gt;
En effet elle est belle est bien prête à communiquer car on arrive à la ping comme le montre la vidéo.&lt;br /&gt;
[[Fichier:Ping2.mp4|centré|vignette|Ping de la carte (et la LED qui clignote lorsqu'elle reçoit le ping)]]&lt;br /&gt;
Le ping fonctionne par usb donc on peut communiquer avec l'extérieur, maintenant il faut le faire aussi par port SPI pour communiquer avec la carte mère.&lt;br /&gt;
[[Fichier:Pong.mp4|centré|vignette|Vidéo test de communication par SPI]]&lt;br /&gt;
[[Fichier:Pongscreen.png|centré|vignette|Pong]]&lt;br /&gt;
Pour cela, on a pris le code pong.c fourni par Mr Redon qui permet de tester la communication par SPI. Le premier essai s'avère être un échec. Le problème venait d'une erreur de conception du shield. On a eu le même problème que le binôme 7 donc on a fait la même manipulation et la communication par SPI fonctionne ! On arrive donc à communiquer avec l'Arduino.&lt;br /&gt;
&lt;br /&gt;
=== Protocole: ===&lt;br /&gt;
Pour envoyer et recevoir des paquets Ethernet avec le PC et la carte, on doit développer notre propre protocole. On a développé un premier protocole test appelé GPOAT (Greatest Protocol Of All Time) qui est composé de la manière suivante:&lt;br /&gt;
[[Fichier:Gpoat.png|centré|vignette|504x504px|Structure d'un paquet GPOAT]]&lt;br /&gt;
Le but de ce paquet est de recevoir 2 nombres de 16 octets et y effectuer une opération qui dépend du bit de point faible de Operation.&lt;br /&gt;
&lt;br /&gt;
Pour reconnaitre ce protocole, on a fait un nouvel Ether Type &amp;quot;GPOAT&amp;quot; référencé à 0x2706.&lt;br /&gt;
&lt;br /&gt;
Ce protocole est intéressant car il permet de montrer que le PC peut envoyer un paquet à la carte, la carte réalise une action qui est l'opération demandé puis renvoie un paquet qui contient la réponse.&lt;br /&gt;
&lt;br /&gt;
Voici comment est traité le paquet et comment la réponse est forgée:&lt;br /&gt;
[[Fichier:Traitement.png|centré|vignette|752x752px|Traitement des données GPOAT]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Dans l'exemple ci dessous, la carte reçoit 2 valeurs qui sont &amp;quot;ff ff&amp;quot; et il lui est demandé de les diviser entre eux, ce à quoi la carte répond avec comme valeur &amp;quot;1&amp;quot;.&lt;br /&gt;
[[Fichier:Gpoat test.png|centré|vignette|401x401px|Test d'envoi et réception d'un GPOAT (le premier est le paquet envoyé par le PC et le 2ème est la réponse de la carte)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Bilan :===&lt;br /&gt;
Nous avons conçu un shield arduino sur lequel nous avons programmé un programme d'ordonnancement, qui peut exécuter en tourniquet plusieurs dont des tâches de communiquer par minicom.&lt;br /&gt;
Nous avons aussi conçu une carte fille réseau RNDIS et utilisé la lib LUFA pour la programmer.&lt;br /&gt;
Cette carte peut répondre au paquet classique ( ARP, IP, ... ) mais aussi à un protocole que l'on a crée.&lt;br /&gt;
&lt;br /&gt;
Par la suite, nous aurions pu faire un deuxième protocole, que transmet les infos qu'il reçoit à la carte mère via SPI, une fonction qui reçoit les commandes de la carte mère qu'elle envoie dans un paquet ethernet au dépot distant ( un pc ), une application sur le pc qui lors de la réception d'un paquet du protocole renvoie un paquet avec les données demandées.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=7090</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=7090"/>
		<updated>2025-01-08T10:26:22Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Programmation de la carte */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test carte SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier si le lecteur est fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segments pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause du défaut de conception, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une exécution en parallèle des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les LEDs lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des LEDs en 5 programmes, 1 pour chaque LED. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi fait une fonction d'initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, on veut pouvoir endormir des tâches pendant une durée définie. Ces tâches doivent être ignorées par le scheduler.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons rajouté une durée d'endormissement dans la structure tab_process et un programme qui réduit le temps de sommeil à chaque interruption puis un programme qui endort la tâche ciblée.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define TIME_INTERRUPT 20&lt;br /&gt;
&lt;br /&gt;
void DecreaseSleep(void)&lt;br /&gt;
{&lt;br /&gt;
   int nb_sleep = 0;&lt;br /&gt;
   for (uint8_t i=1;i&amp;lt;NB_PROCESS-1;i++)&lt;br /&gt;
   {&lt;br /&gt;
     if (tab_process[i].sleep &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        tab_process[i].sleep -= TIME_INTERRUPT;&lt;br /&gt;
        nb_sleep++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setTimeDelay(uint16_t time, uint8_t process)&lt;br /&gt;
{&lt;br /&gt;
  tab_process[process].sleep=time;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi modifié le scheduler :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On a rajouté une condition au passage à la tâche suivante : si la prochaine tâche est endormie, on l'ignore et on regarde l'état de la prochaine jusqu'à avoir une tache éveillée.&lt;br /&gt;
&lt;br /&gt;
On peut repérer un problème : que se passe-t-il si toutes les tâches sont endormies ? On pourrait faire confiance à l'utilisateur en priant pour qu'il n'endorme pas tout le monde mais nous avons préféré ne pas lui faire confiance.&lt;br /&gt;
&lt;br /&gt;
Nous avons donc crée un processus qui est naturellement endormi mais qui se réveille lorsque tout le monde dort, pour éviter une boucle infinie.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Anti_sleep_boucle(void)&lt;br /&gt;
{&lt;br /&gt;
  while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ajoute à setup&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[NB_PROCESS-1].process_add = Anti_sleep_boucle;&lt;br /&gt;
    tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
    tab_process[NB_PROCESS-1].StackPointer = 0x3ff;&lt;br /&gt;
    tab_process[NB_PROCESS-1].state = 1;&lt;br /&gt;
}&lt;br /&gt;
 // ajoute à DecreaseSleep &lt;br /&gt;
&lt;br /&gt;
if (nb_sleep ==  NB_PROCESS-2)&lt;br /&gt;
   {&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On accorde les autres programmes à Anti_sleep_boucle, on a décidé qu'il sera le dernier processus par soucis de simplicité.[[Fichier:Video des LEDs ordonnancé.mp4|vignette&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Video des LEDs ordonnancées|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bonus :&lt;br /&gt;
&lt;br /&gt;
Nous avons amélioré le makefile donné par Mr Boé l'année dernière :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// modification pour un nettoyer plus efficace&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f *.o&lt;br /&gt;
	rm -f *.hex&lt;br /&gt;
	rm -f *.elf&lt;br /&gt;
// modification pour pouvoir upload directement les modfications sur la carte&lt;br /&gt;
upload: $(TARGET).hex&lt;br /&gt;
	stty -F $(TERM) hupcl # reset&lt;br /&gt;
	avrdude -p atmega328p -c arduino -P /dev/ttyUSB0 \ -b 115200 -D -U flash:w:ordonnanceur.hex:i&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;br /&gt;
&lt;br /&gt;
=== Brasure ===&lt;br /&gt;
Le PCB de la Pipelette v1 est arrivée, on peut donc aller braser sans plus tarder.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:PCB nu.jpg|vignette|PCB en manque de composants.|centré|275x275px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
La brasure se passe bien sauf au moment où l'on a remarqué qu'on a confondu l'empreinte du jumper avec celle d'un connecteur de batterie... On a rattrapé l'erreur en brasant un interupteur à l'arrière de la carte.&lt;br /&gt;
[[Fichier:Interrupteur surprise.jpg|vignette|Interrupteur remplacant le jumper à l'arrière.|centré|232x232px]]&lt;br /&gt;
Mise à part ce soucis, tout est en ordre et la carte est brasée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Pico brase.jpg|vignette|PCB plus en manque de composants.|centré|337x337px]]&lt;br /&gt;
&lt;br /&gt;
=== Programmation de la carte ===&lt;br /&gt;
Cette section est dédiée à la programmation de la carte. Tout d'abord, en utilisant les codes RNDIS de la LUFA, notre carte est détectée comme on peut le voir avec un lsusb.&lt;br /&gt;
[[Fichier:LSUSB RNDIS.jpg|vignette|Lsusb qui détecte la carte.|centré|1094x1094px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ensuite, on lui a attribué une addresse IP 10.0.0.1, c'est l'IP Client défini dans l'exemple LUFA et qui est utilisé dans le code certain protocole.&lt;br /&gt;
&lt;br /&gt;
Enfin, avec un ip a, on remarque qu'elle a son interface usb0 et qu'elle est DOWN. Avec un ip link set usb0 up, la carte est prête à communiquer.&lt;br /&gt;
[[Fichier:Ipa.jpg|vignette|ip a où l'on voit la carte (interface usb0)|centré|854x854px]]&lt;br /&gt;
&lt;br /&gt;
En effet elle est belle est bien prête à communiquer car on arrive à la ping.&lt;br /&gt;
&lt;br /&gt;
On ping 10.0.0.2 qui est son IP Serveur défini dans l'exemple LUFA.[[Fichier:Ping.jpg|vignette|Ping de la carte.|centré|570x570px]]&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=7058</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=7058"/>
		<updated>2025-01-06T14:08:35Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Fichier:Screenshot 2025-01-06 15-00-55.jpg|vignette|IP a]]&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test carte SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier si le lecteur est fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segments pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause du défaut de conception, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une exécution en parallèle des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les LEDs lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des LEDs en 5 programmes, 1 pour chaque LED. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi fait une fonction d'initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, on veut pouvoir endormir des tâches pendant une durée définie. Ces tâches doivent être ignorées par le scheduler.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons rajouté une durée d'endormissement dans la structure tab_process et un programme qui réduit le temps de sommeil à chaque interruption puis un programme qui endort la tâche ciblée.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define TIME_INTERRUPT 20&lt;br /&gt;
&lt;br /&gt;
void DecreaseSleep(void)&lt;br /&gt;
{&lt;br /&gt;
   int nb_sleep = 0;&lt;br /&gt;
   for (uint8_t i=1;i&amp;lt;NB_PROCESS-1;i++)&lt;br /&gt;
   {&lt;br /&gt;
     if (tab_process[i].sleep &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        tab_process[i].sleep -= TIME_INTERRUPT;&lt;br /&gt;
        nb_sleep++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setTimeDelay(uint16_t time, uint8_t process)&lt;br /&gt;
{&lt;br /&gt;
  tab_process[process].sleep=time;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi modifié le scheduler :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On a rajouté une condition au passage à la tâche suivante : si la prochaine tâche est endormie, on l'ignore et on regarde l'état de la prochaine jusqu'à avoir une tache éveillée.&lt;br /&gt;
&lt;br /&gt;
On peut repérer un problème : que se passe-t-il si toutes les tâches sont endormies ? On pourrait faire confiance à l'utilisateur en priant pour qu'il n'endorme pas tout le monde mais nous avons préféré ne pas lui faire confiance.&lt;br /&gt;
&lt;br /&gt;
Nous avons donc crée un processus qui est naturellement endormi mais qui se réveille lorsque tout le monde dort, pour éviter une boucle infinie.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Anti_sleep_boucle(void)&lt;br /&gt;
{&lt;br /&gt;
  while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ajoute à setup&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[NB_PROCESS-1].process_add = Anti_sleep_boucle;&lt;br /&gt;
    tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
    tab_process[NB_PROCESS-1].StackPointer = 0x3ff;&lt;br /&gt;
    tab_process[NB_PROCESS-1].state = 1;&lt;br /&gt;
}&lt;br /&gt;
 // ajoute à DecreaseSleep &lt;br /&gt;
&lt;br /&gt;
if (nb_sleep ==  NB_PROCESS-2)&lt;br /&gt;
   {&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On accorde les autres programmes à Anti_sleep_boucle, on a décidé qu'il sera le dernier processus par soucis de simplicité.[[Fichier:Video des LEDs ordonnancé.mp4|vignette&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Video des LEDs ordonnancées|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bonus :&lt;br /&gt;
&lt;br /&gt;
Nous avons amélioré le makefile donné par Mr Boé l'année dernière :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// modification pour un nettoyer plus efficace&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f *.o&lt;br /&gt;
	rm -f *.hex&lt;br /&gt;
	rm -f *.elf&lt;br /&gt;
// modification pour pouvoir upload directement les modfications sur la carte&lt;br /&gt;
upload: $(TARGET).hex&lt;br /&gt;
	stty -F $(TERM) hupcl # reset&lt;br /&gt;
	avrdude -p atmega328p -c arduino -P /dev/ttyUSB0 \ -b 115200 -D -U flash:w:ordonnanceur.hex:i&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;br /&gt;
&lt;br /&gt;
=== Brasure ===&lt;br /&gt;
Le PCB de la Pipelette v1 est arrivée, on peut donc aller braser sans plus tarder.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:PCB nu.jpg|vignette|PCB en manque de composants.|centré|275x275px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
La brasure se passe bien sauf au moment où l'on a remarqué qu'on a confondu l'empreinte du jumper avec celle d'un connecteur de batterie... On a rattrapé l'erreur en brasant un interupteur à l'arrière de la carte.&lt;br /&gt;
[[Fichier:Interrupteur surprise.jpg|vignette|Interrupteur remplacant le jumper à l'arrière.|centré|232x232px]]&lt;br /&gt;
Mise à part ce soucis, tout est en ordre et la carte est brasée.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Pico brase.jpg|vignette|PCB plus en manque de composants.|centré|337x337px]]&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Screenshot_2025-01-06_15-00-55.jpg&amp;diff=7057</id>
		<title>Fichier:Screenshot 2025-01-06 15-00-55.jpg</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Screenshot_2025-01-06_15-00-55.jpg&amp;diff=7057"/>
		<updated>2025-01-06T14:08:00Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ip a&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6947</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6947"/>
		<updated>2024-12-11T14:31:05Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test carte SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier si le lecteur est fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segments pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause du défaut de conception, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une exécution en parallèle des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les LEDs lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
[...]&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des LEDs en 5 programmes, 1 pour chaque LED. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi fait une fonction d'initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, on veut pouvoir endormir des tâches pendant une durée définie. Ces tâches doivent être ignorées par le scheduler.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons rajouté une durée d'endormissement dans la structure tab_process et un programme qui réduit le temps de sommeil à chaque interruption puis un programme qui endort la tâche ciblée.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define TIME_INTERRUPT 20&lt;br /&gt;
&lt;br /&gt;
void DecreaseSleep(void)&lt;br /&gt;
{&lt;br /&gt;
   int nb_sleep = 0;&lt;br /&gt;
   for (uint8_t i=1;i&amp;lt;NB_PROCESS-1;i++)&lt;br /&gt;
   {&lt;br /&gt;
     if (tab_process[i].sleep &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        tab_process[i].sleep -= TIME_INTERRUPT;&lt;br /&gt;
        nb_sleep++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setTimeDelay(uint16_t time, uint8_t process)&lt;br /&gt;
{&lt;br /&gt;
  tab_process[process].sleep=time;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi modifié le scheduler :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On a rajouté une condition au passage à la tâche suivante : si la prochaine tâche est endormie, on l'ignore et on regarde l'état de la prochaine jusqu'à avoir une tache éveillée.&lt;br /&gt;
&lt;br /&gt;
On peut repérer un problème : que se passe-t-il si toutes les tâches sont endormies ? On pourrait faire confiance à l'utilisateur en priant pour qu'il n'endorme pas tout le monde mais nous avons préféré ne pas lui faire confiance.&lt;br /&gt;
&lt;br /&gt;
Nous avons donc crée un processus qui est naturellement endormi mais qui se réveille lorsque tout le monde dort, pour éviter une boucle infinie.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Anti_sleep_boucle(void)&lt;br /&gt;
{&lt;br /&gt;
  while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ajoute à setup&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[NB_PROCESS-1].process_add = Anti_sleep_boucle;&lt;br /&gt;
    tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
    tab_process[NB_PROCESS-1].StackPointer = 0x3ff;&lt;br /&gt;
    tab_process[NB_PROCESS-1].state = 1;&lt;br /&gt;
}&lt;br /&gt;
 // ajoute à DecreaseSleep &lt;br /&gt;
&lt;br /&gt;
if (nb_sleep ==  NB_PROCESS-2)&lt;br /&gt;
   {&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On accorde les autres programmes à Anti_sleep_boucle, on a décidé qu'il sera le dernier processus par soucis de simplicité.[[Fichier:Video des LEDs ordonnancé.mp4|vignette&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Video des LEDs ordonnancées|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bonus :&lt;br /&gt;
&lt;br /&gt;
Nous avons amélioré le makefile donné par Mr Boé l'année dernière :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// modification pour un nettoyer plus efficace&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f *.o&lt;br /&gt;
	rm -f *.hex&lt;br /&gt;
	rm -f *.elf&lt;br /&gt;
// modification pour pouvoir upload directement les modfications sur la carte&lt;br /&gt;
upload: $(TARGET).hex&lt;br /&gt;
	stty -F $(TERM) hupcl # reset&lt;br /&gt;
	avrdude -p atmega328p -c arduino -P /dev/ttyUSB0 \ -b 115200 -D -U flash:w:ordonnanceur.hex:i&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6882</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6882"/>
		<updated>2024-11-27T10:46:05Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi dû créer une fonction d'Initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, on veut pouvoir endormir des tâches pendant une durée définie. Ces tâches doivent être ignorées par le scheduler.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons rajouter dans la structure tab_process, une durée d'endormissement.  Ainsi qu'un programme qui réduit le temps de sommeil à chaque interruption et un programme qui endort la tâche ciblée.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define TIME_INTERRUPT 20&lt;br /&gt;
&lt;br /&gt;
void DecreaseSleep(void)&lt;br /&gt;
{&lt;br /&gt;
   int nb_sleep = 0;&lt;br /&gt;
   for (uint8_t i=1;i&amp;lt;NB_PROCESS-1;i++)&lt;br /&gt;
   {&lt;br /&gt;
     if (tab_process[i].sleep &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        tab_process[i].sleep -= TIME_INTERRUPT;&lt;br /&gt;
        nb_sleep++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setTimeDelay(uint16_t time, uint8_t process)&lt;br /&gt;
{&lt;br /&gt;
  tab_process[process].sleep=time;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi modifier le scheduler :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On a rajouté une condition au passage à la tâche suivante : le fait que la prochaine tâche ne soit pas endormi, si c'est le cas on passe cette tâche et on passe à celle d'après si elle n'est pas endormie aussi et ainsi de suite.&lt;br /&gt;
&lt;br /&gt;
On peut repérer un problème : que se passe-t-il si toutes les tâches sont endormies ? On pourrait faire confiance à l'utilisateur en priant pour qu'il n'endorme pas tout le monde mais nous avons préféré ne pas lui faire confiance.&lt;br /&gt;
&lt;br /&gt;
Nous avons donc créer un processus qui est naturellement endormi mais qui se réveille lors que tout le monde dort, pour éviter une boucle infini.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Anti_sleep_boucle(void)&lt;br /&gt;
{&lt;br /&gt;
  while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ajoute à setup&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[NB_PROCESS-1].process_add = Anti_sleep_boucle;&lt;br /&gt;
    tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
    tab_process[NB_PROCESS-1].StackPointer = 0x3ff;&lt;br /&gt;
    tab_process[NB_PROCESS-1].state = 1;&lt;br /&gt;
}&lt;br /&gt;
 // ajoute à DecreaseSleep &lt;br /&gt;
&lt;br /&gt;
if (nb_sleep ==  NB_PROCESS-2)&lt;br /&gt;
   {&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On accorde les autres programmes à Anti_sleep_boucle, on a décidé qu'il sera le dernier processus par soucis de simplicité.[[Fichier:Video des LEDs ordonnancé.mp4|vignette&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Video des LEDs ordonnancées|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Bonus :&lt;br /&gt;
&lt;br /&gt;
Nous avons amélioré le makefile donné par Mr Boé l'année derniere :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// modification pour un nettoyer plus efficace&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f *.o&lt;br /&gt;
	rm -f *.hex&lt;br /&gt;
	rm -f *.elf&lt;br /&gt;
// modification pour pouvoir upload directement les modfications sur la carte&lt;br /&gt;
upload: $(TARGET).hex&lt;br /&gt;
	stty -F $(TERM) hupcl # reset&lt;br /&gt;
	avrdude -p atmega328p -c arduino -P /dev/ttyUSB0 \ -b 115200 -D -U flash:w:ordonnanceur.hex:i&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6879</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6879"/>
		<updated>2024-11-27T10:22:17Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi dû créer une fonction d'Initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, on veut pouvoir endormir des tâches pendant une durée définie. Ces tâches doivent être ignorées par le scheduler.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons rajouter dans la structure tab_process, une durée d'endormissement.  Ainsi qu'un programme qui réduit le temps de sommeil à chaque interruption et un programme qui endort la tâche ciblée.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define TIME_INTERRUPT 20&lt;br /&gt;
&lt;br /&gt;
void DecreaseSleep(void)&lt;br /&gt;
{&lt;br /&gt;
   int nb_sleep = 0;&lt;br /&gt;
   for (uint8_t i=1;i&amp;lt;NB_PROCESS-1;i++)&lt;br /&gt;
   {&lt;br /&gt;
     if (tab_process[i].sleep &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        tab_process[i].sleep -= TIME_INTERRUPT;&lt;br /&gt;
        nb_sleep++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setTimeDelay(uint16_t time, uint8_t process)&lt;br /&gt;
{&lt;br /&gt;
  tab_process[process].sleep=time;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi modifier le scheduler :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On a rajouté une condition au passage à la tâche suivante : le fait que la prochaine tâche ne soit pas endormi, si c'est le cas on passe cette tâche et on passe à celle d'après si elle n'est pas endormie aussi et ainsi de suite.&lt;br /&gt;
&lt;br /&gt;
On peut repérer un problème : que se passe-t-il si toutes les tâches sont endormies ? On pourrait faire confiance à l'utilisateur en priant pour qu'il n'endorme pas tout le monde mais nous avons préféré ne pas lui faire confiance.&lt;br /&gt;
&lt;br /&gt;
Nous avons donc créer un processus qui est naturellement endormi mais qui se réveille lors que tout le monde dort, pour éviter une boucle infini.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Anti_sleep_boucle(void)&lt;br /&gt;
{&lt;br /&gt;
  while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ajoute à setup&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[NB_PROCESS-1].process_add = Anti_sleep_boucle;&lt;br /&gt;
    tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
    tab_process[NB_PROCESS-1].StackPointer = 0x3ff;&lt;br /&gt;
    tab_process[NB_PROCESS-1].state = 1;&lt;br /&gt;
}&lt;br /&gt;
 // ajoute à DecreaseSleep &lt;br /&gt;
&lt;br /&gt;
if (nb_sleep ==  NB_PROCESS-2)&lt;br /&gt;
   {&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On accorde les autres programmes à Anti_sleep_boucle, on a décidé qu'il sera le dernier processus par soucis de simplicité.[[Fichier:Video des LEDs ordonnancé.mp4|vignette&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Video des LEDs ordonnancées|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6878</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6878"/>
		<updated>2024-11-27T10:15:06Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi dû créer une fonction d'Initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, on veut pouvoir endormir des tâches pendant une durée définie. Ces tâches doivent être ignorées par le scheduler.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons rajouter dans la structure tab_process, une durée d'endormissement.  Ainsi qu'un programme qui réduit le temps de sommeil à chaque interruption et un programme qui endort la tâche ciblée.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define TIME_INTERRUPT 20&lt;br /&gt;
&lt;br /&gt;
void DecreaseSleep(void)&lt;br /&gt;
{&lt;br /&gt;
   int nb_sleep = 0;&lt;br /&gt;
   for (uint8_t i=1;i&amp;lt;NB_PROCESS-1;i++)&lt;br /&gt;
   {&lt;br /&gt;
     if (tab_process[i].sleep &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        tab_process[i].sleep -= TIME_INTERRUPT;&lt;br /&gt;
        nb_sleep++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void setTimeDelay(uint16_t time, uint8_t process)&lt;br /&gt;
{&lt;br /&gt;
  tab_process[process].sleep=time;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi modifier le scheduler :&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;On a rajouté une condition au passage à la tâche suivante : le fait que la prochaine tâche ne soit pas endormi, si c'est le cas on passe cette tâche et on passe à celle d'après si elle n'est pas endormie aussi et ainsi de suite.&lt;br /&gt;
&lt;br /&gt;
On peut repérer un problème : que se passe-t-il si toutes les tâches sont endormies ? On pourrait faire confiance à l'utilisateur en priant pour qu'il n'endorme pas tout le monde mais nous avons préféré ne pas lui faire confiance.&lt;br /&gt;
&lt;br /&gt;
Nous avons donc créer un processus qui est naturellement endormi mais qui se réveille lors que tout le monde dort, pour éviter une boucle infini.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Anti_sleep_boucle(void)&lt;br /&gt;
{&lt;br /&gt;
  while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ajoute à setup&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[NB_PROCESS-1].process_add = Anti_sleep_boucle;&lt;br /&gt;
    tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
    tab_process[NB_PROCESS-1].StackPointer = 0x3ff;&lt;br /&gt;
    tab_process[NB_PROCESS-1].state = 1;&lt;br /&gt;
}&lt;br /&gt;
 // ajoute à DecreaseSleep &lt;br /&gt;
&lt;br /&gt;
if (nb_sleep ==  NB_PROCESS-2)&lt;br /&gt;
   {&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 1;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Video des LEDs ordonnancé.mp4|vignette&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Video des LEDs ordonnancées|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6877</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6877"/>
		<updated>2024-11-27T09:30:48Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi dû créer une fonction d'Initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, on veut pouvoir endormir des tâches pendant une durée définie. Ces tâches doivent être ignorées par le scheduler.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons rajouter dans la structure tab_process, une durée d'endormissement.  Ainsi qu'un programme qui réduit le temps de sommeil à chaque interruption.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define TIME_INTERRUPT 20&lt;br /&gt;
&lt;br /&gt;
void DecreaseSleep(void)&lt;br /&gt;
{&lt;br /&gt;
   int nb_sleep = 0;&lt;br /&gt;
   for (uint8_t i=1;i&amp;lt;NB_PROCESS-1;i++)&lt;br /&gt;
   {&lt;br /&gt;
     if (tab_process[i].sleep &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        tab_process[i].sleep -= TIME_INTERRUPT;&lt;br /&gt;
        nb_sleep++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   if (nb_sleep ==  NB_PROCESS-2)&lt;br /&gt;
   {&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep=1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;|&lt;br /&gt;
&lt;br /&gt;
Nous avons aussi modifier le scheduler :[[Fichier:Video des LEDs ordonnancé.mp4|vignette&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Video des LEDs ordonnancées|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6874</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6874"/>
		<updated>2024-11-20T11:20:36Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi dû créer une fonction d'Initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, on veut pouvoir endormir des tâches pendant une durée définie. Ces tâches doivent être ignorées par le scheduler.&lt;br /&gt;
&lt;br /&gt;
Pour cela, nous avons rajouter dans la structure tab_process, une durée d'endormissement.  Ainsi qu'un programme qui réduit le temps de sommeil à chaque interruption.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define TIME_INTERRUPT 20&lt;br /&gt;
&lt;br /&gt;
void DecreaseSleep(void)&lt;br /&gt;
{&lt;br /&gt;
   int nb_sleep = 0;&lt;br /&gt;
   for (uint8_t i=1;i&amp;lt;NB_PROCESS-1;i++)&lt;br /&gt;
   {&lt;br /&gt;
     if (tab_process[i].sleep &amp;gt; 0)&lt;br /&gt;
      {&lt;br /&gt;
        tab_process[i].sleep -= TIME_INTERRUPT;&lt;br /&gt;
        nb_sleep++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   if (nb_sleep ==  NB_PROCESS-2)&lt;br /&gt;
   {&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep = 0;&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
     tab_process[NB_PROCESS-1].sleep=1;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi modifier le scheduler :ler :[[Fichier:Video des LEDs ordonnancé.mp4|vignette|&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
startScheduler:&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=1;&lt;br /&gt;
  if (tab_process[Cprocess].sleep &amp;gt; 0)&lt;br /&gt;
  {&lt;br /&gt;
//    scheduler();&lt;br /&gt;
	goto startScheduler;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6869</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6869"/>
		<updated>2024-11-20T11:10:40Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restauration du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restaure.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé une structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini ou en cours).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global. De plus, on initialise une variable globale &amp;quot;Cprocess&amp;quot; qui représente le processus courant. &amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led. Et les programmes sont appelés par le scheduler chacun leur tour. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi dû créer une fonction d'Initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'à faire le setup, associer un processus à un emplacement du tableau de processus; lui associer une adresse de StackPointer et un état, démarrer le minuteur, mettre en place les entrées/sorties , initialiser les piles puis activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organisé le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6862</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6862"/>
		<updated>2024-11-20T10:59:44Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restore du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restore.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé un structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et un état (fini, en cours, etc ...).&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus en global.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
uint8_t Cprocess=0;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led. Et les programmes sont appelés par le scheduler chacun leurs tours. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Nous avons aussi dû créer un fonction d'Initialisation des piles d'exécution des programmes qui seront lancés après la première interruption.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void InitialisationPile(int Cprocess){&lt;br /&gt;
    int save = SP;&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    uint16_t address = (uint16_t)tab_process[Cprocess].process_add;&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; (address &amp;amp; 0x00ff) );&lt;br /&gt;
    asm volatile(&amp;quot;push %0&amp;quot; : : &amp;quot;r&amp;quot; ((address &amp;amp; 0xff00)&amp;gt;&amp;gt;8) );&lt;br /&gt;
    portSAVE_REGISTER();&lt;br /&gt;
    tab_process[Cprocess].StackPointer = SP;&lt;br /&gt;
    SP = save;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Il ne reste plus qu'a faire le setup; associer un processus à un emplacement du tableau de processus, lui associer une adresse de StackPointer, et un état; démarrer le miniteur; mettre en place les entrées/sorties ; initialiser les piles et activer les interruptions .&lt;br /&gt;
&lt;br /&gt;
Et finalement, on peut lancer la première tâche.&lt;br /&gt;
&lt;br /&gt;
Avec la façon dont nous avons organiser le scheduler, l'ordonnanceur fonctionne en tourniquet.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
    tab_process[0].process_add = Led1;&lt;br /&gt;
    tab_process[1].process_add = Led2;&lt;br /&gt;
    tab_process[2].process_add = Led3;&lt;br /&gt;
    tab_process[3].process_add = Led4;&lt;br /&gt;
    tab_process[4].process_add = Led5;&lt;br /&gt;
    tab_process[0].StackPointer = 0x6ff;&lt;br /&gt;
    tab_process[1].StackPointer = 0x680;&lt;br /&gt;
    tab_process[2].StackPointer = 0x5ff;&lt;br /&gt;
    tab_process[3].StackPointer = 0x580;&lt;br /&gt;
    tab_process[4].StackPointer = 0x4ff;&lt;br /&gt;
    tab_process[0].state = 0;&lt;br /&gt;
    tab_process[1].state = 0;&lt;br /&gt;
    tab_process[2].state = 0;&lt;br /&gt;
    tab_process[3].state = 0;&lt;br /&gt;
    tab_process[4].state = 0;&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    InitialisationPile(1);&lt;br /&gt;
    InitialisationPile(2);&lt;br /&gt;
    InitialisationPile(3);&lt;br /&gt;
    InitialisationPile(4);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    setup();&lt;br /&gt;
    SP = tab_process[Cprocess].StackPointer;&lt;br /&gt;
    tab_process[Cprocess].process_add();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6853</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6853"/>
		<updated>2024-11-20T10:40:24Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restore du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restore.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puis, nous avons créé un structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et une adresse de départ de la pile du processus.&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led. Et les programmes sont appelés par le scheduler chacun leurs tours. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6852</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6852"/>
		<updated>2024-11-20T10:38:56Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Maintenant, nous allons utiliser l'ISR en mode Naked, c'est-à-dire qu'il ne gère plus la sauvegarde et la restore du contexte des tâches lors de leur interruption.&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons écrit le bout de code qui sauvegarde le contexte sur la pile et celui qui le restore.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#define portSAVE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;in r0, __SREG__ \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;push r31 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define portRESTORE_REGISTER() \&lt;br /&gt;
asm volatile ( \&lt;br /&gt;
&amp;quot;pop r31 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r30 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r29 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r28 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r27 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r26 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r25 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r24 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r23 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r22 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r21 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r20 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r19 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r18 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r17 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r16 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r15 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r14 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r13 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r12 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r11 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r10 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r9 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r8 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r7 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r6 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r5 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r4 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r3 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r2 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r1 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;out __SREG__, r0 \n\t&amp;quot; \&lt;br /&gt;
&amp;quot;pop r0 \n\t&amp;quot; \&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect,ISR_NAKED){    // Procédure d'interruption&lt;br /&gt;
  portSAVE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  scheduler();&lt;br /&gt;
&lt;br /&gt;
  portRESTORE_REGISTER();&lt;br /&gt;
&lt;br /&gt;
  asm volatile ( &amp;quot;reti&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ensuite, nous avons séparé le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led. Et les programmes sont appelés par le scheduler chacun leurs tours. &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void scheduler(void)&lt;br /&gt;
{&lt;br /&gt;
   if (Cprocess &amp;lt; NB_PROCESS-1)&lt;br /&gt;
     Cprocess+=1;&lt;br /&gt;
   else&lt;br /&gt;
     Cprocess=0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Puis, nous avons créé un structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et une adresse de départ de la pile du processus.&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&lt;br /&gt;
tab_process_t tab_process[NB_PROCESS];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6849</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6849"/>
		<updated>2024-11-20T10:28:09Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
===Ordonnanceur :===&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons séparer le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ensuite nous avons créé un structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et une adresse de départ de la pile du processus.&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6848</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6848"/>
		<updated>2024-11-20T10:27:34Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
'''Ordonnanceur (No Naked):'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
'''Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :'''&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons séparer le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Ensuite nous avons créé un structure de processus, pour que chaque processus soit décrit par un pointeur de fonction, un StackPointer et une adresse de départ de la pile du processus.&lt;br /&gt;
&lt;br /&gt;
Afin de pouvoir créer un tableau de processus.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
typedef struct tab_process{&lt;br /&gt;
                uint16_t StackPointer;&lt;br /&gt;
                void (*process_add)(void);&lt;br /&gt;
              	uint8_t  state;&lt;br /&gt;
                uint16_t sleep;&lt;br /&gt;
                }&lt;br /&gt;
                tab_process_t;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
'''Ordonnanceur Naked avec fonction d'endormissement des tâches :'''&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6847</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6847"/>
		<updated>2024-11-20T10:24:07Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
Ordonnanceur (No Naked):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :&lt;br /&gt;
&lt;br /&gt;
Pour commencer, nous avons séparer le programme de clignotement des Leds en 5 programmes, 1 pour chaque Led.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
Ordonnanceur Naked avec fonction d'endormissement des tâches :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6845</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6845"/>
		<updated>2024-11-20T10:22:33Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
Ordonnanceur (No Naked):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
void Led1(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00000001;&lt;br /&gt;
    _delay_ms(100);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led2(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00000010;&lt;br /&gt;
    _delay_ms(200);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led3(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTC ^= 0b00001000;&lt;br /&gt;
    _delay_ms(300);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led4(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b00010000;&lt;br /&gt;
    _delay_ms(400);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Led5(void)&lt;br /&gt;
{&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    PORTD ^= 0b10000000;&lt;br /&gt;
    _delay_ms(500);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
Ordonnanceur Naked avec fonction d'endormissement des tâches :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6842</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6842"/>
		<updated>2024-11-20T10:17:36Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
Ordonnanceur (No Naked):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Le principe de l'ordonnanceur est de simuler une execution en parallele des tâches.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Pour cela, on génère un minuteur qui va nous donner une durée d'exécution d'un programme avant que ce-dernier ne se fasse interrompre pour qu'une autre tâche s'exécute.&lt;br /&gt;
&lt;br /&gt;
Lorsqu'une tâche précédemment interrompue se réexécute, elle reprend là où elle en était dans son processus.&lt;br /&gt;
&lt;br /&gt;
Ici la fonction d'interruption ISR fait clignoter les Leds lors d'une interruption, la fonction sei() active les interruptions.&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
Ordonnanceur Naked avec fonction d'endormissement des tâches :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper. On a également ajouté des LEDs qui vont servir de témoins lorsqu'il y a communication.[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6837</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6837"/>
		<updated>2024-11-20T10:04:07Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Carte Réseau */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
Ordonnanceur UnNaked:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
Ordonnanceur Naked avec fonction d'endormissement des tâches :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]][[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |néant]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6836</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6836"/>
		<updated>2024-11-20T10:03:24Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Conception */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
Ordonnanceur UnNaked:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
Ordonnanceur Naked avec fonction d'endormissement des tâches :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
===Conception ===&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6835</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6835"/>
		<updated>2024-11-20T10:02:55Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Carte Réseau */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
Ordonnanceur UnNaked:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
Ordonnanceur Naked avec fonction d'endormissement des tâches :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
====Conception ====&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6834</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6834"/>
		<updated>2024-11-20T10:02:22Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Carte Réseau */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
Ordonnanceur UnNaked:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
Ordonnanceur Naked avec fonction d'endormissement des tâches :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
====Conception ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6833</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6833"/>
		<updated>2024-11-20T10:01:51Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Conception */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
Ordonnanceur UnNaked:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
Ordonnanceur Naked avec fonction d'endormissement des tâches :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
====Conception ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6832</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6832"/>
		<updated>2024-11-20T10:00:48Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
Ordonnanceur UnNaked:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
Ordonnanceur Naked avec fonction d'endormissement des tâches :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
====Conception ====&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6831</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6831"/>
		<updated>2024-11-20T09:59:46Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
Ordonnanceur UnNaked:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
Ordonnanceur Naked avec fonction d'endormissement des tâches :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6830</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6830"/>
		<updated>2024-11-20T09:58:52Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
Ordonnanceur :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
Ordonnanceur Naked avec fonction d'endormissement des tâches :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6829</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6829"/>
		<updated>2024-11-20T09:57:45Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports He-10 pour y brancher des cartes filles.&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Petite erreur de conception, la carte a été routée à l'envers... Ce n'est pas catastrophique (un peu quand même) et c'est rattrapable en rajoutant des rallonges pour avoir assez d'espace pour brancher les He-10.&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
=====Ordonnanceur :=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=====Ordonnanceur Naked en Round-Robin ( Tourniquet en patois ) :=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
===== Ordonnanceur Naked avec fonction d'endormissement des tâches :=====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6824</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6824"/>
		<updated>2024-11-20T09:47:04Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Le shield va nous permettre de tester nos cartes filles sans la carte mère du Pico. Pour faire nos tests, le shield doit posséder un lecteur de carte SD pour tester la mémoire, des LEDs pour tester des processus et des ports HE10 pour y brancher des cartes filles. &lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons tester les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
sous-partie1 : Ordonnanceur&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define CTC1 WGM12&lt;br /&gt;
&lt;br /&gt;
#define PERIODE         1000&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect){    // Procédure d'interruption&lt;br /&gt;
int led1=(PORTC &amp;amp; 0x0f);&lt;br /&gt;
led1 &amp;gt;&amp;gt;= 1; if(led1==0) led1=0b00001001;&lt;br /&gt;
PORTC &amp;amp;= 0xf0; PORTC |= led1;&lt;br /&gt;
&lt;br /&gt;
int led2=(PORTD &amp;amp; 0x0f);&lt;br /&gt;
led2 &amp;gt;&amp;gt;= 1; if(led2==0) led2=0b10010010;&lt;br /&gt;
PORTD &amp;amp;= 0xf0; PORTD |= led2;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void init_minuteur(int diviseur,long periode){&lt;br /&gt;
TCCR1A=0;               // Le mode choisi n'utilise pas ce registre&lt;br /&gt;
TCCR1B=(1&amp;lt;&amp;lt;CTC1);       // Réinitialisation du minuteur sur expiration&lt;br /&gt;
switch(diviseur){&lt;br /&gt;
  case    8: TCCR1B |= (1&amp;lt;&amp;lt;CS11); break;&lt;br /&gt;
  case   64: TCCR1B |= (1&amp;lt;&amp;lt;CS11 | 11&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
  case  256: TCCR1B |= (1&amp;lt;&amp;lt;CS12); break;&lt;br /&gt;
  case 1024: TCCR1B |= (1&amp;lt;&amp;lt;CS12 | 1&amp;lt;&amp;lt;CS10); break;&lt;br /&gt;
}&lt;br /&gt;
// Un cycle prend 1/F_CPU secondes.&lt;br /&gt;
// Un pas de compteur prend diviseur/F_CPU secondes.&lt;br /&gt;
// Pour une periode en millisecondes, il faut (periode/1000)/(diviseur/F_CPU) pas&lt;br /&gt;
// soit (periode*F_CPU)/(1000*diviseur)&lt;br /&gt;
OCR1A=F_CPU/1000*periode/diviseur;  // Calcul du pas&lt;br /&gt;
TCNT1=0;                // Compteur initialisé&lt;br /&gt;
TIMSK1=(1&amp;lt;&amp;lt;OCIE1A);     // Comparaison du compteur avec OCR1A&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    init_minuteur(1024,PERIODE);&lt;br /&gt;
    DDRC |= 0b00001001;&lt;br /&gt;
    DDRD |= 0b10010010;&lt;br /&gt;
    PORTC &amp;amp;= ~0b00001001;&lt;br /&gt;
    PORTD &amp;amp;= ~0b10010010;&lt;br /&gt;
    init_minuteur(256,PERIODE);&lt;br /&gt;
    sei();    // Autorisation des interruptions&lt;br /&gt;
    while(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;sous-partie2 : Ordonnanceur Naked en Round-Robin ( Tourniquet en patois )&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
sous-partie3 : Ordonnanceur Naked avec fonction d'endormissement des tâches&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6822</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6822"/>
		<updated>2024-11-20T09:39:43Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
sous-partie1 : Ordonnanceur&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;sous-partie2 : Ordonnanceur Naked en Round-Robin ( Tourniquet en patois )&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
sous-partie3 : Ordonnanceur Naked avec fonction d'endormissement des tâches&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; start=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
bonjour&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6820</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6820"/>
		<updated>2024-11-20T09:27:36Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6819</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6819"/>
		<updated>2024-11-20T09:27:13Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6775</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6775"/>
		<updated>2024-11-19T14:54:51Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Fichier:Video des LEDs ordonnancé.mp4|vignette|Video des LEDs ordonnancé es]]&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad:[[Fichier:Kicad CReseau.zip|vignette|Fichier Kicad de la carte réseau RNDIS]]&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau. Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287 car il a une plus grande capacité de stockage que l'AtMega32u4. La carte communiquera avec l'extérieur par mini USB et pourra être alimenté de deux manières différentes: Soit par la carte mère ou soit par le port USB directement grâce à un jumper.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Kicad CReseau PCB.svg|vignette|Schéma du PCB |gauche]]&lt;br /&gt;
[[Fichier:SVG Kicad CReseau.svg|vignette|Schématique de la carte réseau]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Video_des_LEDs_ordonnanc%C3%A9.mp4&amp;diff=6774</id>
		<title>Fichier:Video des LEDs ordonnancé.mp4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Video_des_LEDs_ordonnanc%C3%A9.mp4&amp;diff=6774"/>
		<updated>2024-11-19T14:53:28Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Dans un premier temps, toutes les taches sont endormis de ce fait, une tache spéciale prend le relai pour évité une boucle infini.&lt;br /&gt;
Ensuite les programmes se réveillent les uns apres les autres.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6522</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6522"/>
		<updated>2024-11-13T09:29:27Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Ordonnanceur : */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad :&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6489</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6489"/>
		<updated>2024-11-06T10:57:55Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : /* Carte Réseau */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
Projet Kicad :&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6488</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6488"/>
		<updated>2024-11-06T10:51:27Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Carte Shield Soudé :==== &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
====Test LED :====&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test cart SD :====&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Test Port He-10 : ====&lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
====Ordonnanceur :====&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6487</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6487"/>
		<updated>2024-11-06T10:47:54Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Carte Shield Soudé : &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
Test LED :&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test cart SD :&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test Port He-10 : &lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Malgré des difficultés à connecter les afficheurs 7-segments à cause de défaut de conceptions, les 5 ports HE-10 sont fonctionnels.&lt;br /&gt;
&lt;br /&gt;
Ordonnanceur :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6485</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6485"/>
		<updated>2024-11-06T10:13:09Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Carte Shield Soudé : &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
Test LED :&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test cart SD :&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test Port He-10 : &lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ordonnanceur :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6484</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6484"/>
		<updated>2024-11-06T10:10:20Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Carte Shield Soudé : &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
Test LED :&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test cart SD :&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test Port He-10 : &lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ordonnanceur :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6483</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6483"/>
		<updated>2024-11-06T10:08:09Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Fichier:Video de test des ports HE-10.mp4|vignette|Video de test d'un port HE-10]]&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Carte Shield Soudé : &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
Test LED :&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test cart SD :&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test Port He-10 : &lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ordonnanceur :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Video_de_test_des_ports_HE-10.mp4&amp;diff=6482</id>
		<title>Fichier:Video de test des ports HE-10.mp4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Video_de_test_des_ports_HE-10.mp4&amp;diff=6482"/>
		<updated>2024-11-06T10:07:15Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Video de test des ports HE-10 via des afficher 7-segments&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6481</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6481"/>
		<updated>2024-11-06T09:55:47Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Carte Shield Soudé : &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
Test LED :&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test cart SD :&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test Port He-10 : &lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ordonnanceur :&lt;br /&gt;
&lt;br /&gt;
[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6480</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6480"/>
		<updated>2024-11-06T09:54:20Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Fichier:Ordonnanceur tourniquet .mp4|centré|vignette|Video de démonstration de l'ordonnanceur en tourniquet ]]&lt;br /&gt;
&lt;br /&gt;
== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Carte Shield Soudé : &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
Test LED :&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test cart SD :&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test Port He-10 : &lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ordonnanceur :&lt;br /&gt;
[[Fichier:Vidéo du tourniquet synchrone.mp4|vignette|Video des Leds qui s'alluments grace a l'ordonnanceur en tourniquet |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Ordonnanceur_tourniquet_.mp4&amp;diff=6479</id>
		<title>Fichier:Ordonnanceur tourniquet .mp4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=Fichier:Ordonnanceur_tourniquet_.mp4&amp;diff=6479"/>
		<updated>2024-11-06T09:53:44Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Vidéo de démonstration de l'ordonnanceur en tourniquet avec un allumage &amp;quot;asynchrone&amp;quot; des LEDs&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6474</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6474"/>
		<updated>2024-11-05T16:38:04Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Carte Shield Soudé : &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
Test LED :&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test cart SD :&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test Port He-10 : &lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ordonnanceur :&lt;br /&gt;
[[Fichier:Vidéo du tourniquet synchrone.mp4|vignette|Video des Leds qui s'alluments grace a l'ordonnanceur en tourniquet |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6473</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6473"/>
		<updated>2024-11-05T16:37:42Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD|centré]]&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Carte Shield Soudé : &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
Test LED :&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test cart SD :&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test Port He-10 : &lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ordonnanceur :&lt;br /&gt;
[[Fichier:Vidéo du tourniquet synchrone.mp4|vignette|Video des Leds qui s'alluments grace a l'ordonnanceur en tourniquet |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
	<entry>
		<id>https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6467</id>
		<title>SE4Binome2024-4</title>
		<link rel="alternate" type="text/html" href="https://projets-se.plil.fr/mediawiki/index.php?title=SE4Binome2024-4&amp;diff=6467"/>
		<updated>2024-11-05T15:08:52Z</updated>

		<summary type="html">&lt;p&gt;Jwacquet : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Shield Arduino ==&lt;br /&gt;
[[Fichier:Test du lecteur de carte SD.png|vignette|Capture d'écran de l'IDE Arduino lors du test du lecteur de carte SD]]&lt;br /&gt;
Lien du GIT : https://gitea.plil.fr/jwacquet/Pico_Binome4_Justin_Ibrahim.git&lt;br /&gt;
&lt;br /&gt;
Projet Kicad : [[Fichier:Projet Kicad Shield.zip|vignette|Projet Kicad Shield Compressé]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Carte Shield Soudé : &lt;br /&gt;
[[Fichier:Carte shield soudée face .jpg|vignette|Carte shield soudée face |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Maintenant que la carte est soudé nous devons les différents éléments de la carte.&lt;br /&gt;
&lt;br /&gt;
Test LED :&lt;br /&gt;
&lt;br /&gt;
Pour tester les Leds nous avons réalisé un programme sur arduino qui allume les Leds. &lt;br /&gt;
[[Fichier:VID 20241015 151605(1).mp4|vignette|Vidéo du test des Leds|centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test cart SD :&lt;br /&gt;
&lt;br /&gt;
Nous avons placé la carte SD dans le lecteur puis nous avons utilisé le programme info-carte sur l'IDE Arduino pour vérifier que le lecteur était fonctionnel.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Test Port He-10 : &lt;br /&gt;
&lt;br /&gt;
Pour tester les ports He-10, nous avons connecté un afficheur 7-segment pour vérifier qu'ils fonctionnent.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ordonnanceur :&lt;br /&gt;
[[Fichier:Vidéo du tourniquet synchrone.mp4|vignette|Video des Leds qui s'alluments grace a l'ordonnanceur en tourniquet |centré]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Carte Réseau ==&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Nous allons réaliser la carte fille réseau du projet PICO-Ordinateur.&lt;br /&gt;
Nous avons décidé de partir sur la carte RNDIS, avec un AT90USB1287.&lt;br /&gt;
&lt;br /&gt;
=== Bilan de puissance ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Suite à une demande de la part de l'équipe Mère, nous allons effectuer un bilan de puissance de notre carte :&lt;br /&gt;
&lt;br /&gt;
Le composant majeur de notre carte est le microprocesseur, l'AT90USB.&lt;br /&gt;
[[Fichier:Carte d'écran du courant de l'AT90USB.png|centré|vignette|500x500px|Carte d'écran du courant de l'AT90USB]]&lt;br /&gt;
Avec un tension d'entrée de 5V et une fréquence de 16MHz, le microprocesseur consomme : 0,030A x 5V =0,15 W.&lt;/div&gt;</summary>
		<author><name>Jwacquet</name></author>
	</entry>
</feed>