Unità 3 / 9

Sistemi embedded e codice del microcontrollore

Guadagni:

  • Capacità di definire i requisiti di registro, interruzione e temporizzazione per il microcontrollore con un prompt chiaro
  • Possibilità di controllare il codice C/Arduino prodotto dall'AI in termini di impostazioni di registro, buffer overflow e vincoli in tempo reale
  • Capacità di applicare l'abitudine di verificare il codice generato misurandolo su hardware (oscilloscopio, porta seriale)

Lo sviluppo di sistemi embedded è il punto in cui software e hardware si intersecano: l'impostazione errata di un bit di registro, il mantenimento di un'interruzione troppo a lungo o il sovraccarico di un buffer causeranno errori strani e difficili da riprodurre sul campo, anche se il codice "si compila" e viene eseguito. L’intelligenza artificiale è davvero un acceleratore in questo ambito; Può produrre scheletri iniziali, funzioni di astrazione hardware, macchine a stati e routine di comunicazione. Ma l'intelligenza artificiale non vede la scheda tecnica della tua carta, non conosce la frequenza del tuo orologio e non rileva i tuoi vincoli in tempo reale. In questa unità tratteremo come definire chiaramente il funzionamento del microcontrollore per l'intelligenza artificiale, come controllare il codice C/Arduino generato e perché dovresti misurare tutto nell'hardware.

Definire chiaramente il requisito: registro, taglio, tempistica

Dire all'IA di "accendere un LED" non funzionerà; Quale carta, quale pin, quale frequenza di clock, quale temporizzazione? Quando assegni un'attività incorporata all'intelligenza artificiale, utilizza questo framework: hardware (famiglia MCU, orologio, pin), funzione (cosa accadrà), vincolo (tempistiche, potenza, memoria) e interfaccia (registro, HAL, libreria Arduino).

Prompt debole / Prompt forte

DEBOLE: "Produci PWM con STM32." (Risultato: quale timer, quale frequenza, quale pin non è chiaro; generale, probabilmente codice nome registro errato.) FORTE: "Produce 20 kHz, 0-100% PWM di servizio regolabile su TIM3 CH1 (PA6) per STM32F103 (orologio di sistema a 72 MHz). Scrivere a livello di registro (non HAL). - I valori di prescaler e ARR per 20 kHz CALCOLANO e mostrano il calcolo nella riga di commento. - Impostare il servizio con un parametro di funzione compreso tra 0-100 - Commenta ogni bit di registro che usi. Tieni presente che i valori cambieranno se il presupposto dell'orologio è sbagliato.

La differenza è che il potente prompt fa sì che il modello mostri il calcolo e riveli l'ipotesi dell'orologio. Quindi puoi controllare i valori prescaler/ARR in modo indipendente:

Per PWM a 20 kHz (orologio a 72 MHz):Timer_clock = 72 MHzSe vogliamo prescaler = 72-1 → contatore orologio = 1 MHzARR = (1 MHz / 20 kHz) - 1 = 50 - 1 = 49Verifica: 1e6 / (49+1) = 20 000 Hz ✓

Controllo del codice AI: cosa cercare?

Solo perché il codice generato viene compilato non significa che funzioni correttamente. Segui questa lista di controllo:

zona di controllo

Cosa cercare

Impostazioni registro/bit

Perfettamente compatibile con la scheda tecnica, maschera di bit corretta

Interruzione (ISR)

È corto? Nessun ritardo bloccante? Viene utilizzato il volatile?

buffer/array

C'è il controllo delle frontiere? Rischio di traboccamento?

tempistica

Con ritardo o timer? I vincoli temporali effettivi sono rispettati?

Tipo e larghezza

Overflow 8/16/32 bit, confusione con segno/senza segno

potere/guardiano

Cane da guardia di alimentazione a ciclo infinito?

Le routine di servizio di interruzione (ISR) sono la fonte di errori più comune. L'intelligenza artificiale a volte inserisce il ritardo() o il ciclo lungo all'interno dell'ISR. Ciò porta alla perdita di altri interrupt e al ripristino del watchdog. Regola: la PVR dovrebbe essere la più breve possibile; Il lavoro principale dovrebbe essere quello di impostare un flag e spostarlo nel ciclo principale.

