Jedinica 3 / 9

Ugrađeni sustavi i generiranje koda mikrokontrolera

Dobici:

  • Sposobnost generiranja ugrađenog koda s obzirom na registar i hardverski kontekst za Arduino/STM32/ESP32 s AI
  • Sposobnost prepoznavanja i ispravljanja ugrađenih uzoraka kao što su prekidi, mjerači vremena i neblokirajuće petlje u AI izlazu
  • Mogućnost pregleda generiranog koda u smislu memorije, stvarnog vremena i sigurnosti prije učitavanja na hardver

U mehatronici, mikrokontroler je mjesto gdje se ideje susreću s fizičkim svijetom. Kartice kao što su Arduino, STM32, ESP32; očitava senzore, pokreće aktuatore, komunicira i sve to radi pod ograničenom memorijom, ograničenom procesorskom snagom i strogim vremenskim zahtjevima. Umjetna inteligencija vrlo je korisna u ovom polju: može izdvojiti postavke registra na temelju podatkovne tablice senzora, kodirati komunikacijski protokol, postaviti prekid timera. Ali ugrađeni sustavi jedno su od područja u kojima umjetna inteligencija proizvodi najviše "uvjerljivih laži"; jer su adrese registara, maske bitova i vremensko ponašanje specifični za ploču i jedna pogreška bita remeti cijelo ponašanje. U ovoj jedinici pokrivamo kako imati ugrađeni kod generiran AI i kako ga pregledati prije učitavanja u hardver.

Razlika ugrađenog koda od čistog softvera

Program za stolno računalo ima puno memorije, operativni sustav i jednostavno otklanjanje pogrešaka. Ugrađenom kodu nedostaje većina ovoga:

Veličina

radna površina

ugrađeni sustav

pamćenje

GB razina

KB razina (npr. 2 KB RAM-a)

vrijeme

Općenito fleksibilan

Čvrsto, stvarno vrijeme

otklanjanje pogrešaka

Lako (debugger, log)

Tvrdi (JTAG, serijski, LED)

Rezultat pogreške

Program se ruši

Pokretač/hardver može biti oštećen

pristup resursima

OS sažeci

Izravan pristup Registru

Ove razlike određuju vaše kriterije za procjenu izlaza umjetne inteligencije: upotreba memorije, točnost registra u stvarnom vremenu (bez blokiranja) i hardverski registar su uvijek na vrhu vašeg popisa za provjeru.

Blokirajući nasuprot neblokirajućem kodu

Najčešća pogreška koju čine početnici (i često AI) je korištenje delay(). delay(1000) zaključava procesor na 1 sekundu; Tijekom tog razdoblja ne mogu se očitati nikakvi drugi senzori, niti se mogu kontrolirati nikakvi gumbi. To je nedopustivo u mehatronici. Umjesto toga koristi se neblokirajući uzorak temeljen na millis().

// LOŠE: blokator -- procesor ne može obavljati nikakav drugi posao 1 sekundu void loop() { digitalWrite(LED, HIGH); kašnjenje (1000); // sve se zaustavlja digitalWrite(LED, LOW); kašnjenje (1000); // Trenutačno se ne može pročitati gumb za hitne slučajeve!}// DOBRO: ne blokira -- petlja nije blokirana, drugi se zadaci pokreću ako (nowMs - previousMs >= interval) { previousMs = nowMs; ledStatus = !ledStatus; digitalWrite(LED, ledStatus); } buttonCheck(); // može se izvoditi u svakom ciklusu sensorRead(); //može se izvoditi u bilo kojoj petlji}

Uzorak bez blokiranja osnova je ugrađene mehatronike: kontrolna petlja teče neprekidno, nijedan zadatak ne zaključava drugi. Reći AI-u da "ne koristi odgodu, zapiši bez blokiranja na temelju millisa" kada pišete kod izravno poboljšava kvalitetu izlaza.

