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

Άνοιγμα νέων θυρών στην Java με το javax.comm

Εισήχθη στο πακέτο τάξεων javax.comm όταν ανακάλυψα ότι χρησιμοποιήθηκαν στο κιτ ανάπτυξης για το Java Ring. (Για λεπτομέρειες στο javax.comm, ανατρέξτε στο Rinaldo Di Giorgio's Προγραμματιστής Java στήλη στο τεύχος Μαΐου του JavaWorld: "Η Java λαμβάνει σειριακή υποστήριξη με το νέο πακέτο javax.comm.") Κατά τη διάρκεια της τρελής μου βιασύνης στο JavaOne για να βάλω ένα πρόγραμμα στο δαχτυλίδι μου, αντιμετώπισα διάφορα προβλήματα, τα περισσότερα από τα οποία δεν επικοινωνούσαν με το δαχτυλίδι. Κατέβασα τη διανομή από το Java Developer Connection και προσπάθησα να το χρησιμοποιήσω ανεπιτυχώς για να μιλήσω στο Java Ring. Αργότερα, ανακάλυψα το πρόβλημα με το δαχτυλίδι μου: Δεν είχα εγκαταστήσει σωστά τα παλαιά API του Dallas Semiconductor. Με το δαχτυλίδι να λειτουργεί, ξέχασα βασικά το πακέτο επικοινωνίας. Δηλαδή, μέχρι ένα σαββατοκύριακο πριν από ένα μήνα, που είναι το σημείο εκκίνησης αυτής της ιστορίας.

Για πολλούς διαφορετικούς λόγους (ως επί το πλείστον έχουν να κάνουν με πολύ διαδραστικά προσομοιωμένα περιβάλλοντα - για παράδειγμα παιχνίδια), ο κύριος υπολογιστής στο "εργαστήριό μου" εκτελεί Windows 95. Ωστόσο, αυτό το συγκεκριμένο Σαββατοκύριακο ασχολήθηκα περισσότερο με έναν άλλο υπολογιστή που, στο με πολλούς τρόπους, ήταν εξίσου ισχυρό με το Java Ring: μια Digital Equipment Corporation PDP-8 / e.

Το PDP-8 ήταν αναμφισβήτητα ο πρώτος αληθινός προσωπικός υπολογιστής. Σχεδιασμένο στα τέλη της δεκαετίας του 1960 και παράγεται σε σχετικά υψηλές ποσότητες στη δεκαετία του '70, το PDP-8 θα μπορούσε να ανυψωθεί από ένα άτομο, τροφοδοτήθηκε από ρεύμα γραμμής 120 volt και κόστισε λιγότερο από 0,000. Οι περισσότεροι από αυτούς τους υπολογιστές αποστέλλονται με ένα μόνο περιφερειακό: ένα τερματικό Teletype Model ASR-33 - το πρωτότυπο "TTY" στο lingo του υπολογιστή.

Ο τύπος ASR-33 ήταν ένα τερματικό εκτύπωσης που συνοδεύτηκε από συσκευή ανάγνωσης ταινιών και διάτρησης. Ναι, ήταν χαρτοταινία, χαρτί 1 ιντσών με τρύπες μέσα σε αυτό, ήταν το κύριο μέσο αποθήκευσης για προγράμματα στο PDP-8.

Το PDP-8 ήταν ο πρώτος υπολογιστής που έχω προγραμματίσει ποτέ και ως εκ τούτου έχει μια ξεχωριστή θέση στην καρδιά μου. Επιπλέον, λόγω κάποιων τυχαίων συνθηκών, ήμουν στο σωστό μέρος τη σωστή στιγμή και κατάφερα να σώσω ένα PDP-8 που επρόκειτο να απορριφθεί ως σκουπίδια. Παρακάτω εμφανίζεται μια φωτογραφία του βραβείου μου.

Σε αυτό το ξεχωριστό σαββατοκύριακο πριν από πολύ καιρό, αποφάσισα να ξαναζώ το PDP-8 στη ζωή μου, αν ήθελα μόνο να ξαναζήσω αυτές τις πολύτιμες πρώτες αναμνήσεις και να δείξω στην κόρη μου πόσο καλό το έχει με το "παλαιό Pentium 133-MHz της ιλαράς. "

Αναβιώνοντας ένα κλασικό προσομοιώνοντας ένα άλλο

Για να ξεκινήσω την αναζωογονητική μου προσπάθεια, έπρεπε να κάνω ένα πρόγραμμα στο PDP-8. Στο PDP-8, αυτό επιτυγχάνεται ακολουθώντας μια διαδικασία τριών βημάτων:

  1. Χρησιμοποιώντας τους διακόπτες του μπροστινού πίνακα, ο χρήστης "κλειδώνει" ένα σύντομο πρόγραμμα στη μνήμη του μαγνητικού πυρήνα. Αυτό το πρόγραμμα ονομάζεται RIM Loader και σκοπός του είναι να φορτώσει ένα άλλο πρόγραμμα από κασέτα χαρτιού που είναι σε μορφή Read-in-Mode ή RIM.

  2. Το RIM Loader φορτώνει την ταινία χαρτιού σε μορφή RIM. Αυτή η κασέτα περιέχει ένα πρόγραμμα που ονομάζεται BIN Loader, το οποίο μπορεί να φορτώσει προγράμματα από χαρτοταινία σε δυαδική (BIN) μορφή.

  3. Τέλος, εκτελείτε το BIN Loader για να φορτώσετε το πρόγραμμα που πραγματικά θέλετε, το οποίο είναι σε χαρτί σε μορφή BIN. Μπά!

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

Στην προσπάθειά μου να αναζωογονήσω το μηχάνημα, το Βήμα 1 δεν ήταν πρόβλημα, αλλά το Βήμα 2 αφορούσε τη χρήση της συσκευής ανάγνωσης χαρτοταινιών στον Τηλέτυπο - και δεν είχα έναν Τηλετύπο. Φυσικά εγώ έκανε έχω τον επιτραπέζιο υπολογιστή μου, οπότε το λογικό βήμα ήταν να προσομοιώσω μια συσκευή ανάγνωσης χαρτιού στην επιφάνεια εργασίας μου.

Από λογική και προγραμματική άποψη, η προσομοίωση μιας συσκευής ανάγνωσης ταινιών είναι ασήμαντη. Διαβάζετε απλώς ένα αρχείο που περιέχει τα δεδομένα από την ταινία, το στέλνετε σε μια σειριακή θύρα στα 110 baud (ναι, μόνο 10 χαρακτήρες ανά δευτερόλεπτο), έως ότου εξαντλήσετε το αρχείο. Θα μπορούσα να γράψω ένα πρόγραμμα στο C στο σύστημα Solaris ή στο σύστημα FreeBSD σε περίπου 10 λεπτά που θα μπορούσε να το κάνει αυτό - αλλά, θυμηθείτε, ήμουν σε ένα σύστημα Windows 95, όχι σε σύστημα Unix.

Από κακό σε άσχημο και πάλι πίσω

Ήξερα ότι μπορούσα εύκολα να γράψω αυτό το πρόγραμμα στο C, έτσι ήταν η γλώσσα επιλογής μου. Κακή επιλογή. Έφερα το αντίγραφο του Visual C ++ 5.0 και έβγαλα ένα απλό πρόγραμμα που ονομάζεται sendtape.c που κάλεσε Άνοιξε() στη θύρα επικοινωνιών. Προσπάθησα να το βάλω ΑΚΑΤΕΡΓΑΣΤΟΣ mode (η λειτουργία στο Unix όπου το λειτουργικό σύστημα δεν προσπαθεί να ερμηνεύσει τίποτα στη σειριακή θύρα ως είσοδο χρήστη) και στη συνέχεια προσπάθησε να το μεταγλωττίσει. Ωχ, όχι ioctl () λειτουργία ή tty λειτουργίες - nada, zip, zilch!

Κανένα πρόβλημα, σκέφτηκα, "Έχω ολόκληρη τη βιβλιοθήκη του Microsoft Software Developer's Network σε CD με τον μεταγλωττιστή μου. Θα κάνω μια γρήγορη αναζήτηση στις λέξεις-κλειδιά" θύρα COM "."

Η αναζήτηση εμφανίστηκε πολλές αναφορές στο Microsoft Component Object Model (ονομάζεται επίσης COM) και επίσης αναφορές στο MSComm. Το MSComm είναι μια τάξη C ++ που παρέχει η Microsoft για να μιλήσει στις σειριακές θύρες. Κοίταξα τα παραδείγματα και φοβόμουν πόσο κώδικα θα χρειαζόταν για να κάνω ένα τόσο απλό πράγμα όπως να γράψω bytes στη σειριακή θύρα στα 110 baud. Το μόνο που ήθελα να κάνω ήταν να ανοίξω την καταραμένη σειριακή θύρα, να ορίσω το ρυθμό baud και να γεμίσει μερικά bytes - να μην δημιουργήσει μια νέα κατηγορία εφαρμογών ενισχυμένων σειριακών επικοινωνιών!

Καθισμένος μπροστά από την οθόνη μου ήταν ο υποδοχέας Blue Dot για το Java Ring μου, και σκέφτηκα, "Αα! Οι άνθρωποι στο Dallas Semiconductor έχουν βρει πώς να μιλήσουν σε μια σειριακή θύρα στον υπολογιστή. Ας δούμε τι κάνουν. " Αφού εξέτασε τον πηγαίο κώδικα της εταιρείας για το Win32, ήταν σαφές ότι η συνομιλία με σειριακές θύρες δεν θα ήταν απλή εργασία.

Java στη διάσωση

Σε αυτό το σημείο το Σαββατοκύριακο μου, σκεφτόμουν ίσως να έφερνα ένα από τα μηχανήματά μου Unix στο εργαστήριο για να κωδικοποιήσω το πρόγραμμα το αντί να χρησιμοποιήσω αυτό που είχα ήδη. Τότε θυμήθηκα την εμπειρία μου με το Java Ring και το πακέτο java.comm από την Sun. Αντίθετα, αποφάσισα να ακολουθήσω αυτήν τη λεωφόρο.

Τι παρέχει το java.comm;

Το Java Communications API - ή java.comm - παρέχει μια ανεξάρτητη από πλατφόρμα μέθοδο πρόσβασης σε σειριακές και παράλληλες θύρες από την Java. Όπως και με άλλα API της Java, όπως το JFC, το JDBC και το Java 3D, ένα συγκεκριμένο επίπεδο έμμεσης αναγκάζεται στον προγραμματιστή να απομονώσει την ιδέα της πλατφόρμας «τι είναι μια σειριακή θύρα» από το μοντέλο προγραμματισμού. Στην περίπτωση του σχεδιασμού javax.comm, στοιχεία όπως ονόματα συσκευών, τα οποία διαφέρουν από πλατφόρμα σε πλατφόρμα, δεν χρησιμοποιούνται ποτέ απευθείας. Οι τρεις διεπαφές του API παρέχουν ανεξάρτητη πλατφόρμα πρόσβαση σε σειριακές και παράλληλες θύρες. Αυτές οι διεπαφές παρέχουν κλήσεις μεθόδου για να απαριθμήσουν τις διαθέσιμες θύρες επικοινωνίας, να ελέγχουν κοινόχρηστη και αποκλειστική πρόσβαση σε θύρες και να ελέγχουν συγκεκριμένες λειτουργίες θύρας όπως ρυθμό baud, παραγωγή ισοτιμιών και έλεγχο ροής.

Όταν είδα το παράδειγμα SimpleWrite.java στην τεκμηρίωση και συνέκρινα τις 40 γραμμές κώδικα με τις 150 έως 200 γραμμές κώδικα που έβλεπα να γράφω στο C, ήξερα ότι η λύση ήταν στο χέρι.

Η άντληση υψηλού επιπέδου για αυτό το πακέτο είναι η κατηγορία javax.comm.CommPort. ο CommPort Η τάξη καθορίζει τα είδη των πραγμάτων που θα κάνατε συνήθως με μια θύρα, η οποία περιλαμβάνει τη λήψη InputStream και Έξοδος ροής αντικείμενα που είναι τα κανάλια I / O για τη θύρα. ο CommPort Η κλάση περιλαμβάνει επίσης μεθόδους για τον έλεγχο των μεγεθών buffer και την προσαρμογή του τρόπου χειρισμού της εισαγωγής. Δεδομένου ότι ήξερα ότι αυτά τα μαθήματα υποστηρίζουν το πρωτόκολλο Dallas Semiconductor One-Wire (ένα πρωτόκολλο που περιελάμβανε δυναμικές αλλαγές στο ρυθμό baud και απόλυτη διαφάνεια στα byte που μεταφέρθηκαν), ήξερα ότι το API javax.comm έπρεπε να είναι ευέλικτο. Αυτό που ήρθε ως μια ευχάριστη έκπληξη ήταν το πόσο σφιχτά ήταν τα μαθήματα: Είχαν αρκετή ευελιξία για να ολοκληρώσουν τη δουλειά και όχι περισσότερο. Υπήρχε λίγο ή καθόλου περιττό bloatware με τη μορφή «μεθόδων ευκολίας» ή υποστήριξης πρωτοκόλλων μόντεμ όπως Kermit ή xmodem.

Μια συνοδευτική τάξη για CommPort είναι το javax.comm.CommPortIdentifier τάξη. Αυτή η τάξη αφαιρεί τη σχέση μεταξύ του τρόπου με τον οποίο ονομάζεται μια θύρα σε ένα συγκεκριμένο σύστημα (δηλαδή, "/ dev / ttya" σε συστήματα Unix και "COM1" σε συστήματα Windows) και πώς εντοπίζονται οι θύρες. Η στατική μέθοδος getCommPortIdentifiers θα απαριθμήσει όλες τις γνωστές θύρες επικοινωνίας στο σύστημα. Επιπλέον, μπορείτε να προσθέσετε τα δικά σας ονόματα θύρας για ψευδο θύρες επικοινωνίας χρησιμοποιώντας το addPortName μέθοδος.

ο CommPort το μάθημα είναι πραγματικά αφηρημένο και αυτό που παίρνεις πίσω από μια επίκληση άνοιγμα Port στο CommPortIdentifier είναι μια υποκατηγορία του CommPort αυτό είναι είτε Παράλληλη θύρα ή Σειριακή θύρα. Αυτές οι δύο υποκατηγορίες έχουν επιπρόσθετες μεθόδους που σας επιτρέπουν να ελέγχετε την ίδια τη θύρα.

Η δύναμη της Java

Μπορείτε να διαφωνήσετε για την πραγματικότητα του "γράψτε μια φορά, τρέξτε οπουδήποτε" ό, τι θέλετε, αλλά θα σας πω από την εμπειρία ότι για εφαρμογές με ένα νήμα ή ακόμη και απλές πολυήματες μη GUI, η Java είναι εκεί. Συγκεκριμένα, εάν θέλετε να γράψετε ένα πρόγραμμα που εκτελείται σε συστήματα Unix, Win32 και Mac και μπορεί να έχει πρόσβαση στη σειριακή θύρα, τότε η Java είναι η μόνο λύση σήμερα.

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

Ορισμένες εφαρμογές μοιράζονται την απαίτηση για πρόσβαση σε χαμηλό επίπεδο στη σειριακή θύρα. Ο όρος χαμηλό επίπεδο Σε αυτό το πλαίσιο σημαίνει ότι ένα πρόγραμμα έχει πρόσβαση σε διασυνδέσεις που του επιτρέπουν να αλλάζει τρόπους on-the-fly και να δειγματοληπτεί απευθείας και να αλλάζει τις καταστάσεις των καρφιτσών ελέγχου ροής υλικού. Εκτός από το έργο PDP-8, ο Dallas Semiconductor χρειάστηκε να χρησιμοποιήσει τις διασυνδέσεις Blue Dot σε σειριακές θύρες για να μιλήσει στο iButton με την Java. Επιπλέον, οι κατασκευαστές μικροεπεξεργαστών διαθέτουν πίνακες αξιολόγησης που χρησιμοποιούν μια σειριακή θύρα για επικοινωνίες και φόρτωση προγραμμάτων. Όλες αυτές οι εφαρμογές μπορούν τώρα να γραφτούν εντελώς και φορητά σε Java - μια αρκετά ισχυρή δήλωση.

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

Πώς παίζετε με αυτά τα πράγματα;

Για να λάβετε ένα αντίγραφο της τελευταίας διανομής javax.comm, πρώτα θα πρέπει να εγγραφείτε ως προγραμματιστής στο Java Developer Connection (JDC) εάν δεν το έχετε κάνει ήδη. (Δείτε τους πόρους.) Το JDC είναι δωρεάν και ως μέλος θα έχετε πρώιμη πρόσβαση σε μαθήματα Java που τελικά θα είναι μέρος του τελικού προϊόντος.

Μεταβείτε στην ενότητα Java Communications API και κατεβάστε το πιο πρόσφατο αρχείο αρχειοθέτησης javax.comm. Αποσυμπιέστε το αρχείο και εγκαταστήστε τις κοινόχρηστες βιβλιοθήκες (ναι, η εικονική μηχανή Java χρειάζεται εγγενή κώδικα για να μιλήσει στις θύρες - ευτυχώς για εσάς, δεν χρειάζεται να το γράψετε) και εγκαταστήστε το αρχείο comm.jar. Τέλος, προσθέστε το αρχείο comm.jar στο δικό σας CLASSPATH μεταβλητός.

Μόλις το αρχείο comm.jar αποθηκευτεί στον κατάλογο lib της εγκατάστασης Java και το win32comm.dll αποθηκευτεί στον κατάλογο bin της εγκατάστασης Java, μπορείτε να μεταγλωττίσετε και να εκτελέσετε όλα τα παραδείγματα που συνοδεύουν τη λήψη. Σας ενθαρρύνω να τα κοιτάξετε καθώς υπάρχουν πολλές καλές πληροφορίες με τον πηγαίο κώδικα.

Πού αφήνει αυτό το PDP-8;

Λοιπόν, τι συνέβη με το PDP-8; Νόμιζα ότι δεν θα ρωτούσες ποτέ! Αφού διαβάσω το έγγραφο README που συνοδεύει τη διανομή javax.comm και, στη συνέχεια, σάρωση του JavaDocs για το πακέτο javax.comm, έκανα μαζί μια κατηγορία εφαρμογών που ονομάζεται Αποστολή ταινίας. Αυτή η τάξη προσομοιώνει μια συσκευή ανάγνωσης ταινιών ανοίγοντας τη σειριακή θύρα και γεμίζοντας bytes πάνω της στα 110 baud. Ο κωδικός για αυτήν την τάξη εμφανίζεται εδώ:

εισαγωγή javax.comm. *; εισαγωγή java.io. *; δημόσια τάξη SendTape {static final int LEADER = 0; στατικό τελικό int COLLECT_ADDR = 1; στατικό τελικό int COLLECT_DATA = 2; στατικό τελικό int COLLECT_DATA2 = 3; / * Αυτός ο πίνακας περιέχει ένα αντίγραφο του φορτωτή μορφής BIN * / static byte binloader [] = {(byte) 0x80, (byte) 0x80, (byte) 0x80, (byte) 0x80, ... (byte) 0x80, ( byte) 0x80,}; 

Το παραπάνω τμήμα κώδικα είναι το πρώτο μέρος του Αποστολή ταινίας τάξη. Αυτή η τάξη ξεκινά εισάγοντας σιωπηρά όλες τις τάξεις στο πακέτο javax.comm και τα πακέτα java.io. ο Αποστολή ταινίας Η κλάση ορίζει έπειτα ορισμένες σταθερές και προ-προετοιμάζει έναν πίνακα byte για να περιέχει το πρόγραμμα BIN Loader που ανέφερα νωρίτερα. Περιέλαβα το BIN Loader επειδή είναι πάντα απαραίτητο κατά την προετοιμασία της μνήμης του PDP-8 και συνέχισα να χάσω το πού είχα αποθηκεύσει τελευταία το αρχείο που περιέχει την εικόνα του σε μορφή RIM. Με αυτήν την κρίσιμη εικόνα κασέτας ενσωματωμένη στην τάξη με αυτόν τον τρόπο, έχω πάντα τη δυνατότητα να την φορτώνω με αυτήν την τάξη.

 / ** * Αυτή η μέθοδος εκτελεί ένα μηχάνημα mini-state που δίνει * μια χρήσιμη ανθρώπινη αναγνώσιμη έξοδο από ό, τι συμβαίνει * με τη λήψη. * / στατικό int newState (int oldState, byte b) {...} 

Μετά την προετοιμασία, έχετε τον κωδικό για τη μέθοδο νέο κράτος, φαίνεται παραπάνω, που παρακολουθεί τα περιεχόμενα της κασέτας (είτε πρόκειται για πληροφορίες διεύθυνσης είτε για πληροφορίες προγραμματισμού). Η παραπάνω μέθοδος εκτυπώνει επίσης ένα μήνυμα για κάθε θέση μνήμης στο PDP-8 που έχει αρχικοποιηθεί.

Στη συνέχεια έχετε το κύριος μέθοδο, η οποία φαίνεται παρακάτω · ανοίγει το αρχείο και το διαβάζει. Στη συνέχεια, ο κώδικας ανοίγει τη σειριακή θύρα και ορίζει τις παραμέτρους επικοινωνίας.