Jednostka 3 / 9

Systemy wbudowane i kod mikrokontrolera

Zyski:

  • Możliwość definiowania wymagań dotyczących rejestrów, przerwań i taktowania mikrokontrolera za pomocą przejrzystego podpowiedzi
  • Możliwość sprawdzenia kodu C/Arduino wytworzonego przez sztuczną inteligencję pod kątem ustawień rejestrów, przepełnienia bufora i ograniczeń w czasie rzeczywistym
  • Umiejętność zastosowania nawyku weryfikacji wygenerowanego kodu poprzez pomiar go na sprzęcie (oscyloskop, port szeregowy)

Rozwój systemów wbudowanych ma miejsce tam, gdzie oprogramowanie i sprzęt przecinają się: nieprawidłowe ustawienie bitu rejestru, zbyt długie wstrzymywanie przerwania lub przepełnienie bufora spowoduje dziwne, trudne do odtworzenia błędy w terenie, nawet jeśli kod „kompiluje się” i działa. Sztuczna inteligencja jest prawdziwym akceleratorem w tej dziedzinie; Może tworzyć początkowe szkielety, funkcje abstrakcji sprzętu, maszyny stanowe i procedury komunikacyjne. Ale sztuczna inteligencja nie widzi arkusza danych twojej karty, nie zna częstotliwości zegara i nie wyczuwa ograniczeń w czasie rzeczywistym. W tym rozdziale omówimy, jak jasno zdefiniować pracę mikrokontrolera dla AI, jak sprawdzić wygenerowany kod C/Arduino i dlaczego należy mierzyć wszystko sprzętowo.

Jasne zdefiniowanie wymagań: rejestr, cięcie, harmonogram

Nakazanie AI, aby „zapaliła diodę LED”, nie zadziała; Która karta, jaki pin, jaka częstotliwość taktowania, jakie taktowanie? Przypisując wbudowane zadanie do AI, użyj tego frameworka: sprzęt (rodzina MCU, zegar, pin), funkcja (co się stanie), ograniczenie (czas, moc, pamięć) i interfejs (rejestr, HAL, biblioteka Arduino).

Słaba podpowiedź/silna podpowiedź

SŁABY: „Wytwórz PWM za pomocą STM32”. (Wynik: który timer, która częstotliwość, który pin jest niejasny; ogólnie, prawdopodobnie błędny kod nazwy rejestru.) STRONG: „Wytwórz PWM 20 kHz, 0-100% regulowanego obciążenia na TIM3 CH1 (PA6) dla STM32F103 (zegar systemowy 72 MHz). Zapisz na poziomie rejestru (nie HAL). - Wartości preskalera i ARR dla 20 kHz OBLICZ i pokaż obliczenia w wierszu komentarza. - Ustaw obciążenie z parametrem funkcji pomiędzy 0-100 - Skomentuj każdy używany bit rejestru. Pamiętaj, że wartości ulegną zmianie, jeśli twoje założenia dotyczące zegara są błędne.

Różnica polega na tym, że potężny monit sprawia, że ​​model pokazuje obliczenia i ujawnia założenia zegara. Możesz więc niezależnie sprawdzić wartości preskalera/ARR:

Dla 20 kHz PWM (zegar 72 MHz): Timer_clock = 72 MHz Jeśli chcemy preskalera = 72-1 → zegar licznika = 1 MHzARR = (1 MHz / 20 kHz) - 1 = 50 - 1 = 49Weryfikacja: 1e6 / (49+1) = 20 000 Hz ✓

Audyt kodu AI: na co zwrócić uwagę?

To, że wygenerowany kod się kompiluje, nie oznacza, że ​​działa poprawnie. Postępuj zgodnie z poniższą listą kontrolną:

obszar kontrolny

Czego szukać

Ustawienia rejestru/bitu

Dokładnie zgodny z arkuszem danych, poprawna maska ​​bitowa

Przerwanie (ISR)

Czy jest krótki? Nie ma opóźnienia blokowania? Czy używany jest lotny?

bufor/tablica

Czy jest kontrola graniczna? Ryzyko przepełnienia?

czas

Z opóźnieniem czy timerem? Czy dotrzymano faktycznego limitu czasowego?

Typ i szerokość

Przepełnienie 8/16/32-bitowe, zamieszanie ze znakiem/bez znaku

władza/stróż

Strażnik karmienia w nieskończonej pętli?

Procedury obsługi przerwań (ISR) są najczęstszym źródłem błędów. AI czasami umieszcza opóźnienie() lub długą pętlę wewnątrz ISR. Prowadzi to do pominięcia innych przerwań i zresetowania układu watchdog. Zasada: ISR powinien być jak najkrótszy; Głównym zadaniem powinno być ustawienie flagi i przeniesienie jej do głównej pętli.

