« SE4Binome2025-2 » : différence entre les versions

De projets-se.plil.fr
Aller à la navigation Aller à la recherche
Aucun résumé des modifications
Aucun résumé des modifications
Ligne 33 : Ligne 33 :


<br clear="all" />
<br clear="all" />
= Firmware — RTOS =
 
= Firmware — Pico-OS (RTOS Préemptif) =
= Firmware — Pico-OS (RTOS Préemptif) =



Version du 25 novembre 2025 à 22:55

Objectif

L'objectif du projet est de concevoir un pico-ordinateur complet, intégrant :

  • Une carte mère basée sue le microcontrôleur AT90USB1286

Une partie logicielle permettant l'éxecution de de commandes telles que ls, cp ou mv

Shield Arduino

Une première étape du projet a consisté à développer un shield pour Aduino uno, servant de plateforme de test et de développement pour les cartes filles SPI.

Fonctionalités:

  • Connexion de 5 périphériques SPI via des cartes filles.
  • Gestion des signaux Reset et Interruption.
  • Ajout d'une mémoire externe carte micro-SD via un connecteur Molex 10431.
  • Adaptation des niveaux logiques (5V a 3,3V) grâce à la puce 74LV125.

Ce shield joue le rôle de plateforme de développement temporaire, en attendant la carte mère du pico-ordinateur.

Schématique et routage

Schema shield arduino.jpg

Objectif

Schema shield arduino


Routage shield arduino


Carte mère

Schématique

Schéma carte mère du pico ordinateur



Firmware — Pico-OS (RTOS Préemptif)

Vue d'ensemble du système

Le firmware implémente un système d'exploitation temps réel (RTOS) préemptif complet pour l'ATmega328P. Contrairement à la version coopérative précédente, ce noyau utilise des interruptions matérielles pour forcer le changement de contexte entre les tâches, garantissant qu'une tâche lourde (comme lister des fichiers SD) ne bloque jamais les tâches critiques (comme clignoter une LED).

Caractéristiques principales :

  • Ordonnancement Préemptif : Commutation de contexte basée sur le Timer1 (100 Hz).
  • Priorités : Ordonnanceur Round-Robin avec niveaux de priorité (IDLE, LOW, MEDIUM, HIGH).
  • Système de Fichiers FAT16 : Lecture/Écriture complète, création/suppression de fichiers, support des scripts.
  • Shell Interactif : Interface ligne de commande via UART (115200 bauds).
  • Optimisation Extrême : Conçu pour fonctionner dans les 2 Ko de RAM de l'ATmega328p.

Architecture Logicielle

L'arborescence du projet est structurée pour séparer le noyau, les pilotes et le système de fichiers.

src/
 ├─ main.c                # Point d'entrée et définition des tâches utilisateur
 ├─ Makefile              # Système de compilation
 ├─ kernel/               # Cœur de l'OS
 │   ├─ kernel.c/h        # Initialisation et boucles principales
 │   ├─ scheduler.c/h     # Gestionnaire de tâches et ISR
 │   ├─ task.c/h          # Création de tâches et gestion de la pile
 │   └─ config.h          # Paramètres globaux (Fréquence, Taille piles)
 ├─ drivers/              # Pilotes Matériels
 │   ├─ uart.c/h          # Gestion du port série (Interruption RX)
 │   ├─ spi_bitbang.c/h   # SPI logiciel atomique
 │   └─ sd_card.c/h       # Protocole SD bas niveau (CMD/Response)
 ├─ fs/                   # Système de fichiers
 │   └─ fat16.c/h         # Implémentation FAT16 complète
 └─ shell/                # Interface Utilisateur
     └─ shell_core.c/h    # Interpréteur de commandes

Le Noyau (Kernel)

Commutation de Contexte (Context Switching)

Le cœur du système repose sur l'interruption du Timer 1. Nous utilisons une fonction `ISR_NAKED` pour avoir un contrôle total sur la pile (Stack).


Le mécanisme de préemption : 1. **Interruption :** Le Timer 1 se déclenche toutes les 10ms. 2. **Sauvegarde (Push) :** L'ISR empile manuellement les 32 registres généraux (`r0` à `r31`) et le registre d'état (`SREG`). 3. **Sauvegarde du SP :** Le pointeur de pile matériel (`SP`) est sauvegardé dans la structure de la tâche courante (`task->stack_ptr`). 4. **Ordonnancement :** La fonction C `scheduler_tick_preemptive()` choisit la prochaine tâche. 5. **Restauration (Pop) :** Le `SP` de la nouvelle tâche est chargé, puis ses registres sont dépilés. 6. **RETI :** L'instruction de retour restaure le compteur ordinal (PC), reprenant l'exécution de la nouvelle tâche exactement là où elle s'était arrêtée.

