Unité 3 / 9

Systèmes embarqués et code de microcontrôleur

Gains :

  • Possibilité de définir les exigences de registre, d'interruption et de synchronisation pour le microcontrôleur avec une invite claire
  • Possibilité de vérifier le code C/Arduino produit par l'IA en termes de paramètres de registre, de débordement de tampon et de contraintes de temps réel
  • Capacité à prendre l'habitude de vérifier le code généré en le mesurant sur du matériel (oscilloscope, port série)

Le développement de systèmes embarqués est l'intersection du logiciel et du matériel : définir incorrectement un bit de registre, maintenir une interruption trop longtemps ou déborder d'un tampon provoquera des échecs étranges et difficiles à reproduire sur le terrain, même si le code "compile" et s'exécute. L’IA est véritablement un accélérateur dans ce domaine ; Il peut produire des squelettes initiaux, des fonctions d'abstraction matérielle, des machines à états et des routines de communication. Mais l'IA ne voit pas la fiche technique de votre carte, ne connaît pas votre fréquence d'horloge et ne détecte pas vos contraintes de temps réel. Dans cette unité, nous expliquerons comment définir clairement le travail du microcontrôleur pour l'IA, comment vérifier le code C/Arduino généré et pourquoi vous devez tout mesurer dans le matériel.

Définir clairement les exigences : registre, coupe, timing

Dire à l’IA « d’allumer une LED » ne fonctionnera pas ; Quelle carte, quelle broche, quelle fréquence d'horloge, quel timing ? Lorsque vous attribuez une tâche intégrée à l'IA, utilisez ce cadre : matériel (famille MCU, horloge, broche), fonction (ce qui va se passer), contrainte (synchronisation, alimentation, mémoire) et interface (registre, HAL, bibliothèque Arduino).

Invite faible/Invite forte

