Προγραμματισμός

Η Java λαμβάνει σειριακή υποστήριξη με το νέο πακέτο javax.comm

Το Java Communications API (a.k.a. javax.comm) είναι μια προτεινόμενη τυπική επέκταση που επιτρέπει στους δημιουργούς εφαρμογών επικοινωνίας να γράφουν λογισμικό Java που έχει πρόσβαση σε θύρες επικοινωνιών με τρόπο ανεξάρτητο από την πλατφόρμα. Αυτό το API μπορεί να χρησιμοποιηθεί για την εγγραφή λογισμικού εξομοίωσης τερματικού, λογισμικού φαξ, λογισμικού αναγνώστης έξυπνων καρτών και ούτω καθεξής.

Η ανάπτυξη καλού λογισμικού συνήθως σημαίνει ότι έχετε κάποιες σαφώς καθορισμένες διεπαφές. Το διάγραμμα υψηλού επιπέδου των επιπέδων διεπαφής API φαίνεται σε αυτό το σχήμα.

Σε αυτό το άρθρο θα σας δείξουμε πώς να χρησιμοποιήσετε το javax.comm για επικοινωνία με μια σειριακή συσκευή που βασίζεται στο RS-232. Θα συζητήσουμε επίσης τι παρέχει το javax.comm API και τι δεν παρέχει. Θα παρουσιάσουμε ένα μικρό παράδειγμα προγράμματος που σας δείχνει πώς να επικοινωνείτε με τη σειριακή θύρα χρησιμοποιώντας αυτό το API. Στο τέλος του άρθρου θα αναλύσουμε εν συντομία πώς αυτό το API javax.comm θα λειτουργεί με άλλα προγράμματα οδήγησης συσκευών και θα εξετάσουμε τις απαιτήσεις για την εκτέλεση μιας εγγενής θύρας αυτού του API σε ένα συγκεκριμένο λειτουργικό σύστημα.

Σε αντίθεση με τα κλασσικά προγράμματα οδήγησης, τα οποία συνοδεύονται από τα δικά τους μοντέλα επικοινωνίας ασύγχρονων συμβάντων, το javax.comm API παρέχει μια διεπαφή τύπου συμβάντος που βασίζεται στο μοντέλο συμβάντων Java (πακέτο java.awt.event). Ας πούμε ότι θέλουμε να μάθουμε αν υπάρχουν νέα δεδομένα που βρίσκονται στο buffer εισόδου. Μπορούμε να το βρούμε με δύο τρόπους - από σφυγμομέτρηση ή ακούω. Με την ψηφοφορία, ο επεξεργαστής ελέγχει περιοδικά το buffer για να δει αν υπάρχουν νέα δεδομένα στο buffer. Με την ακρόαση, ο επεξεργαστής περιμένει ένα συμβάν με τη μορφή νέων δεδομένων στο buffer εισόδου. Μόλις φτάσουν νέα δεδομένα στο buffer, στέλνει μια ειδοποίηση ή ένα συμβάν στον επεξεργαστή.

Μεταξύ των διαφόρων διαθέσιμων σειριακών διεπαφών, δύο από τα πιο δημοφιλή είναι τα πρότυπα RS-232C και RS-422, τα οποία καθορίζουν τα επίπεδα ηλεκτρικού σήματος και την έννοια των διαφόρων γραμμών σήματος. Οι σειριακές διεπαφές χαμηλής ταχύτητας συνήθως ρολογούν δεδομένα ως τετράγωνο κύμα, με συντονισμό ρολογιού από bit έναρξης και διακοπής.

Το RS-232 σημαίνει Προτείνετε το πρότυπο 232; ο ντο απλώς αναφέρεται στην τελευταία αναθεώρηση του προτύπου. Οι σειριακές θύρες στους περισσότερους υπολογιστές χρησιμοποιούν ένα υποσύνολο του προτύπου RS-232C. Το πλήρες πρότυπο RS-232C καθορίζει έναν συνδετήρα "D" 25 ακίδων, από τους οποίους χρησιμοποιούνται 22 ακίδες. Οι περισσότερες από αυτές τις ακίδες δεν είναι απαραίτητες για κανονικές επικοινωνίες υπολογιστή, και μάλιστα, οι περισσότεροι νέοι υπολογιστές είναι εξοπλισμένοι με αρσενικές συνδέσεις τύπου D που έχουν μόνο 9 ακίδες. Για περισσότερα σχετικά με το RS-232, ανατρέξτε στην ενότητα Πόροι.