Savjet: Potražite kašnjenje( u ugrađenom kodu iz umjetne inteligencije. Ako vidite kašnjenje u glavnoj kontrolnoj petlji, taj kod najčešće nije prikladan za sustav u stvarnom vremenu i treba ga ponovno napisati.

Prekidi i mjerači vremena

Hvatamo vremenski kritične događaje (impuls kodera, gumb, periodično uzorkovanje) s prekidima umjesto čekanja u glavnoj petlji. Prekidnu rutinu (ISR) treba napisati kratko i pažljivo: bez kašnjenja, Serial.printa ili dugih izračuna u njoj; Zajedničke varijable označene su kao nepostojane.

volatile long encoderCounter = 0; // ISR i petlja se dijele -> nestabilno stanje void enkoderISR() { // Kratki ISR: samo brojite, ne radite ništa drugo if (digitalRead(ENC_B)) enkoderCounter++; else encoderCounter--;}void setup() { pinMode(ENC_A, INPUT_PULLUP); pinMode(ENC_B, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(ENC_A), enkoderISR, RISING);}void loop() { long counter; bez prekida(); //kratki prekidi za atomsko čitanje brojača = encoderCounter; prekidi(); //sigurno obavljajte transakcije s brojačem...}

Tri su kritične točke u ovom primjeru gdje AI često promašuje: (1) dijeljeni encoderCounter mora biti "nepostojan" ili će optimizacija prevoditelja propustiti ažuriranja; (2) ISR treba biti kratak; (3) Prilikom čitanja višebajtne varijable u glavnoj petlji, prekidi za atomsko čitanje moraju biti zatvoreni na kratko vrijeme, inače ISR može intervenirati tijekom čitanja i može se pročitati polovična/pokvarena vrijednost (stanje utrke). Svakako provjerite jesu li ova tri prisutna u AI kodu.

Registrirajte točnost i podatkovnu tablicu

AI može vjerodostojno pogrešno prikazati adresu registra senzora ili konfiguracijski bit MCU-a. Na primjer, registar upravljanja napajanjem MPU6050 IMU je 0x6B; Ako AI ovo daje kao 0x6A, kod je kompajliran, čini se da radi, ali senzor se ne budi. Takve se pogreške otkrivaju samo u usporedbi s podatkovnom tablicom.

// MPU6050 buđenje: prema podatkovnoj tablici PWR_MGMT_1 = 0x6B, vrijednost 0x00#define MPU_ADDR 0x68#define PWR_MGMT_1 0x6B // <-- VERIFY iz datasheetWire.beginTransmission(MPU_ADDR);Wire.write(PWR_MGMT_1);Wire.write(0x00); // probudi se iz stanja mirovanjaWire.endTransmission(true);

Pažnja: Provjerite svaku adresu registra, masku bita i I2C/SPI adresu koju je dao AI iz podatkovne tablice. Ove vrijednosti su specifične za karticu i čip; Vrijednost koju AI "pamti" može biti iz druge revizije čipa. Netočan registar tiho dovodi do netočnog ponašanja.

Slab upit / Jak upit

SLABO: "Očitajte senzor temperature na ESP32." (Koji senzor? Koji protokol? Koji pin? Generički, vjerojatno pogrešan kod.) JAKO: "Očitajte senzor temperature DS18B20 na ESP32 (Arduino framework) iz GPIO4 s OneWireom. Pišite bez blokiranja, uzorkujte svaku 1 sekundu (koristeći odgodu, na temelju millisa). Postavite oznaku pogreške u slučaju pogreške čitanja (fiksna vrijednost). -127 ili 85). Navedite svaku biblioteku i pin vezu koju koristite u prvom komentaru, koristite char buffer umjesto String."

Snažan brz; Daje čip, okvir, senzor, protokol, pin, uzorak uzorkovanja, status pogreške i memorijsko ograničenje. Na ovaj način rezultat je i provjerljiv i realan.

Pregledajte kontrolni popis za ugrađeni kod

Prije učitavanja AI izlaza, prođite kroz ovaj popis:

  1. Blokiranje: Postoji li kašnjenje ili dugo blokiranje u glavnoj petlji?
  2. volatile: Jesu li varijable koje se dijele s ISR-om nestabilne?
  3. Atomski pristup: Je li višebajtna dijeljena varijabla sigurna za čitanje?
  4. Registrirajte se: Jesu li adrese i bit maske kompatibilne s podatkovnom tablicom?
  5. Memorija: String, veliki nizovi, stvara li rekurzija prekoračenje razine KB?
  6. Rješavanje pogrešaka: obrađuju li se pogreške u očitanju senzora, komunikacijski istek vremena?
  7. Siguran početak: Jesu li izlazi aktuatora postavljeni u sigurno (pasivno) stanje pri pokretanju?

Mini torbica

Inženjer ugrađenih sustava Baran ima AI da napiše kod koji čita IMU za dron. Kod se kompajlira i čini se da radi, ali vrijednosti kuta su besmislene. Baran primjenjuje popis za provjeru: uspoređuje adrese registara s podatkovnom tablicom i otkriva da AI netočno šalje registar konfiguracije žiroskopa (0x1A umjesto 0x1B), tako da je ljestvica osjetljivosti pogrešna. Nakon korekcije, vrijednosti se slažu. Zatim delay(10) obavještava u glavnoj petlji; pretvarajući ovo u strukturu temeljenu na milisisima, jer je blokiranje petlje kontrole leta neprihvatljivo. Konačno, vidi da dijeljena varijabla brojača nije nepostojana i dodaje je. AI je brzo dao kostur; Ali popis za pregled uhvatio je tri odvojene pogreške: registraciju, blokiranje i nepostojanost, a hardver uopće nije bio u opasnosti.

Uobičajene greške

  • Uništavanje odgovora u stvarnom vremenu korištenjem delay() u glavnoj kontrolnoj petlji.
  • Izbjegavajte da varijabla koja se dijeli s ISR-om postane nestabilna i da dođe do tihog oštećenja podataka.
  • Čitanje višebajtne zajedničke varijable neatomski i generiranje uvjeta utrke.
  • Ne provjerava maske registra/bita koje daje AI s podatkovnom tablicom.
  • Stvaranje preljeva memorije korištenjem nizova i velikih polja u ograničenom RAM-u.
  • Zaboravljanje inicijalno osiguravanja izlaza aktuatora.

Ukratko

  • Ugrađeni kod; Radi s ograničenom memorijom, ograničenim vremenom i izravnim pristupom registru.
  • U glavnoj petlji umjesto odgode koristi se neblokirajući uzorak temeljen na milisekundama.
  • ISR je kratak; zajedničke varijable moraju biti nepostojane i pristupati im se atomski.
  • Adrese registara i bit maske uvijek se provjeravaju prema podatkovnoj tablici; AI može biti u krivu.
  • Memorija, rukovanje pogreškama i status sigurnog pokretanja uvijek se provjeravaju.
  • Snažan brz; Uključuje čip, okvir, senzor, protokol, pin i ograničenja.

Zadatak aplikacije

Odaberite senzor (npr. DS18B20, MPU6050 ili HC-SR04) i mikrokontroler (Arduino/ESP32/STM32). Neka AI generira neblokirajući kod za čitanje pomoću moćnog predloška upita u ovoj jedinici. Zatim slijedite sedam stavki popisa za pregled jednu po jednu: usporedite barem jednu vrijednost registra/pina s podatkovnom tablicom, provjerite kašnjenja petlje, provjerite nestabilni status zajedničkih varijabli. Koliko je zadataka "prošlo" u prvom pokušaju, a koliko ih je trebalo ispraviti? Zabilježite svaki problem koji pronađete i njegovo rješenje.