FAIBLE : "Produire du PWM avec STM32." (Résultat : quelle minuterie, quelle fréquence, quelle broche n'est pas claire ; général, probablement un mauvais registre nommé code.) FORT : "Produire 20 kHz, 0-100 % de PWM de service réglable sur TIM3 CH1 (PA6) pour STM32F103 (horloge système de 72 MHz). Écrivez au niveau du registre (pas HAL). - Les valeurs du pré-échelonneur et de l'ARR pour 20 kHz CALCULENT et affichent le calcul dans la ligne de commentaire. - Réglez le devoir avec un paramètre de fonction entre 0 et 100. - Commentez chaque bit de registre que vous utilisez. Notez que les valeurs changeront si votre hypothèse d'horloge est fausse.

La différence est que l'invite puissante permet au modèle d'afficher le calcul et de révéler l'hypothèse d'horloge. Vous pouvez donc vérifier les valeurs du prescaler/ARR indépendamment :

Pour 20 kHz PWM (horloge 72 MHz) :Timer_clock = 72 MHzSi on veut prescaler = 72-1 → compteur horloge = 1 MHzARR = (1 MHz / 20 kHz) - 1 = 50 - 1 = 49Vérification : 1e6 / (49+1) = 20 000 Hz ✓

Audit du code IA : que rechercher ?

Ce n’est pas parce que le code généré se compile qu’il fonctionne correctement. Suivez cette liste de contrôle :

zone de contrôle

Que chercher

Paramètres de registre/bit

Exactement compatible avec la fiche technique, masque de bits correct

Interruption (ISR)

Est-ce court ? Pas de délai de blocage ? Le volatile est-il utilisé ?

tampon/tableau

Y a-t-il un contrôle aux frontières ? Risque de débordement ?

timing

Avec retard ou minuterie ? La contrainte de temps réelle est-elle respectée ?

Type et largeur

Débordement 8/16/32 bits, confusion signé/non signé

puissance/chien de garde

Chien de garde d’alimentation en boucle infinie ?

Les routines de service d'interruption (ISR) sont la source d'erreurs la plus courante. L'IA met parfois un delay() ou une longue boucle à l'intérieur de l'ISR. Cela entraîne l'absence d'autres interruptions et la réinitialisation du chien de garde. Règle : ISR doit être aussi court que possible ; Le travail principal devrait être de mettre en place un drapeau et de le déplacer vers la boucle principale.

// FAIBLE (l'IA produit parfois ceci) : Fonction bloqueur dans ISR void TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; read_sensor(); // peut prendre beaucoup de temps - BAD CASE_Delay(10); // retard dans l'ISR - TRÈS MAUVAIS }}// FORT : ISR court ; le travail se déplace vers la boucle principalevolatile uint8_t tick_flag = 0 ; // volatile CONDITIONvoid TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; tick_flag = 1 ; //juste définir le drapeau }}// dans la boucle principale :if (tick_flag) { tick_flag = 0; read_sensor(); }

Attention : Toute variable partagée entre l'interruption et la boucle principale doit être volatile. Sinon, le compilateur risque de mettre en cache la variable dans le registre et de manquer la mise à jour. L’IA oublie souvent ce mot-clé ; Recherchez-le spécifiquement lors de la lecture du code.

Débordement de tampon et erreurs de type

L'IA peut copier les données du port série dans un tableau de taille fixe sans vérification des limites. Dans un système embarqué, cela signifie écraser la mémoire contiguë et provoquer des plantages inexpliqués. Assurez-vous que la limite est vérifiée à chaque strcpy, index de tableau et tampon DMA. De même, un compteur 8 bits se réinitialise après 255 ; L’IA peut ignorer cela et s’appuyer sur un compte débordant.

Vérification du matériel : le « fonctionnement » est mesuré et non supposé

Dans un système embarqué, la preuve la plus fiable est le compteur, et non le compilateur. Vérifiez le code généré de ces trois manières :

  1. Oscilloscope/analyseur logique : mesurez la fréquence PWM, la synchronisation du signal et la forme d'onde de communication. Si vous vouliez 20 kHz, voyez 20 kHz sur l'écran.
  2. Journal du port série (UART) : imprimez les valeurs des variables, les transitions d'état et les compteurs d'erreurs et comparez-les avec le comportement attendu.
  3. Tests de contrainte et de contrainte : testez si le système résiste à la charge la plus élevée, aux données les plus rapides et au pire timing.

Si la valeur mesurée ne correspond pas au calcul, l'hypothèse d'horloge, la valeur du pré-échelonneur ou le réglage du registre est incorrect ; chasse.

Mini-étui

Une équipe d'étudiants demande à l'IA d'imprimer un code de mesure de distance avec un capteur à ultrasons HC-SR04. Le code compile mais la distance donne toujours des valeurs ridicules. Lorsqu'ils le connectent à l'oscilloscope, ils voient que la jambe d'écho calcule son timing en millisecondes au lieu de microsecondes ; L'IA a utilisé millis() au lieu de micros(). Cette erreur d'un mot a confondu la mesure entière d'un facteur 1000. Lorsqu'ils impriment le temps d'écho brut dans le journal série et le comparent avec une vraie règle, ils trouvent l'erreur et la corrigent. Leçon : le code compilé n'est pas un code correct ; La mesure matérielle révèle immédiatement l'erreur.

Erreurs courantes

  • Accepter les noms de registre et les masques de bits sans les comparer avec la fiche technique.
  • Autoriser un délai de blocage ou un traitement long au sein de l'ISR.
  • Oublier les variables volatiles sur les variables partagées.
  • Contourner la vérification des tampons et des limites du tableau ; je ne vois pas le débordement.
  • S'appuyer sur des hypothèses de fréquence d'horloge et de synchronisation sans les vérifier.
  • Considérer le code "fonctionnant" sans le mesurer avec un oscilloscope/journal série.

En résumé

  • Définissez clairement la tâche intégrée en termes de matériel, de fonction, de contraintes et d'interface.
  • Demandez à l'IA de calculer les valeurs de synchronisation telles que le prescaler/ARR et de les vérifier de manière indépendante.
  • Gardez les ISR courts, utilisez volatile sur les variables partagées.
  • Recherchez spécifiquement les erreurs de registre, de limite de tampon et de largeur de type.
  • "Ça marche" est prouvé avec un oscilloscope, un analyseur logique et un journal série, pas avec le compilateur.
  • Si la valeur mesurée ne correspond pas au calcul, poursuivez les hypothèses.

Tâche de candidature

Avec un microcontrôleur dont vous disposez (Arduino, STM32, ESP32), demandez à l'IA du PWM ou une tâche périodique à une certaine fréquence. Avant de charger le code : (1) vérifiez les valeurs de fréquence/timing indépendamment du compte dans la ligne de commentaire, (2) vérifiez la volatilité et le blocage dans l'ISR et les variables partagées. Après le téléchargement, mesurez la fréquence réelle avec un oscilloscope ou un analyseur logique et comparez-la avec la cible. S'il y a un écart, trouvez la source, corrigez-la, et notez ce qui a été supposé faux.