Eenheid 3 / 9

Ingebouwde systemen en microcontrollercode

Winst:

  • Mogelijkheid om register-, interrupt- en timingvereisten voor de microcontroller te definiëren met een duidelijke prompt
  • Mogelijkheid om de door AI geproduceerde C/Arduino-code te controleren op het gebied van registerinstellingen, bufferoverflow en realtimebeperkingen
  • Mogelijkheid om de gewoonte toe te passen om de gegenereerde code te verifiëren door deze op hardware te meten (oscilloscoop, seriële poort)

Bij de ontwikkeling van ingebedde systemen kruisen software en hardware elkaar: het verkeerd instellen van een registerbit, het te lang vasthouden van een interrupt of het overlopen van een buffer zullen vreemde, moeilijk te reproduceren fouten in het veld veroorzaken, ook al wordt de code "gecompileerd" en uitgevoerd. AI is op dit gebied echt een versneller; Het kan initiële skeletten, hardware-abstractiefuncties, statusmachines en communicatieroutines produceren. Maar AI ziet de datasheet van uw kaart niet, kent uw klokfrequentie niet en voelt uw realtime beperkingen niet. In dit onderdeel bespreken we hoe je het werk van microcontrollers duidelijk kunt definiëren voor AI, hoe je de gegenereerde C/Arduino-code kunt controleren en waarom je alles in de hardware zou moeten meten.

De vereisten duidelijk definiëren: registreren, snijden, timing

AI vertellen dat hij "een LED moet laten oplichten" zal niet werken; Welke kaart, welke pin, welke klokfrequentie, welke timing? Wanneer u een ingebedde taak aan AI toewijst, gebruik dan dit raamwerk: hardware (MCU-familie, klok, pin), functie (wat zal er gebeuren), beperking (timing, vermogen, geheugen) en interface (register, HAL, Arduino-bibliotheek).

Zwakke prompt/sterke prompt

ZWAK: "Produceer PWM met STM32." (Resultaat: welke timer, welke frequentie, welke pin is onduidelijk; algemeen, waarschijnlijk verkeerde registernaamcode.) STRONG: "Produceer 20 kHz, 0-100% instelbare duty PWM op TIM3 CH1 (PA6) voor STM32F103 (72 MHz systeemklok). Schrijf op registerniveau (niet HAL). - Prescaler- en ARR-waarden voor 20 kHz CALCULATE en toon de berekening in de commentaarregel. - Stel de duty in met een functieparameter tussen 0-100 - Geef commentaar op elke registerbit die u gebruikt. Merk op dat de waarden zullen veranderen als uw klokaanname verkeerd is.

Het verschil is dat de krachtige prompt ervoor zorgt dat het model de berekening toont en de klokaanname onthult. U kunt de prescaler/ARR-waarden dus onafhankelijk controleren:

Voor 20 kHz PWM (72 MHz klok):Timer_clock = 72 MHzAls we prescaler = 72-1 willen → tellerklok = 1 MZARR = (1 MHz / 20 kHz) - 1 = 50 - 1 = 49Verificatie: 1e6 / (49+1) = 20.000 Hz ✓

AI-code controleren: waar moet u op letten?

Het feit dat de gegenereerde code wordt gecompileerd, betekent niet dat deze correct werkt. Volg deze controlelijst:

controle gebied

Waar u op moet letten

Register/bit-instellingen

Precies compatibel met datasheet, correct bitmasker

Onderbreken (ISR)

Is het kort? Geen blockervertraging? Wordt vluchtig gebruikt?

buffer/array

Is er grenscontrole? Risico op overstroming?

timing

Met vertraging of timer? Wordt aan de werkelijke tijdslimiet voldaan?

Soort en breedte

8/16/32-bit overflow, verwarring met ondertekend/niet-ondertekend

macht/waakhond

Waakhond met oneindige lusvoeding?

Interrupt service routines (ISR) zijn de meest voorkomende bron van fouten. AI plaatst soms delay() of long loop in de ISR. Dit leidt ertoe dat andere interrupts worden gemist en dat de watchdog wordt gereset. Regel: ISR moet zo kort mogelijk zijn; De belangrijkste taak zou moeten zijn om een ​​vlag op te zetten en deze naar de hoofdlus te verplaatsen.