Σημείωση: Για να κατανοήσετε τι έχουν κάνει άλλοι οδηγοί στο παρελθόν, ρίξτε μια ματιά στο Unix τερμιό χειροκίνητη σελίδα ή OpenBSD Unix, μια παραλλαγή της πηγής προγράμματος οδήγησης BSD Unix. Αυτό διατίθεται δωρεάν στο Διαδίκτυο. Ανατρέξτε στην ενότητα Πόροι για περισσότερες πληροφορίες.

Το API javax.comm: Τι παρέχεται

Το javax.comm API παρέχει τις ακόλουθες λειτουργίες στους προγραμματιστές:

  • Μια πλήρης προδιαγραφή API για σειριακές και παράλληλες θύρες επικοινωνίας. (Σε αυτό το άρθρο θεωρούμε μόνο σειριακές θύρες.) Χωρίς κοινό API στις προσπάθειές σας για ανάπτυξη, ο φόρτος εργασίας θα αυξηθεί επειδή θα πρέπει να παρέχετε υποστήριξη σε σειριακές συσκευές.

  • Πλήρης έλεγχος όλων των σειριακών παραμέτρων καρέ (baud stop bits, parity, bits / frame) καθώς και χειροκίνητος ή αυτόματος έλεγχος των γραμμών ελέγχου ροής. Κανονικά, στο RS-232, υπάρχουν δύο γραμμές σήματος και οι υπόλοιπες προορίζονται για γραμμές ελέγχου. Ανάλογα με τον τύπο επικοινωνίας (σύγχρονο ή ασύγχρονο), ο αριθμός των επιλεγμένων γραμμών ελέγχου ενδέχεται να διαφέρει. Αυτό το API παρέχει πρόσβαση στα υποκείμενα σήματα ελέγχου.

    Μια σύντομη εκτροπή εδώ μπορεί να σας βοηθήσει να καταλάβετε κάτι για την ισοτιμία και να ξεκινήσετε και να σταματήσετε. Το Parity προστέθηκε στο RS-232 επειδή οι γραμμές επικοινωνίας μπορεί να είναι θορυβώδεις. Ας πούμε ότι στέλνουμε ASCII 0, το οποίο σε εξάγωνο ισούται με 0x30 (ή 00110000 σε δυαδικό), αλλά στην πορεία κάποιος περνά κρατώντας έναν μαγνήτη, προκαλώντας ένα από τα δυαδικά ψηφία να αλλάξει. Ως αποτέλεσμα, αντί να στέλνετε 8 bits όπως προορίζεται, ένα επιπλέον bit προστίθεται στην πρώτη συμβολοσειρά bits που αποστέλλεται, κάνοντας το άθροισμα των bit που στάλθηκαν ομοιόμορφα ή μονό. βόλα! Έχεις ισοτιμία.

    Προστέθηκαν bit έναρξης και διακοπής στο πρωτόκολλο σειριακής επικοινωνίας για να επιτρέψουν στους δέκτες να συγχρονιστούν με τους χαρακτήρες που αποστέλλονται. Η ισοτιμία ενός bit δεν επιτρέπει διόρθωση σφαλμάτων - μόνο ανίχνευση. Οι λύσεις σε αυτό το πρόβλημα προέρχονται από πρωτόκολλα που βρίσκονται σε στρώσεις πάνω από τα σειριακά API. Οι περισσότερες σειριακές επικοινωνίες αυτές τις μέρες χρησιμοποιούν πρωτόκολλα μπλοκ με αθροίσματα ελέγχου (μια μαθηματική συνάρτηση που μπορεί να δημιουργηθεί στον δέκτη και σε σύγκριση με το μεταδιδόμενο άθροισμα ελέγχου) που επιτρέπουν την ανίχνευση σφαλμάτων σε μεγαλύτερες ομάδες bit. Όταν επικοινωνείτε με τον ISP μέσω PPP, τα πακέτα μπορεί να είναι 128 byte ανά πακέτο με αθροίσματα ελέγχου. Εάν ταιριάζουν, είστε 99,999% σίγουροι ότι τα δεδομένα είναι εντάξει.

    Υπάρχουν περιπτώσεις όπου αυτό το σχήμα δεν λειτουργεί. Για παράδειγμα, κατά την αποστολή κρίσιμων εντολών σε συσκευές που βρίσκονται πολύ μακριά στο ηλιακό σύστημα, προς τα εμπρός διόρθωση πρωτοκόλλων μπορεί να χρησιμοποιηθεί. Απαιτούνται πρωτόκολλα διόρθωσης προς τα εμπρός, επειδή ενδέχεται να μην υπάρχει χρόνος για αναμετάδοση και ο χώρος έχει πολύ ηλεκτρομαγνητικό θόρυβο.

    Εντάξει, επιστρέψτε στη λίστα των λειτουργιών που παρέχονται από το javax.comm API!

  • Το βασικό I / O μέσω μιας υποκατηγορίας ροών Java IO. Για είσοδο και έξοδο, το javax.comm API χρησιμοποιεί ροές. η έννοια των ροών πρέπει να είναι οικεία σε όλους τους προγραμματιστές Java. Είναι σημαντικό να επαναχρησιμοποιήσετε έννοιες Java όταν δημιουργείτε νέες λειτουργίες ή τα API θα γίνουν δυσκίνητα.

  • Ροές που μπορούν να επεκταθούν για να παρέχουν έλεγχο ροής και κατώφλι πελάτη. Για παράδειγμα, μπορεί να θέλετε μια ειδοποίηση όταν υπάρχουν 10 χαρακτήρες στο buffer ή όταν απομένουν μόνο 10 τοποθεσίες για χαρακτήρες. Ο έλεγχος ροής είναι σημαντικός όταν οι δύο συσκευές που συνδέονται μέσω μιας διεπαφής δεν μπορούν να συμβαδίζουν μεταξύ τους. Χωρίς έλεγχο ροής, μπορείτε να έχετε υπερβαίνουν ή υποβαθμίζονται. Στην κατάσταση υπέρβασης, λάβατε δεδομένα πριν από την επεξεργασία τους, ώστε να χαθούν. στο underrun, ήσασταν έτοιμοι για δεδομένα, αλλά δεν ήταν διαθέσιμο. Συνήθως αυτές οι συνθήκες εμφανίζονται στο USART (Universal Synchronous Asynchronous Receiver Transmitter), το οποίο είναι υλικό που μετατρέπει byte σε μορφή σειριακού κύματος με χρονισμό ώστε να ταιριάζει με τον ρυθμό baud.

    Το javax.comm API χρησιμοποιεί το μοντέλο συμβάντος Java για να παρέχει ειδοποίηση για διάφορες αλλαγές γραμμής σήματος καθώς και κατάσταση κατάστασης buffer. Οι αλλαγές κατάστασης αναφέρονται σε καλά καθορισμένα σήματα που καθορίζονται στο πρότυπο RS-232. Για παράδειγμα, η ανίχνευση φορέα χρησιμοποιείται από ένα μόντεμ για να σηματοδοτήσει ότι έχει κάνει σύνδεση με άλλο μόντεμ ή αν έχει ανιχνεύσει έναν τόνο φορέα. Η πραγματοποίηση της σύνδεσης ή η ανίχνευση ενός τόνου φορέα είναι ένα συμβάν. Η ανίχνευση συμβάντων και η ειδοποίηση αλλαγών εφαρμόζεται σε αυτό το API.

