Единица 3 / 9

Вградени системи и генерирање кодови на микроконтролер

Добивки:

  • Способност да се генерира вграден код даден регистар и хардверски контекст за Arduino/STM32/ESP32 со AI
  • Способност за препознавање и корекција на вградени обрасци како што се прекини, тајмери и неблокирачки циклуси во излезот со вештачка интелигенција
  • Можност за прегледување на генерираниот код во однос на меморијата, реално време и безбедноста пред да се постави на хардверот

Во мехатрониката, микроконтролерот е местото каде што идеите се среќаваат со физичкиот свет. Картички како Arduino, STM32, ESP32; чита сензори, погонува актуатори, комуницира и сето тоа го прави под ограничена меморија, ограничена процесорска моќ и строги барања за тајминг. Вештачката интелигенција е многу корисна во ова поле: може да ги извлече поставките за регистар врз основа на листот со податоци на сензорот, да кодира протокол за комуникација, да постави прекин на тајмерот. Но, вградените системи се една од областите каде што вештачката интелигенција произведува „најубедливи невистини“; бидејќи регистерските адреси, бит-маските и однесувањето на времето се специфични за таблата и една битна грешка го нарушува целото однесување. Во оваа единица, покриваме како да имате вграден код генериран со вештачка интелигенција и како да го прегледате пред да го вчитате во хардвер.

Разликата на вградениот код од чист софтвер

Десктоп програма има многу меморија, оперативен систем и лесно дебагирање. На вградениот код му недостасуваат повеќето од овие:

Големина

десктоп

вграден систем

меморија

Ниво на GB

Ниво на KB (на пр. 2 KB RAM)

тајмингот

Генерално флексибилни

Тесно, во реално време

дебагирање

Лесно (дебагер, дневник)

Хард (JTAG, сериски, LED)

Резултат на грешка

Програмата паѓа

Активаторот/хардверот може да се оштети

пристап до ресурси

Апстракти на ОС

Директен пристап до Регистарот

Овие разлики ги одредуваат вашите критериуми за оценување на излезот на вештачката интелигенција: користењето на меморијата, во реално време (не блокирање) и точноста на хардверскиот регистар се секогаш на врвот на вашата листа за проверка.

Блокатор наспроти неблокирачки код

Најчеста грешка што ја прават почетниците (и често ја прават вештачката интелигенција) е употребата на delay(). Delay (1000) го заклучува процесорот за 1 секунда; Во овој период, не може да се читаат други сензори, ниту копчиња не може да се контролираат. Ова е неприфатливо во мехатрониката. Наместо тоа, се користи неблокирачка шема базирана на millis().

// BAD: блокатор -- процесорот не може да врши друга работа за 1 секунда void loop() { digitalWrite(LED, HIGH); доцнење (1000); // сè престанува digitalWrite(LED, LOW); доцнење (1000); // Копчето за итни случаи не може да се прочита во моментов!}// ДОБРО: не-блокирање -- јамката не е блокирана, другите задачи се извршуваат ако (nowMs - previousMs >= интервал) { previousMs = nowMs; ledStatus = !ledStatus; digitalWrite (LED, ledStatus); } buttonCheck(); // може да работи во секој циклус sensorRead(); //може да работи во која било јамка}

Моделот што не е блокиран е основата на вградената мехатроника: контролната јамка тече континуирано, ниту една задача не заклучува друга. Кажувањето на вештачката интелигенција да „не користете одложување, пишувајте не-блокирање базирано на милис“ кога пишувате код директно го подобрува квалитетот на излезот.

