Μονάδα 3 / 9

Ενσωματωμένα συστήματα και δημιουργία κώδικα μικροελεγκτή

Κέρδη:

  • Δυνατότητα δημιουργίας ενσωματωμένου κώδικα δεδομένου μητρώου και περιβάλλοντος υλικού για Arduino/STM32/ESP32 με AI
  • Δυνατότητα αναγνώρισης και διόρθωσης ενσωματωμένων μοτίβων όπως διακοπές, χρονόμετρα και βρόχοι μη αποκλεισμού στην έξοδο AI
  • Δυνατότητα ανασκόπησης του παραγόμενου κώδικα όσον αφορά τη μνήμη, τον πραγματικό χρόνο και την ασφάλεια πριν τον ανεβάσετε στο υλικό

Στη μηχατρονική, ο μικροελεγκτής είναι όπου οι ιδέες συναντούν τον φυσικό κόσμο. Κάρτες όπως Arduino, STM32, ESP32. Διαβάζει αισθητήρες, οδηγεί ενεργοποιητές, επικοινωνεί και τα κάνει όλα αυτά με περιορισμένη μνήμη, περιορισμένη ισχύ επεξεργασίας και αυστηρές απαιτήσεις χρονισμού. Η τεχνητή νοημοσύνη είναι πολύ χρήσιμη σε αυτόν τον τομέα: μπορεί να εξαγάγει ρυθμίσεις μητρώου με βάση το φύλλο δεδομένων ενός αισθητήρα, να κωδικοποιεί ένα πρωτόκολλο επικοινωνίας, να ορίζει μια διακοπή του χρονοδιακόπτη. Αλλά τα ενσωματωμένα συστήματα είναι ένας από τους τομείς όπου η τεχνητή νοημοσύνη παράγει τα πιο «πειστικά ψεύδη». επειδή οι διευθύνσεις μητρώου, οι μάσκες bit και η συμπεριφορά χρονισμού είναι συγκεκριμένα για τον πίνακα και ένα σφάλμα bit διαταράσσει ολόκληρη τη συμπεριφορά. Σε αυτήν την ενότητα, καλύπτουμε πώς να έχετε ενσωματωμένο κώδικα που δημιουργείται με AI και πώς να τον ελέγξετε πριν τον φορτώσετε στο υλικό.

Διαφορά του ενσωματωμένου κώδικα από το καθαρό λογισμικό

Ένα πρόγραμμα επιτραπέζιου υπολογιστή διαθέτει άφθονη μνήμη, λειτουργικό σύστημα και ευκολία εντοπισμού σφαλμάτων. Ο ενσωματωμένος κώδικας δεν διαθέτει τα περισσότερα από αυτά:

Μέγεθος

επιφάνεια εργασίας

ενσωματωμένο σύστημα

μνήμη

επίπεδο GB

Επίπεδο KB (π.χ. 2 KB μνήμης RAM)

χρονοδιάγραμμα

Γενικά ευέλικτο

Σφιχτό, σε πραγματικό χρόνο

αποσφαλμάτωση

Εύκολο (debugger, log)

Σκληρό (JTAG, σειριακό, LED)

Αποτέλεσμα σφάλματος

Το πρόγραμμα κολλάει

Ο ενεργοποιητής/το υλικό μπορεί να έχει καταστραφεί

πρόσβαση σε πόρους

Περιλήψεις OS

Άμεση πρόσβαση στο Μητρώο

Αυτές οι διαφορές καθορίζουν τα κριτήριά σας για την αξιολόγηση της εξόδου τεχνητής νοημοσύνης: η χρήση μνήμης, η ακρίβεια σε πραγματικό χρόνο (χωρίς αποκλεισμό) και η ακρίβεια του μητρώου υλικού βρίσκονται πάντα στην κορυφή της λίστας ελέγχου σας.

Κωδικός αποκλεισμού έναντι μη αποκλειστικού κώδικα