Τι δεν παρέχεται

Το API javax.comm δεν παρέχει:

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

    Διαχείριση κλήσης και διαχείριση μόντεμ είναι πρόσθετες εφαρμογές που μπορούν να γραφτούν χρησιμοποιώντας το javax.comm API. Η διαχείριση κλήσης παρέχει συνήθως μια διεπαφή στη διεπαφή εντολών AT της διαχείρισης του μόντεμ. Σχεδόν όλα τα μόντεμ έχουν μια διεπαφή εντολών AT. Αυτή η διεπαφή τεκμηριώνεται σε εγχειρίδια μόντεμ.

    Ίσως ένα μικρό παράδειγμα θα καταστήσει σαφή αυτή την έννοια. Ας υποθέσουμε ότι έχουμε ένα μόντεμ στο COM1 και θέλουμε να καλέσουμε έναν αριθμό τηλεφώνου. Μια εφαρμογή διαχείρισης κλήσεων Java θα ζητήσει τον αριθμό τηλεφώνου και θα ανακρίνει το μόντεμ. Αυτές οι εντολές εκτελούνται από το javax.comm, το οποίο δεν έχει καμία ερμηνεία. Για να καλέσετε τον αριθμό 918003210288, για παράδειγμα, η διαχείριση κλήσης πιθανότατα στέλνει ένα "AT", ελπίζοντας να επιστρέψει ένα "ΟΚ", ακολουθούμενο από το ATDT918003210288. Ένα από τα πιο σημαντικά καθήκοντα της διαχείρισης κλήσης και της διαχείρισης μόντεμ είναι η αντιμετώπιση σφαλμάτων και χρονικών ορίων.

  • GUI για διαχείριση σειριακής θύρας. Κανονικά, οι σειριακές θύρες έχουν ένα παράθυρο διαλόγου που διαμορφώνει τις σειριακές θύρες, επιτρέποντας στους χρήστες να ορίζουν παραμέτρους όπως baud rate, parity και ούτω καθεξής. Το παρακάτω διάγραμμα απεικονίζει τα αντικείμενα που εμπλέκονται στην ανάγνωση ή / και τη σύνταξη δεδομένων σε μια σειριακή θύρα από την Java.

  • Υποστήριξη για πρωτόκολλα μόντεμ X, Y και Z. Αυτά τα πρωτόκολλα παρέχουν υποστήριξη εντοπισμού και διόρθωσης σφαλμάτων.

