Vérifier les pilotes MCU assistés par IA : registres, temporisation et chemins d’erreur

Le développement de pilotes MCU assisté par IA exige une revue qui atteigne les registres matériels, au-delà du compilateur. Une fonction plausible peut mal interpréter un registre, attendre indéfiniment ou renvoyer une ancienne donnée après un défaut. Le livrable utile est un petit correctif dont les hypothèses, les chemins d’échec et les preuves de réception peuvent être vérifiés pour un composant précis.

Cet article présente un périphérique d’acquisition inventé et des exemples volontairement construits de code de type généré, défectueux puis revu. Aucun outil d’IA n’a été exécuté pour cet exemple ; aucun essai matériel ni mesure temporelle n’est rapporté. Ces extraits sont pédagogiques, pas des modèles prêts à charger sur une carte.

1. Préparer des entrées qui encadrent le brouillon

Commencez par la référence complète du MCU, la révision du silicium, celle de la carte, la version du manuel de référence, les errata et le commit exact du SDK ou des en-têtes du composant. Fournissez les pages des registres concernés, pas seulement le nom de la famille. Deux composants voisins peuvent proposer des indicateurs de noms similaires mais avec des règles d’effacement différentes. Le modèle ne doit pas combler cette lacune en se souvenant d’un composant proche.

Ajoutez l’arbre d’horloge réellement choisi, les débits permis, l’état du périphérique après réinitialisation, l’affectation des broches et les contraintes des modes d’alimentation. Précisez si l’appelant s’exécute dans une tâche ou une interruption, si le DMA intervient, qui possède le périphérique et comment fonctionne l’annulation. Définissez les résultats de succès, expiration, défaut matériel et argument invalide avant de demander du code. Si une entrée manque, demandez de nommer l’incertitude et de laisser un emplacement explicite.

Un bon mandat est limité : concevoir une seule transaction d’acquisition bornée avec les définitions fournies, identifier chaque hypothèse issue du manuel et ne pas inventer d’adresse, de valeur de réinitialisation ou de contournement d’erratum. Demandez séparément la liste des incertitudes et un plan d’essai. Les documents sous licence et schémas confidentiels doivent rester dans le cadre de partage approuvé du projet.

Chaîne de revue des pilotes MCU reliant les données exactes du composant aux registres, aux transitions bornées et aux preuves de réception.
Chaîne de revue proposée. Elle ne représente ni exécution matérielle ni résultat mesuré.

2. Lire le brouillon défectueux comme une série d’affirmations

/* Invented teaching peripheral: deliberately flawed */
ACQ->STATUS |= DONE;
ACQ->DIV = 48000000 / requested_hz;
ACQ->CTRL |= START;
while (!(ACQ->STATUS & DONE)) { }
return ACQ->DATA;

La première ligne est le point de revue prioritaire. Supposons que le registre STATUS inventé contienne des bits de fin et de défaut effacés par écriture d’un un. Une lecture-modification-écriture peut réécrire des uns correspondant à d’autres événements en attente et les effacer. Une mise à jour de type RAM est donc une mauvaise abstraction. La description des registres CMSIS-SVD d’Arm distingue explicitement les attributs d’accès, les effets particuliers des écritures et ceux des lectures. Un fichier SVD aide la revue, mais le manuel exact et les errata restent nécessaires.

La constante 48 MHz suppose silencieusement une fréquence fixe pour le périphérique. La division suppose un codage particulier du diviseur et une règle d’arrondi. Rien ne l’établit. Une fréquence demandée nulle provoque une division par zéro ; une fréquence élevée peut produire un diviseur interdit. Même un résultat numériquement valide peut dépasser l’horloge permise du capteur ou violer son temps d’établissement.

La boucle n’a ni échéance ni branche de défaut. Un périphérique déconnecté, une horloge arrêtée ou un débordement non traité peuvent bloquer l’appelant indéfiniment. Faute de résultat d’état indépendant, la fonction ne distingue pas non plus une donnée valide de toutes les erreurs possibles. Enfin, elle suppose qu’aucune interruption ni seconde tâche n’acquitte le même indicateur. Ce sont des défauts de comportement même si tous les noms compilent correctement.

3. Revoir la correction avant de la traduire en accès aux registres

/* Review pseudocode, not a device implementation. */
require(exclusive_owner && output != NULL);
require(valid_clock_and_divider(clock_hz, requested_hz));
require(timer_runs_during_wait && budget_within_wrap_limit);

prepare_idle_device_or_fail();   // bounded, device-specific
ack_owned_stale_flags();        // exact manual-defined write
configure_validated_divider();
start = monotonic_ticks();
start_one_transfer();
for (;;) {
    s = read_non_destructive_status();
    if (s & FAULTS) {
        capture_fault(s);
        return abort_and_quiesce_or_mark_unusable(IO_ERROR);
    }
    if (s & DONE) {
        value = read_result_in_required_order();
        acknowledge_owned_completion();
        *output = value;
        return OK;
    }
    if (elapsed_unsigned(start) >= budget_ticks)
        return abort_and_quiesce_or_mark_unusable(TIMEOUT);
}

