SE4Binome2023-3

De projets-se.plil.fr
Aller à la navigation Aller à la recherche

Ordonnanceur / SE

Nous avons soudé l'ensemble des composants du shield arduino et avons testé son bon fonctionnement à l'aide de l'application Arduino. Voici ci-dessous une vidéo du clignotement des LEDs.

Nous testerons notre ordonnanceur dans un premier temps avec 3 tâches représentées par le clignotement d'une Led. Nous avons débuté par un premier programme pour vérifier le clignotement des Leds et faire fonctionner l'ISR nue. Après vérification que tout fonctionne bien, nous essayons de sauvegarder le contexte et de le reconstituer.


Après moulte tentative, nous sommes parvenus à réaliser un ordonnancuer fonctionelle qui a comme tâches le clignotement de 3 LEDs. Cependant, ce multi-tasking engendre un ralentissement des temps voulu, il faut donc géré cette partie afin de faire correspondre les délais du cahier des charges et ceux de notre réalisation.Ci-dessous, voici le code permettant de gérer l'ordonnancement :

struct task_t{
    void (*addr)(void);
    uint16_t sp;
    int state;
};

void initTask(int taskId){
    int save = SP;
    SP = task[taskId].sp;
    uint16_t address = (uint16_t)task[taskId].addr;
    asm volatile("push %0" : : "r" (address & 0x00ff) );
    asm volatile("push %0" : : "r" ((address & 0xff00)>>8) );
    SAVE_REGISTER();
    task[taskId].sp = SP;
    SP = save;
}

void scheduler (){
    currentTask ++;
    if(currentTask == NB_TASK) currentTask = 0;
}

ISR(TIMER1_COMPA_vect,ISR_NAKED){
    // Sauvegarde du contexte de la tâche interrompue
    SAVE_REGISTER();
    task[currentTask].sp = SP;
    // Appel à l'ordonnanceur
    scheduler();
    // Récupération du contexte de la tâche ré-activée
    SP = task[currentTask].sp; 
    RESTORE_REGISTER();
    
    asm volatile("reti");
}

int main(){
    setup();
    SP = task[currentTask].sp;
    task0();
}

Le main réalise d'abord le setup des LEDs, des interruptions, des tâches (leur addresse, leur pointeur de pile par exemple: 0x0600, leur état) ... puis récupère le pointeur de pile et lance manuellement la première tâche (task0). A chaque interruption de l'ISR, on sauvegarde le contexte de la tâche en cours, on choisit la prochaine tâche (task0 --> task1) et on restaure le contexte précédent associé à cette tâche. A la fin de l'interruption, la tâche voulue se lance et on attend la prochaine interruption pour continuer l'algorithme.

Cependant, vous pouvez voir ci-dessous que les tâches sont 3 fois plus longues que voulues. En effet, chaque delay est multipplié par le nombre de tâches à réaliser (ici, 3). Nous devons donc réfléchir à une méthode permettant d'endormir les tâches non sollicitées par l'ordonnanceur.

Afin d'endormir les tâches, nous écrivons une fonction wait. Désormais, chaque structure task_t inclut son état (endormi ou éveillé) et une structure sleep_t qui contient deux paramètres. Ces deux paramètres sont la raison de l'endormissement de la tâche et un compteur. Le but de notre fonction est d'attendre la fin du compteur pour changer son état et réinitialiser le compteur.

Ordonnanceur.c :

void wait_ms(uint16_t ms){
    cli();
    task[currentTask].state = SLEEP;
    sleep_t sleep;
    sleep.reason = DELAY_SLEEPING;
    sleep.data = ms;
    task[currentTask].sleep = sleep;
    TCNT1 = 0;
    sei();
    TIMER1_COMPA_vect();
}

Ordonnanceur.h :

#define SLEEP 0
#define AWAKE 1

#define DELAY_SLEEPING 0

typedef struct sleep_t{
    uint8_t reason;
    uint16_t data;
}sleep_t;

typedef struct task_t{
    void (*addr)(void);
    uint16_t sp;
    uint8_t state;
    sleep_t sleep;
}task_t;

Voici donc ci-dessous le résultat en contrôlant l'état des LEDs (ce dernier ressemble ostensiblement à la vidéo précédente, mais cette fois ci, les temps voulus sont exacts)

Carte FPGA / VHDL

Carte électronique numérique

L'ENSEMBLE DE NOS FICHIERS SONT DISPONIBLE ICI

Type de carte choisi

Nous avons choisi la carte fille gérant le clavier. Nous allons donc souder et programmer une carte sur laquelle sera branché un clavier en USB.

Schematic et routage de la carte

Nous avons réalisé le schematic de notre carte en nous basant sur ce projet. Nous avons pris la décision d'utiliser le même port USB femelle pour brancher le clavier et programmer la carte avec l'ordinateur (plutôt qu'un femelle pour le clavier et un mâle pour la programmation).

Schematic

Après avoir assigné les correctes footprint à chacun des éléments, nous avons commencé le routage de notre carte fille. Nous avons fait le choix de connecter chaque pin seul à un test point, ce qui nous a valu en premier lieu de sacré problème quant à l'organisation de l'espace que prenaient ces test point sur le PCB ! Après vérifications auprès de Mrs Boé et Redon, nous avons supprimé certains test points prenant trop de place et avons déplacer certains composants (rapprochage du crystal et des condensateur du microprocesseur, perfectionnement de la carte, ajout de vias pour répartir le transfert de courant entre les deux faces pour la masse...) nous avons généré les deux fichiers nécessaires à l'impression par un prestataire extérieur et avons, en attendant sa réception, commencé à travailler notre ordonnanceur.

Routage

Soudage de la carte

Nous avons reçu notre carte en 5 exemplaires le 24/10, et avons décidé de continuer l'ordonnanceur avant de commencer la soudure.

En ce grand jour du 15/11, nous avons enfin reçu notre AT90USB647 et pourrons commencer la soudure à la prochaine séance ! Au cours du premier test, notre carte n'était pas reconnu et nous avions des valeurs de tensions incohérentes en différents points. Après different soudage-resoudage de nombreux composants, nous avons compris que ceci venait en fait des boutons. En effet, nous avons choisi un composant incorrect sur notre schematic ce qui a entrainé des erreurs sur notre routage, ce qui engendre le fait que le port reset et le port HWB était constamment en court-circuit avec le ground (ceci explique cela...). Pour résoudre le problème, nous avons resoudé nos boutons avec une erreur de 90° et avons mis à jour notre schematic et le routage qui va avec. Voici donc la deuxième version de ces deux fichiers :


Nous avons commencé les premiers tests le 21/11et ces derniers furent concluant. Notre carte est reconnu par le terminal avec la commande lsusb et on a pu faire clignoter nos LEDs de test.