ISR(TIMER1_COMPA_vect, ISR_NAKED) {
    // 1. Sauvegarde du contexte (Assembleur inline)
    asm volatile(
        "push r0 \n in r0, __SREG__ \n push r0 \n" // Sauve SREG
        "push r1 \n push r2 \n ... \n push r31 \n" // Sauve R1-R31
    );
    
    // 2. Sauvegarde du Pointeur de Pile (SP) vers la Tâche Courante
    asm volatile(
        "lds r28, current_task_ptr \n" // Charge l'adresse du TCB
        "in r30, 0x3d \n"              // Lit SPL
        "std Y+4, r30 \n"              // Stocke dans TCB->stack_ptr
    );
    
    // 3. Appel de l'Ordonnanceur C
    asm volatile("call scheduler_tick_preemptive");
    
    // 4. Restauration du Pointeur de Pile depuis la Nouvelle Tâche
    // 5. Restauration du contexte (Pop)
    asm volatile("reti");
}

Gestion de la Mémoire et PROGMEM

L'ATmega328p ne dispose que de **2048 octets de RAM**. Avec un système de fichiers et un shell, la saturation mémoire est le principal danger.

Stratégies d'optimisation :

  • **Chaînes en Flash (PROGMEM) :** Tous les noms de tâches et les chaînes de caractères du Shell sont stockés en mémoire programme (Flash) pour épargner la RAM. Les fonctions comme `pgm_read_word` sont utilisées pour y accéder.
  • **Buffer Partagé :** Le pilote FAT16 utilise un unique buffer de 512 octets (`shared_buffer`) pour toutes les opérations (lecture MBR, FAT, Répertoire, Données), au lieu d'allouer plusieurs tampons.
  • **Piles Ajustées :** Chaque tâche possède une taille de pile spécifique définie à la création (`blink`: 64o, `shell`: 384o).

Système de Fichiers (FAT16)

Le pilote FAT16 a été écrit à la main pour supporter les opérations de lecture et d'écriture tout en minimisant l'empreinte mémoire.


Fonctionnalités

  • **Montage Dynamique :** Détection automatique du Master Boot Record (MBR) ou du format Superfloppy.
  • **Allocation Réelle :** Recherche de clusters libres dans la FAT pour l'écriture.
  • **Mise à jour Miroir :** Écriture simultanée dans `FAT1` et `FAT2` pour assurer la compatibilité avec Linux/Windows (évite les erreurs "Read-only file system").
  • **Noms 8.3 :** Conversion automatique des noms de fichiers (ex: `test.txt` → `TEST TXT`).

Écriture de Fichier (Create)

La fonction `fat16_create_file` effectue les opérations suivantes :

  1. Scanne la FAT pour trouver un cluster libre (marqué `0x0000`).
  2. Scanne le répertoire racine pour trouver une entrée libre.
  3. Écrit les métadonnées du fichier (Nom, Taille, Cluster de départ) dans le répertoire.
  4. Écrit le contenu du fichier dans le secteur de données correspondant.
  5. Met à jour la FAT pour marquer le cluster comme "Fin de fichier" (`0xFFFF`).

Pilotes Matériels (Drivers)

SPI Atomique

Le pilote SPI (`spi_bitbang.c`) est critique dans un système préemptif.

  • **Problème :** Si l'ordonnanceur interrompt l'envoi d'un octet SPI, l'horloge (SCK) peut rester à l'état haut/bas pendant 10ms. Certaines cartes SD interprètent cela comme un timeout ou une erreur.
  • **Solution :** Utilisation de blocs atomiques. Les interruptions sont désactivées (`cli()`) juste avant d'envoyer les 8 bits d'un octet, et réactivées (`SREG = sreg`) immédiatement après.
uint8_t spi_transfer(uint8_t data) {
    uint8_t sreg = SREG;
    cli(); // DÉBUT SECTION CRITIQUE
    
    // Bit-banging rapide (quelques microsecondes)
    for (int i=7; i>=0; i--) { ... }
    
    SREG = sreg; // FIN SECTION CRITIQUE
    return received;
}

Shell et Scripting

Le Shell (`shell_core.c`) permet l'interaction utilisateur. Il supporte l'exécution de scripts via la commande `exec`.

Commande EXEC : La commande `exec SCRIPT.TXT` :

  1. Utilise `fat16_read_to_buffer` pour charger le contenu du fichier texte dans la RAM.
  2. Passe ce buffer à l'interpréteur de commandes `shell_process_line`.
  3. Cela permet d'automatiser des séquences de démarrage ou de test.

Guide d'utilisation

Commandes disponibles

Commande Description
`ps` Affiche la liste des tâches, leur état et l'utilisation CPU.
`list` Affiche les fichiers présents sur la carte SD avec leur taille.
`type <fichier>` Affiche le contenu d'un fichier texte.
`create <nom> <txt>` Crée un nouveau fichier contenant le texte spécifié.
`del <nom>` Supprime un fichier (marque comme supprimé).
`exec <script>` Exécute le contenu d'un fichier comme une commande.
`free` Affiche une estimation de la RAM libre.
`reboot` Redémarre le microcontrôleur.

Exemple de Session

Pico> create auto.bat version
Fichier cree.
Pico> exec auto.bat
Exec: auto.bat
Run: version
Pico-OS v1.2 (Dual FAT + Exec)

Modèle d'Ordonnancement

L’ordonnanceur utilise un algorithme **round-robin coopératif** sans préemption. Chaque tâche s’exécute jusqu’à son retour, puis la suivante prend le relais.