La correction sépare volontairement la politique des accès au composant. Chaque fonction auxiliaire demande une implémentation revue pour le silicium choisi. Pour le registre fictif à effacement par écriture d’un un, acquitter signifie écrire uniquement le masque documenté dont on a la responsabilité, sans lecture préalable. Cette règle ne se transpose pas à un registre effacé à la lecture ni à un composant imposant un ordre de lecture état/données.

L’exemple suppose un seul propriétaire, une seule transaction en cours et une lecture d’état non destructive. Si défaut et fin sont observés ensemble, le défaut prévaut : cette API pédagogique ne doit pas rendre une donnée suspecte comme un succès. Un autre produit peut demander une politique différente ; explicitez ce choix. Après expiration, le périphérique doit être inactif ou déclaré inutilisable jusqu’à réussite d’une réinitialisation bornée. Renvoyer une erreur alors que le DMA écrit encore dans un tampon libéré n’est pas une reprise sûre.

Utilisez une source de temps monotone dont le comportement est connu dans les états d’alimentation et d’interruption concernés. Un calcul non signé du temps écoulé ne gère le rebouclage du compteur que dans un intervalle et un modèle d’observation documentés. Fixez le budget maximal et assurez-vous que le compteur continue d’avancer. Une expiration fondée sur un tick entretenu par interruption peut échouer si la boucle empêche cette interruption de s’exécuter.

4. Examiner séparément temporisation, concurrence et responsabilité des erreurs

Construisez une liste de contrôle à partir du manuel : largeur d’accès, alignement, bits réservés, protection en écriture, valeurs de réinitialisation, séquence d’effacement et prérequis d’horloge/réinitialisation. Justifiez chaque accès. N’ajoutez pas de barrières mémoire simplement par prudence apparente ; les exigences de l’architecture et du composant doivent expliquer l’ordre à imposer.

Pour la temporisation, calculez la fréquence programmée à partir de l’horloge retenue, du codage réel du diviseur et de l’arrondi. Comparez-la aux limites du périphérique et à l’erreur admise par l’application. Incluez la durée de conversion, les temps d’établissement et de maintien de sélection de circuit si applicables, ainsi que la reprise après défaut. Il s’agit de calculs proposés, pas de performances mesurées.

Pour la concurrence, choisissez un propriétaire de l’état de transaction et de son achèvement. Vérifiez priorité d’interruption, données partagées, annulation et contexte des rappels par rapport à l’API RTOS choisie. Une variable volatile ne constitue pas une synchronisation complète. Pour le DMA, documentez la durée de vie du tampon, l’accessibilité mémoire et les opérations de cache propres à la plateforme. Ces obligations subsistent même avec un nom de fonction fournisseur familier.

5. Transformer la revue en essais réfutables

  • Tests du modèle de registres : simuler l’effacement par écriture d’un un, DONE et FAULT simultanés, un ancien indicateur de fin et les bits réservés. La réception exige les écritures exactes prévues et aucun acquittement d’indicateur étranger.
  • Tests aux limites : essayer les fréquences nulles et hors plage, les diviseurs autorisés minimal et maximal, le rebouclage du compteur et une horloge indisponible. Le résultat attendu est un refus défini ou un échec borné, sans faux succès.
  • Tests de propriété : injecter une annulation et un second appelant à chaque transition. Le plan doit démontrer qu’un tampon ne peut être réutilisé tant que le matériel le possède et que l’achèvement n’est signalé qu’une fois au maximum.
  • Tests sur banc : sur la carte retenue, capturer les signaux d’horloge, de données et de commande pertinents, répéter les démarrages à froid et couvrir les conditions d’alimentation et de température prises en charge. Comparer les mesures aux limites convenues ; voir une forme d’onde ne suffit pas à réussir.
  • Tests de reprise : supprimer la réponse du périphérique ou injecter sans danger un défaut prévu. Confirmer l’état d’expiration, la durée de reprise et le comportement de la transaction suivante, y compris l’état explicitement inutilisable si la réinitialisation échoue.

Conservez commit du firmware, options de compilation, identité de carte, montage, limite attendue, observation réelle et emplacement des traces brutes. La simulation établit un comportement logiciel dans un modèle ; les traces de banc établissent celui de l’assemblage testé dans les conditions annoncées. Ni l’une ni les autres ne justifient une fiabilité sans restriction.

6. Constituer le résultat revu par un humain

Le dossier doit relier chaque accès modifié à sa source, chaque branche d’échec à un essai et chaque hypothèse ouverte à un responsable. Gardez le brouillon défectueux s’il explique la correction, mais n’acceptez que le diff revu. Une seconde revue par IA peut poser des questions utiles ; son accord ne certifie pas le premier brouillon.

Pour un projet produit, le service de diagnostic firmware et BSP d’Obeita constitue un point d’échange technique pertinent. Le projet d’acquisition de données STM32 fournit un contexte voisin d’acquisition et d’intégration applicative. Ce lien ne signifie pas que le pilote fictif ci-dessus a été utilisé, généré par IA ou testé dans cette livraison.

Publications similaires