Το πιο συνηθισμένο λάθος που γίνεται από αρχάριους (και συχνά από AI) είναι η χρήση της καθυστέρησης (). Η καθυστέρηση (1000) κλειδώνει τον επεξεργαστή για 1 δευτερόλεπτο. Κατά τη διάρκεια αυτής της περιόδου, κανένας άλλος αισθητήρας δεν μπορεί να διαβαστεί, κανένα κουμπί δεν μπορεί να ελεγχθεί. Αυτό είναι απαράδεκτο στη Μηχατρονική. Αντίθετα, χρησιμοποιείται ένα μοτίβο μη αποκλεισμού που βασίζεται σε millis().

// BAD: blocker -- ο επεξεργαστής δεν μπορεί να κάνει άλλη δουλειά για 1 δευτερόλεπτο void loop() { digitalWrite(LED, HIGH); καθυστέρηση (1000); // όλα σταματούν digitalWrite(LED, LOW); καθυστέρηση (1000); // Δεν είναι δυνατή η ανάγνωση ενός κουμπιού έκτακτης ανάγκης αυτήν τη στιγμή!}// ΚΑΛΟ: μη αποκλεισμός -- ο βρόχος δεν είναι αποκλεισμένος, άλλες εργασίες εκτελούνται εάν (nowMs - previousMs >= interval) { previousMs = nowMs; ledStatus = !ledStatus; digitalWrite(LED, ledStatus); } buttonCheck(); // μπορεί να εκτελεστεί σε κάθε κύκλο sensorRead(); //μπορεί να εκτελεστεί σε οποιοδήποτε βρόχο}

Το μοτίβο μη αποκλεισμού είναι η βάση της ενσωματωμένης μηχατρονικής: ο βρόχος ελέγχου ρέει συνεχώς, καμία εργασία δεν κλειδώνει άλλη. Λέγοντας στην τεχνητή νοημοσύνη να "μην χρησιμοποιείτε καθυστέρηση, γράψτε μη αποκλεισμό βάσει χιλιοστών" κατά τη σύνταξη κώδικα βελτιώνει άμεσα την ποιότητα της εξόδου.

Συμβουλή: Αναζητήστε καθυστέρηση (στον ενσωματωμένο κώδικα από το AI. Εάν δείτε καθυστέρηση στον κύριο βρόχο ελέγχου, τις περισσότερες φορές αυτός ο κωδικός δεν είναι κατάλληλος για ένα σύστημα σε πραγματικό χρόνο και θα πρέπει να ξαναγραφτεί.

Διακοπές και χρονοδιακόπτες

Καταγράφουμε γεγονότα κρίσιμα για το χρόνο (παλμός κωδικοποιητή, κουμπί, περιοδική δειγματοληψία) με διακοπές αντί να περιμένουμε στον κύριο βρόχο. Η ρουτίνα διακοπής (ISR) πρέπει να γράφεται σύντομη και προσεκτικά: χωρίς καθυστερήσεις, Serial.print ή μεγάλους υπολογισμούς σε αυτήν. Οι κοινόχρηστες μεταβλητές επισημαίνονται ως πτητικές.

volatile long encoderCounter = 0; // ISR και βρόχος είναι κοινόχρηστα -> volatile condition void enkoderISR() { // Short ISR: απλά μετρήστε, μην κάνετε άλλη εργασία εάν (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; noInterrupts(); //μικρές διακοπές για μετρητή ατομικής ανάγνωσης = encoderCounter; interrupts(); //συναλλαγές με ασφάλεια με τον μετρητή...}

Τρία κρίσιμα σημεία σε αυτό το παράδειγμα είναι τα σημεία όπου η τεχνητή νοημοσύνη συχνά χάνει: (1) ο κοινός μετρητής κωδικοποιητή πρέπει να είναι «πτητικός» διαφορετικά η βελτιστοποίηση του μεταγλωττιστή θα χάσει ενημερώσεις. (2) το ISR πρέπει να είναι σύντομο. (3) Κατά την ανάγνωση μιας μεταβλητής πολλών byte στον κύριο βρόχο, οι διακοπές για ατομική ανάγνωση πρέπει να κλείνουν για μικρό χρονικό διάστημα, διαφορετικά το ISR μπορεί να παρέμβει κατά την ανάγνωση και η μισή/κατεστραμμένη τιμή μπορεί να διαβαστεί (συνθήκη αγώνα). Βεβαιωθείτε ότι έχετε ελέγξει εάν αυτά τα τρία υπάρχουν στον κώδικα AI.

Ακρίβεια εγγραφής και φύλλο δεδομένων

Το AI μπορεί να παραποιήσει αξιόπιστα τη διεύθυνση μητρώου ενός αισθητήρα ή το bit διαμόρφωσης ενός MCU. Για παράδειγμα, ο καταχωρητής διαχείρισης ενέργειας ενός MPU6050 IMU είναι 0x6B. Εάν το AI δίνει αυτό ως 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); // wake up from sleep modeWire.endTransmission(true);