Τα βασικά του προγραμματισμού

Πολύ συχνά, οι προγραμματιστές βουτούν κατευθείαν σε ένα έργο και κωδικοποιούν αλληλεπιδραστικά με ένα API στην οθόνη χωρίς να σκέφτονται το πρόβλημα που προσπαθούν να λύσουν. Για να αποφύγετε σύγχυση και πιθανά προβλήματα, συλλέξτε τις ακόλουθες πληροφορίες πριν ξεκινήσετε ένα έργο. Θυμηθείτε, οι συσκευές προγραμματισμού συνήθως απαιτούν να συμβουλευτείτε ένα εγχειρίδιο.

  1. Αποκτήστε το εγχειρίδιο για τη συσκευή και διαβάστε την ενότητα στη διεπαφή RS-232 και το πρωτόκολλο RS-232. Οι περισσότερες συσκευές διαθέτουν ένα πρωτόκολλο που πρέπει να ακολουθηθεί. Αυτό το πρωτόκολλο θα μεταφερθεί από το API javax.comm και θα παραδοθεί στη συσκευή. Η συσκευή θα αποκωδικοποιήσει το πρωτόκολλο και θα πρέπει να δώσετε ιδιαίτερη προσοχή στην αποστολή δεδομένων μπρος-πίσω. Η μη σωστή ρύθμιση της αρχικής ρύθμισης μπορεί να σημαίνει ότι η εφαρμογή σας δεν θα ξεκινήσει, οπότε αφιερώστε λίγο χρόνο για να δοκιμάσετε τα πράγματα με μια απλή εφαρμογή. Με άλλα λόγια, δημιουργήστε μια εφαρμογή που μπορεί απλώς να γράψει δεδομένα στη σειριακή θύρα και στη συνέχεια να διαβάσει δεδομένα από τη σειριακή θύρα χρησιμοποιώντας το API javax.comm.

  2. Προσπαθήστε να λάβετε μερικά δείγματα κώδικα από τον κατασκευαστή. Ακόμα κι αν είναι σε άλλη γλώσσα, αυτά τα παραδείγματα μπορεί να είναι αρκετά χρήσιμα.

  3. Βρείτε και κωδικοποιήστε το μικρότερο παράδειγμα που μπορείτε να επιβεβαιώσετε ότι μπορείτε να επικοινωνήσετε με τη συσκευή. Στην περίπτωση σειριακών συσκευών, αυτό μπορεί να είναι πολύ οδυνηρό - στέλνετε δεδομένα σε μια συσκευή συνδεδεμένη στη σειριακή θύρα και δεν συμβαίνει τίποτα. Αυτό είναι συχνά αποτέλεσμα λανθασμένης ρύθμισης της γραμμής. Ο νούμερο ένα κανόνας του προγραμματισμού συσκευών (εκτός αν γράφετε πρόγραμμα οδήγησης συσκευής) είναι να βεβαιωθείτε ότι μπορείτε να επικοινωνείτε με τη συσκευή. Κάντε το με την εύρεση του απλούστερου πράγμα που μπορείτε να κάνετε με τη συσκευή σας και τη λειτουργία του.

  4. Εάν το πρωτόκολλο είναι πολύ περίπλοκο, σκεφτείτε να αποκτήσετε κάποιο λογισμικό ανάλυσης γραμμής RS-232. Αυτό το λογισμικό σας επιτρέπει να δείτε τα δεδομένα που κινούνται μεταξύ των δύο συσκευών στη σύνδεση RS-232 χωρίς να παρεμβαίνει στη μετάδοση.

Η επιτυχής χρήση του API javax.comm σε μια εφαρμογή απαιτεί την παροχή κάποιου τύπου διασύνδεσης στο πρωτόκολλο της συσκευής χρησιμοποιώντας το σειριακό API ως μηχανισμό μεταφοράς. Με άλλα λόγια, με εξαίρεση τις απλούστερες συσκευές, συνήθως απαιτείται ένα άλλο επίπεδο για τη μορφοποίηση των δεδομένων για τη συσκευή. Φυσικά το απλούστερο πρωτόκολλο είναι "βανίλια" - που σημαίνει ότι δεν υπάρχει πρωτόκολλο. Στέλνετε και λαμβάνετε δεδομένα χωρίς ερμηνεία.