// DEBOLE (l'AI a volte produce questo): Funzione bloccante in ISR void TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; leggi_sensore(); // potrebbe richiedere molto tempo - BAD CASE_Delay(10); // ritardo nell'ISR - MOLTO CATTIVO }}// FORTE: ISR corto; il lavoro si sposta nel loop volatile principale uint8_t tick_flag = 0; // CONDIZIONE volatilevoid TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; tick_flag = 1; //imposta semplicemente il flag }}// nel ciclo principale:if (tick_flag) { tick_flag = 0; leggi_sensore(); }

Attenzione: qualsiasi variabile condivisa tra l'interrupt e il ciclo principale deve essere volatile. In caso contrario, il compilatore potrebbe memorizzare nella cache la variabile nel registro e perdere l'aggiornamento. L'intelligenza artificiale spesso dimentica questa parola chiave; Cercalo specificamente durante la lettura del codice.

Overflow del buffer ed errori di tipo

L'intelligenza artificiale può copiare i dati dalla porta seriale in un array di dimensioni fisse senza controllo dei limiti. In un sistema embedded, ciò significa schiacciare la memoria contigua e crash inspiegabili. Assicurati che il limite sia controllato su ogni strcpy, indice di array e buffer DMA. Allo stesso modo, un contatore a 8 bit si reimposta dopo 255; L’intelligenza artificiale può ignorarlo e fare affidamento su un conto in eccesso.

Verifica nell'hardware: il "funzionamento" è misurato, non dato per scontato

In un sistema embedded, la prova più affidabile è il misuratore, non il compilatore. Verifica il codice generato in questi tre modi:

  1. Oscilloscopio/analizzatore logico: misura la frequenza PWM, la temporizzazione del segnale e la forma d'onda di comunicazione. Se desideri 20 kHz, vedi 20 kHz sullo schermo.
  2. Registro della porta seriale (UART): stampa valori di variabili, transizioni di stato e contatori di errori e confronta con il comportamento previsto.
  3. Test vincolati e di stress: verifica se il sistema regge sotto il carico più elevato, i dati più veloci e i tempi peggiori.

Se il valore misurato non concorda con il calcolo, il presupposto dell'orologio, il valore del prescaler o l'impostazione del registro non sono corretti; caccia.

Mini custodia

Un team di studenti fa stampare all’IA un codice di misurazione della distanza con un sensore a ultrasuoni HC-SR04. Il codice viene compilato ma la distanza dà sempre valori ridicoli. Quando lo collegano all'oscilloscopio, vedono che la gamba dell'eco calcola i suoi tempi in millisecondi anziché in microsecondi; L'intelligenza artificiale ha utilizzato millis() invece di micros(). Questo errore di una parola ha confuso l'intera misurazione di un fattore 1000. Quando stampano il tempo dell'eco grezzo nel registro seriale e lo confrontano con un righello reale, trovano l'errore e lo correggono. Lezione: il codice compilato non è codice corretto; La misurazione nell'hardware rivela immediatamente l'errore.

Errori comuni

  • Accettare nomi di registri e maschere di bit senza confrontarli con il foglio dati.
  • Consentire il ritardo di blocco o l'elaborazione lunga all'interno dell'ISR.
  • Dimenticando volatile sulle variabili condivise.
  • Bypassare il buffer e il controllo dei limiti dell'array; non vedere l'overflow.
  • Affidarsi alla frequenza di clock e alle ipotesi temporali senza verificarle.
  • Considerare il codice "funzionante" senza misurarlo con oscilloscopio/log seriale.

In sintesi

  • Definire chiaramente l'attività integrata in termini di hardware, funzione, vincoli e interfaccia.
  • Chiedi all'IA di calcolare i valori temporali come prescaler/ARR e di verificarli in modo indipendente.
  • Mantieni gli ISR ​​brevi, usa volatile sulle variabili condivise.
  • Cerca in particolare gli errori di registro, limite buffer e larghezza del tipo.
  • "Funziona" è dimostrato con un oscilloscopio, un analizzatore logico e un registro seriale, non con il compilatore.
  • Se il valore misurato non concorda con il calcolo, inseguire le ipotesi.

Compito dell'applicazione

Con un microcontrollore che possiedi (Arduino, STM32, ESP32), chiedi all'IA il PWM o un'attività periodica ad una certa frequenza. Prima di caricare il codice: (1) verificare i valori di frequenza/temporizzazione indipendentemente dall'account nella riga dei commenti, (2) verificare la presenza di variabili volatili e bloccanti nell'ISR e nelle variabili condivise. Dopo il caricamento, misurare la frequenza effettiva con un oscilloscopio o un analizzatore logico e confrontarla con il target. Se c'è una deviazione, trova la fonte e correggila, e annota cosa si presumeva sbagliato.