Προσοχή: Επαληθεύστε κάθε διεύθυνση μητρώου, μάσκα bit και διεύθυνση I2C/SPI που δίνεται από το AI από το φύλλο δεδομένων. Αυτές οι τιμές είναι συγκεκριμένες για κάρτες και τσιπ. Η τιμή που «θυμάται» η τεχνητή νοημοσύνη μπορεί να προέρχεται από άλλη αναθεώρηση τσιπ. Η λανθασμένη εγγραφή οδηγεί σιωπηλά σε εσφαλμένη συμπεριφορά.

Αδύναμη προτροπή / Ισχυρή προτροπή

ΑΔΥΝΑΤΟ:"Ανάγνωση αισθητήρα θερμοκρασίας στο ESP32."(Ποιος αισθητήρας; Ποιο πρωτόκολλο; Ποιο pin; Γενικός, πιθανότατα λάθος κωδικός.) ΔΥΝΑΤΟΤΗΤΑ:"Διαβάστε έναν αισθητήρα θερμοκρασίας DS18B20 στο ESP32 (πλαίσιο Arduino) από το GPIO4 με OneWire. Γράψτε χωρίς αποκλεισμό, δειγματίστε κάθε 1 δευτερόλεπτο (χρησιμοποιώντας την τιμή καθυστέρησης ανάγνωσης κεφαλαίων, millis-base). -127 ή 85. Προσδιορίστε κάθε σύνδεση βιβλιοθήκης και pin που χρησιμοποιείτε στο πρώτο σχόλιο.

Ισχυρή προτροπή. Δίνει το τσιπ, το πλαίσιο, τον αισθητήρα, το πρωτόκολλο, την καρφίτσα, το μοτίβο δειγματοληψίας, την κατάσταση σφάλματος και τον περιορισμό μνήμης. Με αυτόν τον τρόπο η έξοδος είναι επαληθεύσιμη και ρεαλιστική.

Ελέγξτε τη λίστα ελέγχου για τον ενσωματωμένο κώδικα

Πριν φορτώσετε την έξοδο AI, περάστε την από αυτήν τη λίστα:

  1. Αποκλεισμός: Υπάρχει καθυστέρηση ή μεγάλος αποκλεισμός στον κύριο βρόχο;
  2. volatile: Είναι ασταθείς οι μεταβλητές που μοιράζονται με το ISR;
  3. Ατομική πρόσβαση: Είναι ασφαλής η ανάγνωση της κοινής μεταβλητής πολλών byte;
  4. Εγγραφή: Είναι οι διευθύνσεις και οι μάσκες bit συμβατές με το φύλλο δεδομένων;
  5. Μνήμη: Συμβολοσειρά, μεγάλοι πίνακες, η αναδρομή δημιουργεί υπερχείλιση επιπέδου KB;
  6. Αντιμετώπιση σφαλμάτων: Αντιμετωπίζονται σφάλματα ανάγνωσης αισθητήρα, χρονικά όρια επικοινωνίας;
  7. Ασφαλής εκκίνηση: Οι έξοδοι του ενεργοποιητή τοποθετούνται σε ασφαλή (παθητική) κατάσταση κατά την εκκίνηση;

Μίνι θήκη