Επισκόπηση των προτεινόμενων βημάτων για τη χρήση του javax.comm

Εκτός από την παροχή ενός πρωτοκόλλου, το πρότυπο στρώσης ISO που χρησιμοποιείται για TCP / IP ισχύει επίσης εδώ, καθώς έχουμε ένα ηλεκτρικό στρώμα, ακολουθούμενο από ένα πολύ απλό στρώμα μεταφοράς byte. Πάνω από αυτό το στρώμα μεταφοράς byte θα μπορούσατε να βάλετε το στρώμα μεταφοράς σας. Για παράδειγμα, η στοίβα PPP θα μπορούσε να χρησιμοποιήσει το API javax.comm για να μεταφέρει bytes μπρος-πίσω στο μόντεμ. Ο ρόλος του επιπέδου javax.comm είναι πολύ μικρός όταν εξετάζεται σε αυτό το πλαίσιο:

  1. Δώστε στο javax.comm API έλεγχο ορισμένων από τις συσκευές. Πριν χρησιμοποιήσετε μια συσκευή, το javax.comm API πρέπει να το γνωρίζει.

  2. Ανοίξτε τη συσκευή και ρυθμίστε τη γραμμή. Ενδέχεται να έχετε μια συσκευή που απαιτεί ρυθμό baud 115 kilobits χωρίς ισοτιμία.

  3. Γράψτε μερικά δεδομένα ή / και διαβάστε δεδομένα ακολουθώντας οποιοδήποτε πρωτόκολλο απαιτεί η συσκευή με την οποία επικοινωνείτε. Για παράδειγμα, εάν συνδεθείτε σε έναν εκτυπωτή, ίσως χρειαστεί να στείλετε έναν ειδικό κωδικό για να ξεκινήσετε τον εκτυπωτή ή / και να τερματίσετε την εργασία. Ορισμένοι εκτυπωτές PostScript απαιτούν να τερματίσετε την εργασία στέλνοντας CTRL-D 0x03.

  4. Κλείστε τη θύρα.

Αρχικοποίηση του μητρώου API javax.comm με σειριακές θύρες διασύνδεσης

Το API javax.comm μπορεί να διαχειρίζεται μόνο τις θύρες που γνωρίζει. Η τελευταία έκδοση του API δεν απαιτεί την προετοιμασία θυρών. Κατά την εκκίνηση, το javax.comm API σαρώνει θύρες στον συγκεκριμένο κεντρικό υπολογιστή και τις προσθέτει αυτόματα.

Μπορείτε να αρχικοποιήσετε τις σειριακές θύρες που μπορεί να χρησιμοποιήσει το API javax.comm. Για συσκευές που δεν ακολουθούν την τυπική σύμβαση ονομασίας, μπορείτε να τις προσθέσετε ρητά χρησιμοποιώντας το τμήμα κώδικα παρακάτω.

// Καταχωρίστε τη συσκευή CommPort ttya = new javax.comm.solaris.SolarisSerial ("ttya", "/ dev / ttya"); CommPortIdentifier.addPort (ttya, CommPortIdentifier.PORT_SERIAL); CommPort ttyb = νέο javax.comm.solaris.SolarisSerial ("ttyb", "/ dev / ttyb"); CommPortIdentifier.addPort (ttyb, CommPortIdentifier.PORT_SERIAL); 

Συσκευές ανοίγματος και κλιματισμού

Αυτό το επόμενο δείγμα κώδικα δείχνει τον τρόπο προσθήκης, συνθήκης και ανοίγματος μιας συσκευής. Λεπτομέρειες σχετικά με τις συγκεκριμένες μεθόδους κλήσεων βρίσκονται στις σελίδες API για το javax.comm. Αυτό το παράδειγμα ορίζει ότι η συσκευή που ονομάζεται XYZSerialDevice είναι προσβάσιμη με όνομα GenericSerialReader. Η συσκευή που είναι συνδεδεμένη σε αυτήν τη γραμμή έχει ρυθμό baud 9600, 1 bit διακοπής, χαρακτήρα 8 bit (ναι, μπορεί να είναι μικρότερα) και χωρίς ισοτιμία. Το αποτέλεσμα όλων αυτών είναι η παροχή δύο ροών - η μία για ανάγνωση και η άλλη για γραφή.