Совет: Барајте доцнење( во вградениот код од вештачката интелигенција. Ако видите доцнење во главната контролна јамка, најчесто тој код не е погоден за систем во реално време и треба да се препише.

Прекини и тајмери

Снимаме настани кои се критични за времето (пулс на енкодер, копче, периодично земање примероци) со прекини наместо да чекаме во главната јамка. Рутината за прекини (ISR) треба да биде напишана кратко и внимателно: без одложувања, Serial.print или долги пресметки во неа; Споделените променливи се означени како испарливи.

испарлив долг енкодер Бројач = 0; ( else encoderCounter--;}void setup() { pinMode(ENC_A, INPUT_PULLUP); pinMode (ENC_B, INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(ENC_A), enkoderISR, RISING);}void loop() { long counter; noInterrupts(); //кратки прекини за бројач за атомско читање = енкодерБрој; прекинува(); //трансактирај безбедно со бројачот...}

Три критични точки во овој пример се оние каде што вештачката интелигенција често промашува: (1) споделениот бројач на кодерот мора да биде „испарлив“ или оптимизацијата на компајлерот ќе ги пропушти ажурирањата; (2) ISR треба да биде краток; (3) При читање на променлива од повеќе бајти во главната јамка, прекините за атомско отчитување мора да се затворат кратко време, во спротивно ISR може да интервенира при читањето и може да се прочита половина/коруптивна вредност (состојба на трка). Задолжително проверете дали овие три се присутни во кодот на AI.

Регистрирај се точност и лист со податоци

AI може веродостојно погрешно да ја претстави адресата на регистарот на сензорот или битот за конфигурација на MCU. На пример, регистарот за управување со енергија на MPU6050 IMU е 0x6B; Ако вештачката интелигенција го даде ова како 0x6A, кодот се компајлира, се чини дека работи, но сензорот не се буди. Ваквите грешки се откриваат само кога се споредуваат со листот со податоци.

// будење MPU6050: според листот со податоци PWR_MGMT_1 = 0x6B, вредност 0x00#define MPU_ADDR 0x68#define PWR_MGMT_1 0x6B // <-- VERIFY from datasheetWire.beginTransmission(MPU_ADDR);Wire.write(PWR_MGMT_1);Wire.write(0x00); // будење од режим на мирувањеWire.endTransmission(true);

Внимание: Потврдете ја секоја адреса на регистарот, бит-маска и I2C/SPI адреса дадени од AI од листот со податоци. Овие вредности се специфични за картичката и чипот; Вредноста што вештачката интелигенција ја „памти“ може да е од друга ревизија на чипот. Неточниот регистар тивко води до неправилно однесување.

Слаба навестување / Силен навестување

СЛАБ: „Читајте сензор за температура на ESP32.“ (Кој сензор? Кој протокол? Кој пин? Генеричка, веројатно погрешна шифра.)СИЛОТ: „Прочитајте температурен сензор DS18B20 на ESP32 (рамка Arduino) од GPIO4 со OneWire. Напишете не-блокирачки, земете примерок на секоја 1 секунда (со користење на доцнење на големината на случаите, на милис-читање на големината на големината на случаите, millis- ex). -127 или 85).

Моќен потсетник; Го дава чипот, рамката, сензорот, протоколот, пинот, шемата за земање примероци, статусот на грешка и ограничувањето на меморијата. На овој начин излезот е и проверлив и реален.

Прегледајте го списокот за проверка за вграден код

Пред да го вчитате излезот со вештачка интелигенција, поминете го низ оваа листа:

  1. Блокирање: Дали има доцнење или долго блокирање во главната јамка?
  2. испарливи: Дали променливите споделени со ISR се испарливи?
  3. Атомски пристап: Дали споделената променлива со повеќе бајти е безбедна за читање?
  4. Регистрирај се: Дали адресите и бит-маските се компатибилни со листот со податоци?
  5. Меморија: Низа, големи низи, дали рекурзијата создава прелевање на ниво на KB?
  6. Ракување со грешки: Дали се постапуваат со грешки при читање на сензорот, истекувања на комуникацијата?
  7. Безбеден старт: Дали излезите на активаторот се ставени во безбедна (пасивна) состојба при стартување?

Мини случај

Инженерот за вградени системи Баран има вештачка интелигенција да го напише кодот што го чита IMU за беспилотно летало. Кодот се компајлира и се чини дека работи, но вредностите на аголот се бесмислени. Баран го применува списокот за проверка: ги споредува адресите на регистерот со листот со податоци и открива дека AI неправилно го издава регистарот за конфигурација на жироскопот (0x1A наместо 0x1B), така што скалата на чувствителност е погрешна. Откако ќе се коригира, вредностите се смируваат. Потоа delay(10) забележува во главната јамка; конвертирање на ова во структура заснована на милис, бидејќи блокирањето на јамката за контрола на летот е неприфатливо. Конечно, гледа дека променливата за споделени бројач не е испарлива и ја додава. АИ брзо го даде скелетот; Но, листата на прегледи фати три посебни грешки: регистрирање, блокирање и испарливи, а хардверот воопшто не беше загрозен.

Вообичаени грешки

  • Убивање на одговорот во реално време со користење на delay() во главната контролна јамка.
  • Избегнувајте да ја направите променливата споделена со ISR нестабилна и да доживеете тивко оштетување на податоците.
  • Читање неатомски споделена променлива со повеќе бајти и генерирање на состојба на трка.
  • Не потврдување на регистарот/битните маски дадени од ВИ со листот со податоци.
  • Создавање прелевање на меморијата со користење на жици и големи низи во ограничена RAM меморија.
  • Заборавајќи првично да ги обезбеди излезите на активаторот.

Сумирано

  • Вграден код; Работи со ограничена меморија, тесно време и директен пристап до регистарот.
  • Во главната јамка, наместо одложување, се користи неблокирачка шема базирана на милис.
  • ISR се одржува кратко; споделените променливи мора да бидат испарливи и атомски да се пристапи.
  • Регистарските адреси и бит-маските секогаш се проверуваат во однос на листот со податоци; Вештачката интелигенција може да биде погрешна.
  • Меморијата, справувањето со грешки и статусот на безбедно стартување секогаш се проверуваат.
  • Моќен потсетник; Вклучува чип, рамка, сензор, протокол, пин и ограничувања.

Задача за апликација

Изберете сензор (на пр. DS18B20, MPU6050 или HC-SR04) и микроконтролер (Arduino/ESP32/STM32). Нека вештачката интелигенција генерира код за читање што не е блокиран со моќниот шаблон за праќање во оваа единица. Потоа следете ги седумте ставки од списокот за проверка на прегледот еден по еден: споредете барем една вредност на регистарот/пинот со листот со податоци, проверете дали има доцнења во јамката, проверете го нестабилниот статус на споделените променливи. Колку ставки „поминаа“ при првиот обид и колку бараа корекција? Забележете го секој проблем што ќе го најдете и неговиот поправен.