Ο μηχανικός ενσωματωμένων συστημάτων Baran έχει το AI να γράψει τον κώδικα που διαβάζει το IMU για ένα drone. Ο κώδικας μεταγλωττίζεται και φαίνεται να λειτουργεί, αλλά οι τιμές γωνίας δεν έχουν νόημα. Ο Baran εφαρμόζει τη λίστα ελέγχου: συγκρίνει τις διευθύνσεις του μητρώου με το φύλλο δεδομένων και διαπιστώνει ότι το AI εξάγει εσφαλμένα τον καταχωρητή διαμόρφωσης γυροσκοπίου (0x1A αντί για 0x1B), επομένως η κλίμακα ευαισθησίας είναι λάθος. Μόλις διορθωθούν, οι τιμές ρυθμίζονται. Στη συνέχεια, το delay(10) σημειώνει στον κύριο βρόχο. μετατροπή αυτού σε δομή που βασίζεται σε millis, επειδή το μπλοκάρισμα του βρόχου ελέγχου πτήσης είναι απαράδεκτο. Τέλος, βλέπει ότι η μεταβλητή κοινόχρηστου μετρητή δεν είναι ασταθής και την προσθέτει. Το AI έδωσε γρήγορα τον σκελετό. Αλλά η λίστα αναθεώρησης εντόπισε τρία ξεχωριστά σφάλματα: εγγραφή, αποκλεισμό και πτητικό, και το υλικό δεν κινδύνευε καθόλου.

Κοινά λάθη

  • Εξοντώστε την απόκριση σε πραγματικό χρόνο χρησιμοποιώντας την καθυστέρηση() στον κύριο βρόχο ελέγχου.
  • Αποφύγετε να κάνετε τη μεταβλητή που είναι κοινή με ISR ασταθή και να αντιμετωπίζετε σιωπηρή καταστροφή δεδομένων.
  • Ανάγνωση μιας κοινής μεταβλητής πολλών byte χωρίς ατομική χρήση και δημιουργία συνθήκης φυλής.
  • Μη επαλήθευση των μάσκες καταχωρητή/bit που δίνονται από το AI με το φύλλο δεδομένων.
  • Δημιουργία υπερχείλισης μνήμης χρησιμοποιώντας συμβολοσειρές και μεγάλους πίνακες σε περιορισμένη μνήμη RAM.
  • Ξεχνώντας να ασφαλίσετε αρχικά τις εξόδους ενεργοποιητή.

Συνοπτικά

  • Ενσωματωμένος κώδικας. Λειτουργεί με περιορισμένη μνήμη, περιορισμένο χρονισμό και άμεση πρόσβαση στο μητρώο.
  • Στον κύριο βρόχο, χρησιμοποιείται ένα μοτίβο μη αποκλεισμού που βασίζεται σε millis αντί για καθυστέρηση.
  • Το ISR διατηρείται σύντομο. Οι κοινόχρηστες μεταβλητές πρέπει να είναι ασταθείς και να έχουν ατομική πρόσβαση.
  • Οι διευθύνσεις μητρώου και οι μάσκες bit επαληθεύονται πάντα με βάση το φύλλο δεδομένων. Το AI μπορεί να είναι λάθος.
  • Η μνήμη, ο χειρισμός σφαλμάτων και η κατάσταση ασφαλούς εκκίνησης ελέγχονται πάντα.
  • Ισχυρή προτροπή. Περιλαμβάνει το τσιπ, το πλαίσιο, τον αισθητήρα, το πρωτόκολλο, την ακίδα και τους περιορισμούς.

Εργασία εφαρμογής

Επιλέξτε έναν αισθητήρα (π.χ. DS18B20, MPU6050 ή HC-SR04) και έναν μικροελεγκτή (Arduino/ESP32/STM32). Ζητήστε από το AI να δημιουργήσει έναν κώδικα ανάγνωσης χωρίς αποκλεισμό με το ισχυρό πρότυπο προτροπής σε αυτήν τη μονάδα. Στη συνέχεια, ακολουθήστε τα επτά στοιχεία της λίστας ελέγχου αναθεώρησης ένα προς ένα: συγκρίνετε τουλάχιστον μία τιμή καταχωρητή/καρφίτσας με το φύλλο δεδομένων, ελέγξτε για καθυστερήσεις βρόχου, ελέγξτε την κατάσταση ασταθούς των κοινόχρηστων μεταβλητών. Πόσα στοιχεία «πέρασαν» με την πρώτη προσπάθεια και πόσα χρειάστηκαν διόρθωση; Σημειώστε κάθε πρόβλημα που βρίσκετε και την επίλυσή του.