// ZWAK (AI produceert dit soms): Blocker-functie in ISR void TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; lees_sensor(); // kan lang duren - BAD CASE_Delay(10); // vertraging in ISR - ZEER SLECHT }}// STERK: ISR kort; taak wordt verplaatst naar hoofdlusvluchtig uint8_t tick_flag = 0; // vluchtige CONDITIONvoid TIM3_IRQHandler(void) { if (TIM3->SR & TIM_SR_UIF) { TIM3->SR &= ~TIM_SR_UIF; tick_flag = 1; // stel gewoon de vlag in }}// in de hoofdlus: if (tick_flag) { tick_flag = 0; lees_sensor(); }

Let op: elke variabele die wordt gedeeld tussen de interrupt en de hoofdlus moet vluchtig zijn. Anders kan de compiler de variabele in het register opslaan en de update missen. AI vergeet dit trefwoord vaak; Zoek er specifiek naar bij het lezen van de code.

Bufferoverloop en typefouten

AI kan gegevens van de seriële poort kopiëren naar een array met een vaste grootte, zonder dat er grenzen worden gecontroleerd. In een ingebed systeem betekent dit het verpletteren van aaneengesloten geheugen en onverklaarbare crashes. Zorg ervoor dat de limiet wordt gecontroleerd bij elke strcpy, array-index en DMA-buffer. Op dezelfde manier wordt een 8-bits teller na 255 gereset; AI kan dit negeren en vertrouwen op een overlopend account.

Verificatie in hardware: "Werken" wordt gemeten, niet aangenomen

In een ingebed systeem is het meest betrouwbare bewijs de meter, niet de compiler. Controleer de gegenereerde code op deze drie manieren:

  1. Oscilloscoop/logische analysator: meet de PWM-frequentie, signaaltiming en communicatiegolfvorm. Als je 20 kHz wilde, zie dan 20 kHz op het scherm.
  2. Logboek voor seriële poort (UART): druk variabele waarden, statusovergangen en fouttellers af en vergelijk deze met het verwachte gedrag.
  3. Bound- en stresstests: Test of het systeem bestand is tegen de hoogste belasting, de snelste gegevens en de slechtste timing.

Als de gemeten waarde niet overeenkomt met de berekening, is de klokaanname, prescalerwaarde of registerinstelling onjuist; achtervolging.

Mini-hoesje

Een team studenten laat de AI een afstandsmeetcode printen met een HC-SR04 ultrasone sensor. De code compileert, maar de afstand geeft altijd belachelijke waarden. Wanneer ze hem op de oscilloscoop aansluiten, zien ze dat het echobeen de timing berekent in milliseconden in plaats van in microseconden; AI gebruikte millis() in plaats van micros(). Deze fout van één woord verstoorde de hele meting met een factor 1000. Wanneer ze de onbewerkte echotijd in het seriële logboek afdrukken en deze vergelijken met een echte liniaal, vinden ze de fout en repareren deze. Les: gecompileerde code is geen correcte code; Meting in hardware brengt de fout onmiddellijk aan het licht.

Veelvoorkomende fouten

  • Registernamen en bitmaskers accepteren zonder ze te vergelijken met de datasheet.
  • Blokkeringsvertraging of lange verwerking binnen de ISR toestaan.
  • Vergeten vluchtige op gedeelde variabelen.
  • Controle van buffer- en arraygrenzen omzeilen; de overloop niet zien.
  • Vertrouwen op aannames over klokfrequentie en timing zonder deze te verifiëren.
  • Gezien de code "werkt" zonder deze te meten met een oscilloscoop/seriële log.

Samengevat

  • Definieer de ingebedde taak duidelijk in termen van hardware, functie, beperkingen en interface.
  • Laat de AI timingwaarden zoals prescaler/ARR berekenen en deze onafhankelijk verifiëren.
  • Houd ISR's kort, gebruik vluchtige variabelen voor gedeelde variabelen.
  • Zoek specifiek naar fouten in het register, de bufferlimiet en de typebreedte.
  • "Het werkt" wordt bewezen met een oscilloscoop, logische analysator en serieel logbestand, niet met de compiler.
  • Als de gemeten waarde niet overeenkomt met de berekening, ga dan op zoek naar de aannames.

Applicatie taak

Met een microcontroller die je hebt (Arduino, STM32, ESP32), vraag je de AI om PWM of een periodieke taak op een bepaalde frequentie. Voordat u de code laadt: (1) verifieer de frequentie-/timingwaarden onafhankelijk van het account in de commentaarregel, (2) controleer op vluchtige en blokkerende waarden in de ISR en gedeelde variabelen. Meet na het uploaden de werkelijke frequentie met een oscilloscoop of logische analysator en vergelijk deze met het doel. Als er een afwijking is, zoek dan de bron en corrigeer deze, en noteer wat er verkeerd werd verondersteld.