- Πώς λειτουργεί το RTOS;
- Συχνά χρησιμοποιούμενοι όροι στο RTOS
- Εγκατάσταση της βιβλιοθήκης Arduino FreeRTOS
- Διάγραμμα κυκλώματος
- Arduino FreeRTOS Παράδειγμα- Δημιουργία εργασιών FreeRTOS στο Arduino IDE
- Εφαρμογή FreeRTOS Task στο Arduino IDE
Το λειτουργικό σύστημα που υπάρχει μέσα στις ενσωματωμένες συσκευές ονομάζεται RTOS (Real-Time Operating System). Στις ενσωματωμένες συσκευές, οι εργασίες σε πραγματικό χρόνο είναι κρίσιμες όταν ο συγχρονισμός παίζει πολύ σημαντικό ρόλο. Οι εργασίες σε πραγματικό χρόνο είναι Time Deterministic σημαίνει ότι ο χρόνος απόκρισης σε οποιοδήποτε συμβάν είναι πάντα σταθερός, έτσι ώστε να μπορεί να διασφαλιστεί ότι οποιοδήποτε συγκεκριμένο συμβάν θα συμβεί σε καθορισμένο χρόνο. Το RTOS έχει σχεδιαστεί για να εκτελεί εφαρμογές με πολύ ακριβή χρονισμό και υψηλό βαθμό αξιοπιστίας. Το RTOS βοηθά επίσης στην εκτέλεση πολλαπλών εργασιών με έναν μόνο πυρήνα.
Έχουμε ήδη καλύψει ένα σεμινάριο για το πώς να χρησιμοποιήσετε το RTOS σε ενσωματωμένα συστήματα όπου μπορείτε να μάθετε περισσότερα για το RTOS, τη διαφορά μεταξύ λειτουργικού συστήματος γενικής χρήσης και RTOS, διαφορετικών τύπων RTOS κ.λπ.
Σε αυτό το σεμινάριο, θα ξεκινήσουμε με το FreeRTOS. Το FreeRTOS είναι μια κατηγορία RTOS για ενσωματωμένες συσκευές, η οποία είναι αρκετά μικρή ώστε να λειτουργεί σε μικροελεγκτές 8/16-bit, αν και η χρήση του δεν περιορίζεται σε αυτούς τους μικροελεγκτές. Είναι εντελώς ανοιχτού κώδικα και ο κώδικας είναι διαθέσιμος στο github. Αν γνωρίζουμε κάποιες βασικές έννοιες του RTOS, τότε είναι πολύ εύκολο να χρησιμοποιήσετε το FreeRTOS, επειδή διαθέτει καλά τεκμηριωμένα API τα οποία μπορούν να χρησιμοποιηθούν απευθείας στον κώδικα χωρίς να γνωρίζουμε το backend μέρος της κωδικοποίησης. Μπορείτε να βρείτε την πλήρη τεκμηρίωση του FreeRTOS εδώ.
Καθώς το FreeRTOS μπορεί να εκτελεστεί σε MCU 8-bit, έτσι μπορεί να εκτελεστεί και στον πίνακα Arduino Uno. Πρέπει απλώς να κατεβάσετε τη βιβλιοθήκη FreeRTOS και μετά να αρχίσουμε να εφαρμόζουμε τον κώδικα χρησιμοποιώντας API. Αυτό το σεμινάριο προορίζεται για έναν πλήρη αρχάριο, παρακάτω είναι τα θέματα που θα καλύψουμε σε αυτό το σεμινάριο Arduino FreeRTOS:
- Πώς λειτουργεί το RTOS
- Μερικοί όροι που χρησιμοποιούνται συχνά στο RTOS
- Εγκατάσταση FreeRTOS στο Arduino IDE
- Τρόπος δημιουργίας εργασιών FreeRTOS με παράδειγμα
Πώς λειτουργεί το RTOS;
Πριν ξεκινήσετε με το RTOS να λειτουργεί, ας δούμε τι είναι μια εργασία. Το Task είναι ένα κομμάτι κώδικα που μπορεί να προγραμματιστεί στην CPU για εκτέλεση. Επομένως, εάν θέλετε να εκτελέσετε κάποια εργασία, τότε θα πρέπει να προγραμματιστεί χρησιμοποιώντας καθυστέρηση πυρήνα ή χρήση διακοπών. Αυτή η εργασία γίνεται από τον Προγραμματιστή που υπάρχει στον πυρήνα. Σε έναν επεξεργαστή ενός πυρήνα, ο προγραμματιστής βοηθάει στην εκτέλεση εργασιών σε ένα συγκεκριμένο χρονικό διάστημα αλλά φαίνεται ότι διαφορετικές εργασίες εκτελούνται ταυτόχρονα. Κάθε εργασία εκτελείται σύμφωνα με την προτεραιότητα που της δίνεται.
Τώρα, ας δούμε τι συμβαίνει στον πυρήνα RTOS εάν θέλουμε να δημιουργήσουμε μια εργασία για το LED να αναβοσβήνει με ένα διάστημα ενός δευτερολέπτου και να θέσουμε αυτήν την εργασία στην υψηλότερη προτεραιότητα.
Εκτός από την εργασία LED, θα υπάρξει μια ακόμη εργασία που δημιουργείται από τον πυρήνα, είναι γνωστή ως αδράνεια. Η αδράνεια δημιουργείται όταν δεν υπάρχει διαθέσιμη εργασία για εκτέλεση. Αυτή η εργασία εκτελείται πάντα με τη χαμηλότερη προτεραιότητα, δηλαδή 0 προτεραιότητα. Αν αναλύσουμε το γράφημα χρονισμού που δίνεται παραπάνω, μπορεί να φανεί ότι η εκτέλεση ξεκινά με μια εργασία LED και εκτελείται για ένα καθορισμένο χρόνο και στη συνέχεια για τον υπόλοιπο χρόνο, η αδράνεια εκτελείται έως ότου συμβεί διακοπή του κρότου. Στη συνέχεια, ο πυρήνας αποφασίζει ποια εργασία πρέπει να εκτελεστεί σύμφωνα με την προτεραιότητα της εργασίας και τον συνολικό χρόνο που έχει παρέλθει από την εργασία LED. Όταν ολοκληρωθεί 1 δευτερόλεπτο, ο πυρήνας επιλέγει ξανά την οδηγημένη εργασία για να εκτελεστεί επειδή έχει υψηλότερη προτεραιότητα από την εργασία αδράνειας, μπορούμε επίσης να πούμε ότι η εργασία LED προδικάζει την αδράνεια. Εάν υπάρχουν περισσότερες από δύο εργασίες με την ίδια προτεραιότητα, τότε θα εκτελούνται με τρόπο round-robin για συγκεκριμένο χρονικό διάστημα.
Κάτω από το διάγραμμα κατάστασης καθώς δείχνει τη μετάβαση της εργασίας που δεν εκτελείται σε κατάσταση λειτουργίας.
Κάθε πρόσφατα δημιουργημένη εργασία πηγαίνει σε κατάσταση ετοιμότητας (μέρος της κατάστασης χωρίς εκτέλεση). Εάν η δημιουργημένη εργασία (Task1) έχει την υψηλότερη προτεραιότητα από άλλες εργασίες, τότε θα μετακινηθεί σε κατάσταση λειτουργίας. Εάν αυτή η εργασία που εκτελείται προεπιλέγεται από την άλλη εργασία, τότε θα επανέλθει ξανά στην κατάσταση ετοιμότητας. Διαφορετικά, εάν η εργασία 1 έχει αποκλειστεί χρησιμοποιώντας το API αποκλεισμού, τότε η CPU δεν θα αλληλεπιδράσει με αυτήν την εργασία μέχρι το χρονικό όριο που ορίζει ο χρήστης.
Εάν η Εργασία1 έχει τεθεί σε αναστολή σε κατάσταση λειτουργίας χρησιμοποιώντας API Αναστολής, τότε η Εργασία 1 θα μεταβεί στην κατάσταση Σε αναστολή και δεν θα είναι ξανά διαθέσιμη στον προγραμματιστή. Εάν συνεχίσετε την Εργασία 1 σε κατάσταση αναστολής, τότε θα επιστρέψει στην κατάσταση ετοιμότητας όπως μπορείτε να δείτε στο διάγραμμα μπλοκ.
Αυτή είναι η βασική ιδέα για το πώς εκτελούνται οι Εργασίες και αλλάζουν τις καταστάσεις τους. Σε αυτό το σεμινάριο, θα εφαρμόσουμε δύο εργασίες στο Arduino Uno χρησιμοποιώντας το FreeRTOS API.
Συχνά χρησιμοποιούμενοι όροι στο RTOS
1. Εργασία: Είναι ένα κομμάτι κώδικα που μπορεί να προγραμματιστεί στην CPU για εκτέλεση.
2. Χρονοδιάγραμμα: Είναι υπεύθυνο για την επιλογή μιας εργασίας από τη λίστα έτοιμων καταστάσεων στην τρέχουσα κατάσταση. Οι προγραμματιστές εφαρμόζονται συχνά, ώστε να διατηρούν όλους τους πόρους του υπολογιστή απασχολημένους (όπως στην εξισορρόπηση φορτίου).
3. Προφύλαξη: Είναι η πράξη προσωρινής διακοπής μιας ήδη εκτελεστικής εργασίας με σκοπό την κατάργησή της από την κατάσταση λειτουργίας χωρίς τη συνεργασία της.
4. Πλαίσιο Εναλλαγή: Σε προτεραιότητας με βάση προτίμησης, ο προγραμματιστής συγκρίνει την προτεραιότητα των εργασιών που εκτελούνται με προτεραιότητα έτοιμη λίστα εργασιών για κάθε systick διακοπή. Εάν υπάρχει κάποια εργασία στη λίστα της οποίας η προτεραιότητα είναι υψηλότερη από την εκτέλεση της εργασίας, τότε πραγματοποιείται εναλλαγή περιβάλλοντος. Βασικά, σε αυτή τη διαδικασία τα περιεχόμενα διαφορετικών εργασιών αποθηκεύονται στην αντίστοιχη μνήμη στοίβας.
5. Τύποι πολιτικών προγραμματισμού:
- Προληπτικός προγραμματισμός: Σε αυτόν τον τύπο προγραμματισμού, οι εργασίες εκτελούνται με ίσο χρονικό διάστημα χωρίς να λαμβάνονται υπόψη οι προτεραιότητες.
- Προτεραιότητα βάσει προτεραιότητας : Η εργασία υψηλής προτεραιότητας θα εκτελεστεί πρώτα.
- Συνεργατικός προγραμματισμός: Η αλλαγή περιεχομένου θα πραγματοποιηθεί μόνο με τη συνεργασία εργασιών που εκτελούνται. Η εργασία θα εκτελείται συνεχώς μέχρι να κληθεί η απόδοση της εργασίας.
6. Αντικείμενα πυρήνα: Για να σηματοδοτήσει την εργασία να εκτελέσει κάποια εργασία, χρησιμοποιείται η διαδικασία συγχρονισμού. Για την εκτέλεση αυτής της διαδικασίας χρησιμοποιούνται αντικείμενα πυρήνα. Ορισμένα αντικείμενα του πυρήνα είναι Εκδηλώσεις, Semaphores, Queues, Mutex, Mailboxes κ.λπ. Θα δούμε πώς να χρησιμοποιούμε αυτά τα αντικείμενα σε προσεχή μαθήματα.
Από την παραπάνω συζήτηση, έχουμε κάποιες βασικές ιδέες για την ιδέα του RTOS και τώρα μπορούμε να εφαρμόσουμε το έργο FreeRTOS στο Arduino. Ας ξεκινήσουμε λοιπόν εγκαθιστώντας βιβλιοθήκες FreeRTOS στο Arduino IDE.
Εγκατάσταση της βιβλιοθήκης Arduino FreeRTOS
1. Ανοίξτε το Arduino IDE και μεταβείτε στο Σκίτσο -> Συμπερίληψη βιβλιοθήκης -> Διαχείριση βιβλιοθηκών . Αναζητήστε το FreeRTOS και εγκαταστήστε τη βιβλιοθήκη όπως φαίνεται παρακάτω.
Μπορείτε να κατεβάσετε τη βιβλιοθήκη από το github και να προσθέσετε το αρχείο.zip στο Σκίτσο-> Συμπερίληψη βιβλιοθήκης -> Προσθήκη αρχείου .zip .
Τώρα, επανεκκινήστε το Arduino IDE. Αυτή η βιβλιοθήκη παρέχει κάποιο παράδειγμα κώδικα, που μπορεί επίσης να βρεθεί στο Αρχείο -> Παραδείγματα -> FreeRTOS όπως φαίνεται παρακάτω.
Εδώ θα γράψουμε τον κώδικα από το μηδέν για να κατανοήσουμε τη λειτουργία, αργότερα μπορείτε να ελέγξετε τους κωδικούς παραδείγματος και να τους χρησιμοποιήσετε.
Διάγραμμα κυκλώματος
Ακολουθεί το διάγραμμα κυκλώματος για τη δημιουργία εργασιών LED που αναβοσβήνει χρησιμοποιώντας το FreeRTOS στο Arduino:
Arduino FreeRTOS Παράδειγμα- Δημιουργία εργασιών FreeRTOS στο Arduino IDE
Ας δούμε μια βασική δομή για να γράψουμε ένα έργο FreeRTOS.
1. Πρώτα, συμπεριλάβετε το αρχείο κεφαλίδας Arduino FreeRTOS ως
#περιλαμβάνω
2. Δώστε το πρωτότυπο της συνάρτησης όλων των συναρτήσεων που γράφετε για εκτέλεση, η οποία είναι γραμμένη ως
void Task1 (void * pvParameters); void Task2 (void * pvParameters); .. ….
3. Τώρα, σε λειτουργία κενής ρύθμισης () , δημιουργήστε εργασίες και ξεκινήστε τον προγραμματιστή εργασιών.
Για τη δημιουργία εργασιών, το xTaskCreate () API καλείται στη λειτουργία εγκατάστασης με ορισμένες παραμέτρους / ορίσματα.
xTaskCreate (TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void * pvParameters, UBaseType_t uxPriority, TaskHandle_t * pxCreatedTask);
Υπάρχουν 6 επιχειρήματα που πρέπει να περάσουν κατά τη δημιουργία οποιασδήποτε εργασίας. Ας δούμε ποια είναι αυτά τα επιχειρήματα
- pvTaskCode: Είναι απλά ένας δείκτης της συνάρτησης που εκτελεί την εργασία (στην πραγματικότητα, μόνο το όνομα της συνάρτησης).
- pcName: Ένα περιγραφικό όνομα για την εργασία. Αυτό δεν χρησιμοποιείται από το FreeRTOS. Περιλαμβάνεται αποκλειστικά για σκοπούς εντοπισμού σφαλμάτων.
- usStackDepth: Κάθε εργασία έχει τη δική της μοναδική στοίβα που εκχωρείται από τον πυρήνα στην εργασία κατά τη δημιουργία της εργασίας. Η τιμή καθορίζει τον αριθμό των λέξεων που μπορεί να διατηρήσει η στοίβα και όχι τον αριθμό των byte. Για παράδειγμα, εάν η στοίβα έχει πλάτος 32-bit και το usStackDepth περάσει ως 100, τότε θα εκχωρηθούν 400 byte χώρου στοίβας (100 * 4 bytes) στη μνήμη RAM. Χρησιμοποιήστε αυτό με σύνεση, επειδή το Arduino Uno έχει μόνο 2Kbytes μνήμης RAM.
- pvParameters: Παράμετρος εισαγωγής εργασιών (μπορεί να είναι NULL).
- uxPriority: Προτεραιότητα της εργασίας (0 είναι η χαμηλότερη προτεραιότητα).
- pxCreatedTask: Μπορεί να χρησιμοποιηθεί για να παραδώσει μια λαβή στην εργασία που δημιουργείται. Αυτή η λαβή μπορεί στη συνέχεια να χρησιμοποιηθεί για την αναφορά της εργασίας σε κλήσεις API που, για παράδειγμα, αλλάζουν την προτεραιότητα της εργασίας ή διαγράφουν την εργασία (μπορεί να είναι NULL).
Παράδειγμα δημιουργίας εργασιών
xTaskCreate (task1, "task1", 128, NULL, 1, NULL); xTaskCreate (task2, "task2", 128, NULL, 2, NULL);
Εδώ, το Task2 έχει μεγαλύτερη προτεραιότητα και ως εκ τούτου εκτελείται πρώτα.
4. Αφού δημιουργήσετε την εργασία, ξεκινήστε τον προγραμματιστή σε κενή ρύθμιση χρησιμοποιώντας το vTaskStartScheduler (); API.
5. Η λειτουργία Void loop () θα παραμείνει κενή καθώς δεν θέλουμε να εκτελέσουμε οποιαδήποτε εργασία χειροκίνητα και απεριόριστα. Επειδή η εκτέλεση εργασιών αντιμετωπίζεται τώρα από το Scheduler.
6. Τώρα, πρέπει να εφαρμόσουμε τις λειτουργίες εργασιών και να γράψουμε τη λογική που θέλετε να εκτελέσετε μέσα σε αυτές τις λειτουργίες. Το όνομα της συνάρτησης πρέπει να είναι το ίδιο με το πρώτο όρισμα του API xTaskCreate () .
void task1 (void * pvParameters) { ενώ (1) { .. ..// τη λογική σας } }
7. Το μεγαλύτερο μέρος του κώδικα χρειάζεται λειτουργία καθυστέρησης για να σταματήσει η εκτέλεση της εργασίας, αλλά σε RTOS δεν προτείνεται να χρησιμοποιήσετε τη λειτουργία καθυστέρησης () καθώς σταματά τη CPU και ως εκ τούτου το RTOS σταματά επίσης να λειτουργεί. Έτσι, το FreeRTOS διαθέτει API πυρήνα για να αποκλείει την εργασία για συγκεκριμένο χρόνο.
vTaskDelay (const TickType_t xTicksToDelay);
Αυτό το API μπορεί να χρησιμοποιηθεί για λόγους καθυστέρησης. Αυτό το API καθυστερεί μια εργασία για έναν δεδομένο αριθμό κροτώνων. Ο πραγματικός χρόνος για τον οποίο η εργασία παραμένει αποκλεισμένη εξαρτάται από το ρυθμό κροτώνων. Το σταθερό portTICK_PERIOD_MS μπορεί να χρησιμοποιηθεί για τον υπολογισμό σε πραγματικό χρόνο από το ρυθμό επιλογής.
Αυτό σημαίνει ότι αν θέλετε καθυστέρηση 200ms, απλώς γράψτε αυτήν τη γραμμή
vTaskDelay (200 / portTICK_PERIOD_MS);
Έτσι, για αυτό το σεμινάριο, θα χρησιμοποιήσουμε αυτά τα API FreeRTOS για την υλοποίηση τριών εργασιών.
API που θα χρησιμοποιηθούν:
- xTaskCreate ();
- vTaskStartScheduler ();
- vTaskDelay ();
Εργασία που θα δημιουργηθεί για αυτό το σεμινάριο:
- Το LED αναβοσβήνει στον ψηφιακό ακροδέκτη 8 με συχνότητα 200ms
- Το LED αναβοσβήνει στον ψηφιακό ακροδέκτη 7 με συχνότητα 300ms
- Εκτυπώστε αριθμούς σε σειριακή οθόνη με συχνότητα 500ms.
Εφαρμογή FreeRTOS Task στο Arduino IDE
1. Από την παραπάνω βασική εξήγηση δομής, συμπεριλάβετε το αρχείο κεφαλίδας Arduino FreeRTOS. Στη συνέχεια, κάντε πρωτότυπα λειτουργίας. Καθώς έχουμε τρεις εργασίες, οπότε κάντε τρεις λειτουργίες και είναι πρωτότυπα.
#include void TaskBlink1 (void * pvParameters); void TaskBlink2 (void * pvParameters); void Taskprint (void * pvParameters);
2. Στη λειτουργία void setup () , αρχικοποιήστε τη σειριακή επικοινωνία στα 9600 bits ανά δευτερόλεπτο και δημιουργήστε και τις τρεις εργασίες χρησιμοποιώντας το xTaskCreate () API. Αρχικά, κάντε τις προτεραιότητες όλων των εργασιών ως «1» και ξεκινήστε το χρονοδιάγραμμα.
άκυρη ρύθμιση () { Serial.begin (9600); xTaskCreate (TaskBlink1, "Task1", 128, NULL, 1, NULL); xTaskCreate (TaskBlink2, "Task2", 128, NULL, 1, NULL); xTaskCreate (Taskprint, "Task3", 128, NULL, 1, NULL); vTaskStartScheduler (); }
3. Τώρα, εφαρμόστε και τις τρεις λειτουργίες όπως φαίνεται παρακάτω για το task1 LED αναβοσβήνει.
void TaskBlink1 (void * pvParameters) { pinMode (8, OUTPUT); ενώ (1) { digitalWrite (8, ΥΨΗΛΟ); vTaskDelay (200 / portTICK_PERIOD_MS); digitalWrite (8, ΧΑΜΗΛΗ); vTaskDelay (200 / portTICK_PERIOD_MS); } }
Ομοίως, υλοποιήστε τη συνάρτηση TaskBlink2. Η συνάρτηση Task3 θα γραφτεί ως
void Taskprint (void * pvParameters) { int counter = 0; ενώ (1) { μετρητής ++; Serial.println (μετρητής); vTaskDelay (500 / portTICK_PERIOD_MS); } }
Αυτό είναι. Ολοκληρώσαμε με επιτυχία ένα έργο FreeRTOS Arduino για το Arduino Uno. Μπορείτε να βρείτε πλήρη κώδικα μαζί με ένα βίντεο στο τέλος αυτού του σεμιναρίου.
Τέλος, συνδέστε δύο LED στον ψηφιακό πείρο 7 και 8 και ανεβάστε τον κωδικό στην πλακέτα Arduino και ανοίξτε την οθόνη Serial Θα δείτε ότι ένας μετρητής λειτουργεί μία φορά στα 500 ms με όνομα εργασίας όπως φαίνεται παρακάτω.
Επίσης, παρατηρήστε τις λυχνίες LED, αναβοσβήνουν σε διαφορετικά χρονικά διαστήματα. Προσπαθήστε να παίξετε με το όρισμα προτεραιότητας στη συνάρτηση xTaskCreate . Αλλάξτε τον αριθμό και παρατηρήστε τη συμπεριφορά της σειριακής οθόνης και των LED.
Τώρα, μπορείτε να καταλάβετε τους δύο πρώτους κωδικούς παραδείγματος στους οποίους δημιουργούνται εργασίες αναλογικής ανάγνωσης και ψηφιακής ανάγνωσης. Με αυτόν τον τρόπο, μπορείτε να κάνετε πιο προχωρημένα έργα χρησιμοποιώντας μόνο τα Arduino Uno και FreeRTOS API.