// SŁABY (AI czasami to produkuje): Funkcja blokująca w ISR void TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; czujnik_czytania(); // może zająć dużo czasu - BAD CASE_Delay(10); // opóźnienie ISR - BARDZO ZŁE }}// SILNE: ISR krótki; zadanie zostaje przeniesione do głównej pętlivolatile uint8_t tick_flag = 0; // volatile CONDITIONvoid TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; tick_flag = 1; //po prostu ustaw flagę }}// w głównej pętli:if (tick_flag) { tick_flag = 0; czujnik_czytania(); }

Uwaga: Każda zmienna współdzielona pomiędzy przerwaniem a pętlą główną musi być niestabilna. W przeciwnym razie kompilator może buforować zmienną w rejestrze i przegapić aktualizację. AI często zapomina o tym słowie kluczowym; Szukaj go szczególnie podczas czytania kodu.

Przepełnienie bufora i błędy typu

Sztuczna inteligencja może kopiować dane z portu szeregowego do tablicy o stałym rozmiarze bez sprawdzania granic. W systemie wbudowanym oznacza to zniszczenie ciągłej pamięci i niewyjaśnione awarie. Upewnij się, że limit jest sprawdzany w każdym strcpy, indeksie tablicy i buforze DMA. Podobnie 8-bitowy licznik resetuje się po 255; Sztuczna inteligencja może to zignorować i polegać na przepełnionym koncie.

Weryfikacja sprzętowa: „Działanie” jest mierzone, a nie zakładane

W systemie wbudowanym najbardziej wiarygodnym dowodem jest licznik, a nie kompilator. Zweryfikuj wygenerowany kod na trzy sposoby:

  1. Oscyloskop/analizator stanów logicznych: Zmierz częstotliwość PWM, synchronizację sygnału i kształt fali komunikacyjnej. Jeśli chcesz 20 kHz, zobacz 20 kHz na ekranie.
  2. Dziennik portu szeregowego (UART): Wydrukuj wartości zmiennych, zmiany stanów i liczniki błędów i porównaj z oczekiwanym zachowaniem.
  3. Testowanie powiązane i obciążeniowe: sprawdź, czy system wytrzymuje największe obciążenie, najszybsze przesyłanie danych i najgorszy czas.

Jeżeli wartość zmierzona nie zgadza się z obliczeniami, założenie zegara, wartość preskalera lub ustawienie rejestru są nieprawidłowe; pościg.

Mini etui

Zespół studentów każe AI wydrukować kod pomiaru odległości za pomocą czujnika ultradźwiękowego HC-SR04. Kod się kompiluje, ale odległość zawsze daje absurdalne wartości. Kiedy podłączają go do oscyloskopu, widzą, że odnoga echa oblicza swój czas w milisekundach zamiast w mikrosekundach; AI użyła millis() zamiast micros(). Ten błąd w jednym słowie zakłócił cały pomiar 1000-krotnie. Kiedy wypiszą surowy czas echa do dziennika szeregowego i porównają go z prawdziwą linijką, znajdują błąd i go naprawiają. Lekcja: skompilowany kod nie jest poprawnym kodem; Pomiar sprzętowy natychmiast ujawnia błąd.

Typowe błędy

  • Akceptowanie nazw rejestrów i masek bitowych bez porównywania ich z arkuszem danych.
  • Zezwalanie na opóźnienie blokowania lub długie przetwarzanie w obrębie ISR.
  • Zapominanie o zmiennych w przypadku zmiennych współdzielonych.
  • Obejście bufora i sprawdzanie granic tablicy; nie widząc przepełnienia.
  • Opieranie się na założeniach dotyczących częstotliwości zegara i czasu bez ich weryfikacji.
  • Rozważenie kodu „działającego” bez pomiaru go za pomocą oscyloskopu/dziennika szeregowego.

Podsumowując

  • Jasno zdefiniuj wbudowane zadanie pod względem sprzętu, funkcji, ograniczeń i interfejsu.
  • Niech sztuczna inteligencja obliczy wartości taktowania, takie jak preskaler/ARR i niezależnie je zweryfikuje.
  • Utrzymuj krótkie ISR, używaj zmiennych w przypadku zmiennych współdzielonych.
  • W szczególności poszukaj błędów rejestru, limitu bufora i szerokości typu.
  • „To działa” można sprawdzić za pomocą oscyloskopu, analizatora stanów logicznych i dziennika szeregowego, a nie za pomocą kompilatora.
  • Jeśli zmierzona wartość nie zgadza się z obliczeniami, goń się za założeniami.

Zadanie aplikacji

Mając mikrokontroler (Arduino, STM32, ESP32), poproś sztuczną inteligencję o PWM lub zadanie okresowe z określoną częstotliwością. Przed załadowaniem kodu: (1) sprawdź w komentarzu wartości częstotliwości/czasu niezależnie od konta, (2) sprawdź pod kątem zmienności i blokowania w ISR i zmiennych współdzielonych. Po przesłaniu zmierz rzeczywistą częstotliwość za pomocą oscyloskopu lub analizatora stanów logicznych i porównaj ją z wartością docelową. Jeśli występuje odchylenie, znajdź jego źródło, popraw je i zanotuj, co zostało przyjęte błędnie.