|
Das USB-Interface wurde vor Jahren von Intel entworfen, um viele bisher am PC verwendeten Interfaces (RS232, Parallelport, PS2) durch eine einheitliche moderne Schnittstelle abzulösen. Obwohl USB vor allem am Anfang der Firewire-Konkurenz hoffnungslos unterlegen war, hat es sich im PC-Sektor durch die Marktdominanz von Intel durchgesetzt.
Nach und nach verschwinden nun die
beliebten
Bastler-Schnittstellen (RS232 und Parallelport) aus den PCs. Die
meisten
Laptops haben schon keine 'Legacy'-Interfaces mehr. Darum wird
der
Druck
immer größer, sich nach einer Alternative umzusehen. Eine
Möglichkeit
ist der Umstieg auf USB.
Oft werden dafür Chips von
FTDI eingesetzt,
die USB-RS232-Interfaces oder USB-Parallel-Interfaces
darstellen
(Erhältlich
bei Reichelt
und Segor:
7 .. 10€). Da sie auf die Legacy-Interfaces aufbauen,
ist die Software
für diese Chips leicht zu erstellen. Allerdings ist der
Hardwareaufwand
recht hoch, da einige externe Bauelemente (und bei
Nutzung mehrerer
USB-Adapter
sogar ein serieller EEPROM) nötig sind. Außerdem gibt es die FTDI-Chips nur in grobmotorikerfeindlichen SMD-Gehäusen mit 0,6 mm Pinabstand. Da gerät man bei der Platinenerstellung mit haushaltsüblichen Mitteln schnell an die Grenzen. |
|
Deshalb ist es clever von
FTDI,
komplette
USB-Module anzubieten, die die USB-Buchse, den USB-Chip,
den EEPROM und
die anderen peripheren Bauteile auf einer kleinen
Platine vereinen.
Solche
Module werden für 14 britische Pfund angeboten, und
machen die
FTDI-Lösung
für Bastler benutzbar. Allerdings hat man für ca. 20,-€ (+ Versand) lediglich das Interface. Inzwischen gibt es von FTDI sogar einen kompletten RS232-USB-Adapter in Form einer SUB-D-9-Buchse zur Printmontage. Damit lassen sich Schaltungen, die ein RS232-Interface enthalten mit minimalem Aufwand auf USB umrüsten. |
|
Mit den USB-Chips der PIC18Fxx5x-Reihe
steht eine einfachere und recht preiswerte Hardwarelösung zur
Verfügung,
die allerdings etwas kompliziertere Softwareentwicklung bedingt.
Wer diesen
Aufwand
scheut, der kommt vielleicht mit meiner Fertiglösung USB4all
aus.
Das ist ein PIC18F2455 mit einer Firmware. Der Chip kann ohne
tiefere
USB-Kentnisse verwendet werden, um einige typische Geräte via
USB
anzusteuern.
Alle anderen sollten weiterlesen.
Ich ignoriere die HUBs vollständig. Stattdessen tue ich so, als ob der USB-Controller 127 Anschlussbuchsen für USB-Geräte hat. Für den Bastler/Anwender sind HUBs nur wenig mehr als "Verteilerdosen" mit zwei Ausnahmen: Jeder Hub benötigt eine eigene Adresse, und sie haben einen gewissen Einfluss auf die Stromversorgung der USB-Geräte.Die Details der elektrischen Signale auf den USB-Leitungen ignoriere ich, da sich in der Praxis ohnehin spezielle Controller um diese Signale kümmern. Mir ist nur ein Fall bekannt, in dem es gelang low-speed-USB ohne speziellen Controller zu emulieren. (Es handelt sich um einen IR-Empfänger mit einem Atmel-Microcontroller ohne USB-Hardware.)
Besonderheiten von USB 1 werden weitestgehend ignoriert, da die PIC18Fxx5x mit einem USB 2.0-Interface ausgestattet sind.
USB ist ein sternförmiges
Netz von
Geräten (Device), die alle von einem Controller (im PC)
verwaltet
werden. (Auch wenn die Verkabelung baumförmig vorgenommen
werden
kann,
ist der logische Aufbau doch sternförmig.) Der Controller
hat
allein
das Recht, die Kommunikation zwischen ihm und dem Device
zu steuern. Er
kann Daten in einen Pufferspeicher des Device schreiben,
und er kann
Daten
aus einem Pufferspeicher im Device auslesen. Das Device
kann dagegen
nicht
selbständig dem Controller melden, dass es Daten haben
will oder
dass
es Daten für den Controller hat. Es gibt auch keinen
Interrupt, den
das Device auslösen könnte (auch wenn es eine Betriebsart
mit
diesem Namen gibt).
Wie ist unter diesen Bedingungen ein Datenfluss vom Device zum Controller möglich? Beim Reset des USB-Busses
(oder
beim Anstecken
an den Bus), meldet sich jedes Device beim Controller
mit der fiktiven
Adresse 0 an. Der Controller gibt dem Device eine
richtige Adresse
(1..127)
und liest die Konfiguration aus dem Device aus. In
dieser Konfiguration
gibt das Device an, wieviele Pufferspeicher
(genannt Endpunkte)
es
besitzt, wie groß diese Puffer sind (max. 64 Byte) und
ob das
für
den Controller Lesepuffer (In) oder Schreibpuffer (Out)
sind.
Außerdem
wird dem Controller gesagt, wie häufig er prüfen soll,
ob im
Lesepuffer Daten für ihn bereitliegen. Der Controller
muss also
alle
Lesepuffer pollen (immer wieder abfragen)! Für Geräte,
die
vom PC eine
schnelle Reaktion
erfordern
(z.B. die Maus), muss dieses Abfragen (Pollen) mehrere
100 mal pro
Sekunde
erfolgen. |
Die meisten USB-Geräte (Device)
haben
nur eine Funktion. So ist ein Memorystick z.B. nur ein
Massenspeichergerät
und nichts anderes. Ein USB-Lautsprecher ist nur ein
USB-Audiogerät.
Einige Device haben aber auch mehrere
ganz unterschiedliche Funktionen. Ein via USB angeschlossener
externer
CD-Brenner ist sowohl eine Massenspeichergerät (zum Lesen und
Schreiben
von Dateien), wie auch ein Audiogerät (beim Abspielen von
Musik-CDs)
als auch ein Video-Gerät (beim Abspielen von Video-CDs).
Für jede seiner Funktionen hat ein
Device genau ein Interface. Der Memorystick hat also (wie die
meisten
Devices)
ein Interface, und der USB-CD-Brenner z.B. drei Interfaces.
Jedes Interface hat einen oder
mehrere
Endpunkte (Endpoint). Das sind Pufferspeicher, in die der
USB-Controller
Daten hineinschreiben kann (out-Endpoint) oder herauslesen kann
(in-Endpoint).
Damit der Controller die
Configuration
auslesen kann, besitzt jedes Interface einen Lesepuffer
Nr. 0 (Endpunkt
0), der für die Konfiguration zuständig ist. Dieser ist
der
einzige
Endpunkt, der sowohl ausgelesen wie auch beschrieben
werden kann, alle
anderen Endpunkte beherrschen nur eine Datenrichtung.
Der Endpunkt 0 kann auch für den Datentransfer mitbenutzt werden, er bietet aber nur eine geringe Datenrate von 800 Byte/s. Besser ist es zusätzliche Endpunkte zu benutzen. Jeder Endpunkt ist im Device natürlich in Hardware realisiert, und so ist die maximale Anzahl der verfügbaren Endpunkte von der im Device vorhandenen Hardware abhängig. Low-Speed-Devices haben maximal 4 Endpunkte, USB2.0 Devices können bis zu 32 Endpunkte haben. PIC18Fxx5x-Controller haben die nötige Hardware für bis zu 16 Endpunkte. |
Als Hardware existieren in einem
USB-PIC
eigentlich nur die Schnittstelle zum Controller und die 16
Endpunkte.
Alles
dazwischen (Device, Configuration, Interface) ist nur Teil der
Firmware (also Software),
und kann deshalb beliebig verändert werden.
Da der PIC nur eine USB-Schnittstelle
hat ist er auch nur ein Device. Er kann aber beliebig viele
Configurationen
mit beliebig vielen Interfaces haben, solange dafür nicht mehr
als
16 Endpunkte benötigt werden.
Begriffe:
Ein Endpunkt ist eigentlich nur ein
Pufferspeicher, auf den sowohl der USB-Controller, wie auch das
USB-Device
(also der Device-Controller) Zugriff haben. Das möchte ich am
Beispiel
eines Chipkartenlesegerätes verdeutlichen.
Beispiel:
Das Chipkartenlesegeräte wird an
den Bus angesteckt. Da eine der USB-Datenleitungen einen
Pull-Up-Widerstand
besitzt, erkennt der Controller (eigentlich der Hub) das, und
spricht
das
Gerät mit der Device-Adresse 0 an. Aus dem Endpunkt 0 liest der
Controller
die Konfiguration des Device aus. In dieser Konfiguration steht,
dass
das
Device zusätzlich einen Endpunkt 1 (out) und einen Endpunkt 2
(in)
besitzt, wie oft die in-Endpunkte (0 und 2) auf neue Daten
geprüft
werden sollen, wie groß die Pufferspeicher in den Endpunkten
sind
und (indirekt) welcher Treiber im PC für dieses Device benutzt
werden
soll. Der Controller weist dem Gerät eine echte Adresse zu, und
prüft,
ob der Treiber installiert ist. Falls nicht, dann fordert es den
Benutzer
zur Treiberinstallation auf.
Der Benutzer startet irgendwann später auf dem PC das Programm für den Kartenleser, und will Daten aus der Karte auslesen. Einen entsprechenden Befehl sendet das Programm an den Device-Treiber. Dieser schreibt nun durch den Controller einen entsprechenden Befehl in den Endpunkt 1 des Device.
Das Schreiben in den Endpunkt 1 löst im Device-Controller einen Interrupt aus. Der Device-Controller liest den Endpunkt 1 aus, und findet darin den Befehl zum Auslesen der Chipkarte. Er liest die Chipkarte aus, und schreibt soviel Kartendaten in den Pufferspeicher des Endpunkt 2 wie hinein passen.
Der USB-Controller fragt
regelmäßig
alle Endpunkte ab. Als er nun routinemäßig auch den Endpunkt
2 des Kartenlesers abfragt, findet er darin neue Daten vor, die
er aus
dem Endpunk 2
ausliest,
und dem Devicetreiber übergibt. Dieser liefert die Daten beim
PC-Programm
ab. Das Auslesen des Endpunkt kann im Device-Controller einen
Interrupt
auslösen, damit der Device-Controller weitere Daten in den
Endpunkt
2 schreiben kann...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Int & Iso zusammen |
Int & Iso zusammen |
|
|
|
|
|
|
|
|
|
|
|
(max. Zeit zwischen Transfers) |
|
|
|
|
Einem Device, das sich gerade am Bus
anmeldet,
stehen pauschal 100 mA zur Verfügung. Das Device muss also
eine
Betriebsart (eine Konfiguration) beherrschen, in der es nicht
mehr als
100mA verbraucht. Ob es in dieser Betriebsart seine eigentliche
Funktion
als Kartenleser, Festplatte oder was auch immer erfüllen kann,
steht
auf einem anderen Blatt.
Ist für den regulären Betrieb
ein höherer Stromverbrauch nötig, dann muss das Device
dafür
eine andere Konfiguration kennen, darf diese aber nicht
selbständig
einnehmen.
Nachdem sich das Device am Bus angemeldet hat, (und dabei höchstens 100mA verbraucht) kann der Device-Treiber im PC versuchen, das Device in die alternative Konfiguration umzuschalten, in der es seine Funktion erfüllen kann, aber auch mehr Strom verbraucht. Der Controller (mit den HUBs) entscheidet, ob genug Strom zur Verfügung steht. Wenn ja, dann schaltet er das Device in die alternative Konfiguration um, wenn nicht, dann verweigert er das. Das Device funktioniert dann zwar nicht, aber es wird auch eine Überlastung der Stromversorgung vermieden.
Verbraucht ein Device unerlaubt mehr
Strom,
als ihm zusteht, dann wird es (lt. Spezifikation) vom Controller
'zur
Strafe'
abgeschaltet.
Ein Device kann aber auch unterschiedliche Konfigurationen haben, zwischen denen der Device-Treiber umschalten kann.
Beispiel:
Ein Microdrive (Minnifestplatte) sei
in
einem externen Gehäuse mit USB-Anschluss eingebaut, um als
externe
Festplatte zu dienen. Die Speisung des Microdrives soll über den
USB-Bus
erfolgen. Mit nur 100 mA kann man aber das Microdrive nicht
'hochdrehen'.
Zuerst muss ein höherer Strom vom Controller genehmigt werden.
Diese externe Festplatte sollte zwei unterschiedliche Konfigurationen beherrschen:
Konfiguration 1:
Konfiguration 2:
Der Controller erkennt, das ein neues Device angesteckt wurde, und liest dessen Konfiguration aus. Daher weiss er, welcher Treiber für das Device zuständig ist. Der Controller ruft den Treiber, und dieser muss nun versuchen, die Festplatte in Betrieb zu nehmen. Dazu ist das Umschalten in die Konfiguration 2 nötig. Der Treiber 'beantragt' also beim Controller das Umschalten in die 2. Konfiguration. Der Controller prüft, ob am Bus ausreichend Stromreserven bestehen. Wenn ja, dann schaltet er das Device in die Konfiguration 2 um.
Nun darf das Device 250 mA verbrauchen, und startet die Festplatte. Außerdem werden die Endpunkte 1 und 2 zum Datenaustausch eingerichtet.
Die gesamte Struktur des USB-Devices
wird
mit sogenannten Deskriptoren
beschrieben.
Das sind kleine Datensätze von wenigen Byte, die der Controller
aus
dem Device auslesen kann. Diese Deskriptoren
enthalten
alle
Daten über das Device, seine Configurationen sowie deren
Interfaces
und Endpoints.
Nachdem das Device (also das USB-Gerät mit dem PIC) an den PC angesteckt wurde, teilt es dem Windows-Betriebssystem mit, welchen Device-Treiber (also gerätespezifischen USB-Treiber) es benötigt. Der Treiber wird geladen, oder, wenn er noch nicht installiert ist, wird er installiert, oder der Nutzer wird zur Installation aufgefordert.
Nun kann das Anwendungsprogramm im PC Daten an den Device-Treiber übergeben, die dieser an die Firmware im PIC weiterleitet. Die Firmware legt die Daten dann in einem Speicherbereich im PIC ab (Speicher des out-Endpunktes). Dort kann das PIC-Anwendungsprogramm die Daten dann abholen.
Sollen Daten von der PIC-Anwendung an die Windows-Anwendung gesendet werden, dann legt die PIC-Anwendung diese Daten im Speicher ab (Speicher des in-Endpunktes). Die Windows-Anwendung kann diese Daten dann vom Device-Treiber anfordern. Der Treiber liest sie mit Hilfe der USB-Firmware aus dem PIC-Speicher und übergibt sie an die Windows-Anwendung.
Es werden also neben der Windows-Anwendung und der PIC-Anwendung zwingend folgende beiden Softwarepakete benötigt:
HID-Treiber
(human interface device, hid.dll)
HID-Treiber gehören zum Lieferumfang
von Windows.
Die HID-Treiber sind für den
Anschluss
einfacher Geräte wie Tastatur oder Maus gedacht. Daher stammt
auch
der Name HID (human interface device). Tastaturen und Mäuse, die
sich
an den HID-Standard halten, werden von den HID-Treibern von
Windows
unterstützt,
so das diese Geräte keine speziellen Treiber benötigen.
Um den HID-Treiber nutzen zu können,
muss sich der PIC im Windows als HID-Gerät anmelden.
Dafür
ist eine entsprechend angepasste
HID-Firmware im
PIC
nötig.
Auch USB-Memorysticks oder externe USB-Festplatten funktionieren ohne spezielle Treiber, da der nötige Treiber "usbstor.sys" in Windows bereits enthalten ist.
CDC-Treiber
(communication device class, usbser.sys, MsPorts.dll)
Hierbei handelt es sich um eine
RS232-Emulation
via USB unter Win2k und WinXP. Beim Anschluss des entsprechenden
USB-Device
wird auf dem PC ein virtueller Com-Port eingerichtet, auf den
jedes
Windowsprogramm
genauso zugreifen kann, wie auf eine echte RS232-Schnittstelle.
Die
erreichbare
Transfergeschwindigkeit erreicht bis zu 1 MBit/s (125 kByte/s),
und ist
somit deutlich schneller als mit echter RS232-Hardware.
Es lassen sich damit zwar nicht alle
USB-Möglichkeiten
ausnutzen, allerdings ermöglicht es der CDC-Treiber, bereits
vorhandene
Windows-Programme (die bisher den RS232-Anschluss verwendeten)
weiterzunutzen.
Man braucht sich also nicht mit einer speziellen USB-DLL
herumzuschlagen,
sondert kommuniziert über ein scheinbar ganz normales RS232-Port
von
Windows.
Natürlich ist eine entsprechende
CDC-Firmware
im PIC nötig.
Microchip
Custom
Driver (mpusbapi.dll)
Das ist die flexibelste Lösung, um
alle USB-Features effektiv nutzen zu können. Die Nutzung dieses
Treiber
erfordert aber auch etwas mehr Hirnschmalz als die einfacheren
Lösungen.
Dafür erlaubt er aber die Nutzung aller USB Transfer Modes
(control,
interrupt, bulk, isochronous) und bietet die höchste Bandbreite.
Natürlich wird eine entsprechende
Firmware im PIC benötigt.
Nähere Informationen zur Nutzung
des Microchip Custom Drivers versteckt Microchip im "PICDEM
FS USB
USER'S
GUIDE" mit der Dokumentennummer DS51526.
Für den Profi wird es damit teuer.
Der C18 von Microchip hat den etwas sperrigen Preis von 382,17
Euro.
Auch
der CC8E von Knudsen Data ist mit 250 $ nicht wirklich
preiswert. Es
geht
auch preiswerter, aber ich habe nichts gefunden, was deutlich
unter 70
Euro liegt, und die 16-Kern-Bit-PICs
unterstützt.
Für nichtkomerzielle Anwender (und
das sind die meisten Bastler) und für die Ausbildung gibt es
aber
die Student-Edition des Microchip-C18-Compilers
kostenlos. Das
ist
der normale C18-Compiler, der aber (nach einer mehrwöchigen
Testphase)
zwei Features abschaltet:
Da die Firmware nur ein Teil der PIC-Software ist, kann Microchip kein fertiges HEX-File liefern. Vielmehr wird der C-Sourcecode zur Verfügung gestellt. Deshalb ist auch zwingend ein C-Compiler nötig, um die Firmware nutzen zu können. Die Firmware-Source ist nicht ein einzelnes File, sondern eine ganze Reihe von Files, die sich über mehrere Unterverzeichnisse verteilen. Die nebenstehende Grafik zeigt beispielhaft eine Übersicht über die CDC-Firmware-Sourcen. Über 16 Directories verteilen sich über 50 Files.
Die meisten dieser Files muss man sich nicht weiter anschauen, in einigen Files müssen aber manuell Änderungen vorgenommen werden. Hier wird die Configuration des USB-Devices eingestellt, z.B. die Anzahl und Art der Endpunkte.
Die Sourcen der eigentliche
PIC-Anwendungssoftware
schreibt man in das "user"-Verzeichnis. Anschließend compiliert
man
alles zusammen mit dem C18-Compiler, und dann steht im
"_output"-Directory
das fertige HEX-File. Klingt doch ganz einfach, oder?
Was ist denn nun der Unterschied
zwischen
den verschiedenen Firmware-Versionen?
Human
Interface
Device (HID) class firmware
Diese Firmware behandelt das Device
als
HID (Human Interface Device). Das ist die einfachste Möglichkeit
ein
Device an den PC anzuschließen. Spezielle Windows-Treiber
sind auf dem PC nicht erforderlich. Allerdings ist die Datenrate
auf
ca.
800 Byte/s limitiert. Die Firmware belegt ca. 3 kByte im PIC.
Bei der von Microchip zur
Verfügung
gestellten Firmware handelt es sich um ein in C geschriebenes
Beispielprogramm,
bei dem ein PIC sich am PC als Maus anmeldet, und den Mauskursor
des PC
bewegt.
Communication
Device
Class
(CDC)
firmware
Hierbei handelt es sich um eine
RS232-Emulation
via USB unter Win2k und WinXP. Beim Anschluss des USB-Device
wird
auf dem PC ein virtueller COM-Port (COM1..4) eingerichtet, auf
den
jedes
Windowsprogramm genauso zugreifen kann, wie auf eine echte
RS232-Schnittstelle.
Die erreichbare Transfergeschwindigkeit erreicht bis zu 1 MBit/s
(125
kByte/s),
und ist somit deutlich schneller als mit echter RS232-Hardware.
Die nötigen
Treiber sind in Windows enthalten. Sie müssen aber mit
einem
passenden
xxx.ini-File installiert werden.
Die Quelltexte liegen als C-Source
vor.
Die fertig compilierte Firmware belegt im PIC ca. 4 kByte.
Microchip
Custom
Driver firmware
Diese Firmware ist der Partner des "Microchip
Custom Driver" und erlaubt die Nutzung des USB-Ports mit
maximaler
Flexibilität. Leider ist auch die Einarbeitung und Nutzung etwas
aufwendiger
als für HID- oder CDC-Lösungen.
Die Quelltexte liegen als C-Source
vor.
Die fertig compilierte Firmware belegt im PIC ca. 4 kByte. Der
nötige
Windows-Treiber wird von Microchip kostenlos angeboten.
Microchip
Bootloader
Der Bootloader
eignet sich, um nachträglich ein geändertes Programm via USB
in den PIC zu brennen. (Es wird also kein spezielles
Programmiergerät
benötigt.) Ist aber nicht dazu geeignet, um zwischen einem PIC-
und
dem PC 'normal' Daten auszutauschen.
Das Laden eines neuen HEX-Files in
den
PIC erfolgt mit Hilfe eines kleinen Windows-Programms.
Diese
Software
und der nötige Windows-Treiber wird von Microchip kostenlos
angeboten.
Die Quelltexte des Bootloaders liegen als C-Source vor.
Die fertig compilierte Firmware
belegt
im PIC ca. 2 kByte, also den Boot-Block. Wird die
Student-Edition des
C18-Compilers
verwendet, dann wird der Bootloader allerdings eine
Klitzekeinigkeit
größer
als der Boot-Block (es fehlt die Optimierung) was zu Problemen
führen
kann.
Ich habe den Microchip-Bootloader für meine Zwecke so
abgewandelt,
das er mit der Student-Edition des C18 übersetzt werden kann,
ohne
zu groß für den Boot-Block zu werden. Das
ganze
ist hier beschrieben.
Quellen:
- Microchip
- FTDI
- USB2.0 Spezifikation
Autor: sprut
erstellt: 01.02.2006
letzte Änderung: 25.11.2012