USB soros kommunikáció

A fejezet tartalma:

Az USB-ről dióhéjban

A személyi számítógépek világméretű elterjedése láttán néhány cég (Compaq, DEC, IBM, Intel, Microsoft, NEC, Northern Telecom) összefogott, és kidolgozta az USB (Universal Serial Bus) specifikációját. Első verzióját 1995 végén hagyták jóvá, 2000-ben megjelent a 2.0-ás változat, 2009. végén pedig kiadták a 3.0 változat specifikációját is (www.usb.org). Számunkra az USB 2.0 specifikációja az irányadó, ugyanis a Freescale Kinetis KL25Z mikrovezérlő család az USB 2.0 Full speed (12 Mbit/s) eszközök specifikációját teljesíti.

Az USB alkalmazása kétféle előnnyel jár a korábbi periféria csatlakoztatásra használt sínekhez képest: a perifériák a számítógép kikapcsolása nélkül csatlakoztathatók, illetve választhatók le (ez a valódi plug and play), és megszünteti a kapuszűkéből adódó kényelmetlenséget. Soros portból elvileg négy van (COM1-COM4), de mivel csak két megszakítást rendeltek hozzájuk, a gyakorlatban csak kettő használható közülük egyszerre.

Az USB közös hozzáférésű, lekérdezés alapú, csillag topológiájú perifériahálózat. Az egyes perifériák csak a központi vezérlőtől, a hosttól kapott engedélycsomag - a token - birtokában küldhetnek vagy fogadhatnak adatot. A hálózaton csak egy host lehet, ezért perifériahálózat az USB. A host szempontjából a perifériák egyenrangúak. Minden perifériának külön saját címe van: egy 1 és 127 közé eső szám; a host ezzel szólítja meg őket. Adatátviteli sebessége 12 megabit/másodperc, de csatlakoztathatók hozzá lassúbb, 1,5 megabit/másodperc átvitelű perifériák is.

A mi esetünkben a host mindig a számítógép lesz, a FRDM-KL25Z kártya mikrovezérlője csak perifériaként képes az USB hálózatra csatlakozni. Habár az MKL25Z128VLK4 mikrovezérlő USB OTG vezérlője elvileg alkalmas host funkció ellátására is, a birtokunkban levő FRDM-KL25Z kártya hardver kialakítása (rev D kiadás) és az mbed API jelenlegi verziója nem támogatja ennek használatát.

Az USB adatkommunikáció egy sodrott érpáron zajlik, amelyeken az adatot differenciális jel formájában (D+ és D-) továbbítjuk. Az USB 2.0 specifikáció háromféle adatátviteli sebességet határoz meg:

Alacsony sebességű átvitel (Low speed eszközök): 1,5 Mbit/s
Teljes sebességű átvitel (Full speed eszközök): 12 Mbit/s
Nagysebességű adatátvitel (High speed eszközök): 480 Mbit/s

Az MKL25Z128VLK4 mikrovezérlő "alacsony" és "teljes" adatátviteli sebességre képes, de ezek közül mi csak a Full speed (12 Mbit/s) üzemmódot fogjuk használni.

Ahhoz, hogy a MKL25Z128VLK4 mikrovezérlő USB kommunikációs egységét használni tudjuk, a KL25Z jelű USB csatlakozót a számítógéphez kell csatlakoztatnunk (lásd az 1. ábrán!).

Programletöltéshez és UART kommunikációhoz természetesen az SDA feliratú USB csatlakozót is a számítógéphez kell kötnünk , de programfuttatásnál bármelyik USB csatlakozón keresztül megkapjuk a működtető tápfeszültséget.

1. ábra: A MKL25Z128VLK4 mikrovezérlő csatlakoztatása USB kommunikációhoz

USB kommunikáció - alkalmazási szinten

Az USB specifikációja nemcsak a hardver követelményeket írja le, hanem az USB adatvonalain folyó kommunikáció rétegeit is. Minden USB tranzakció keretezett csomagokból áll, az adatátvitel hibamentességét CRC ellenőrző kód segítségével állapíthatjuk meg. Az USB tranzakciók legalsó szintjét az USB illesztők többnyire hardveresen lekezelik, tehát nem kell foglalkoznunk vele.

Minden USB tranzakció az alábbi csomagokból áll:

Végpontok és végpont típusok

Ahogy korábban említettük, az USB kommunikáció host központú, tehát a host eszköz kezdeményez minden tranzakciót. A tranzakció a másik oldalon mindig egy úgynevezett "végpontban" (endpoint) ér véget. A szoftver szinten ezek a "végpontok" egy-egy adatbuffert jelentenek, ahol keletkeznek vagy célba érnek az adatcsomagok. A host felől érkező OUT adatcsomagot az USB eszköz firmware programja olvassa ki a megfelelő végpont adatbufferéből és valósít meg egy USB funkciót (pl. kigyújt egy LED-et, beállít egy portot stb.). Fordított irányban (pl. adatgyűjtés, nyomógomb állapotának figyelése) a firmware beírja az adatot a megfelelő végpont bufferébe, s az adat ott várakozik, amíg a host ki nem ad egy IN parancsot, melynek hatására az USB vezérlő kiküldi az USB buszon keresztül a hostnak az adatcsomagot. Egy eszközön belül több végpont is lehet, amelyek különféle funkciót látnak el.

Az USB busz átviteli protokoll a perifériák különféle igényeinek megfelelően négyféle működést valósíthat meg, ennek megfelelően az átvitelt, illetve az érintett végpontot az alábbi típusok valamelyikébe soroljuk be:
A vezérlésátvitel a 0-ás sorszámú végponton (EP0) keresztül történik, ezt minden USB eszközben ki kell alakítani. A többi végpont kialakítása opcionális, az eszköz típusától függ. A 0. végponton át folytatott párbeszédben közli az eszköz a host-tal a többi végpontjának jellemzőit (végpontok száma, bufferméret, sávszélesség igény, átvitel típusa).

Az USBSerial objektumosztály

Az USB 2.0 specifikációja több kommunikációs osztályba sorolja az USB eszközöket. A virtuális soros portot megvalósító USB "bulk transfer" kommunikáció a CDC (Character Device Class) eszközosztályba tartozik. Ez az eszköz a PC felől virtuális soros portnak látszik, ezért a kapcsolat bármelyik olyan alkalmazással kezelhető, amely a soros kommunikációs portokat (COM portok) kezelni tudja.

A mikrovezérlő oldalon ehhez a kommunikációs típushoz az USBSerial objektumosztályt kell használnunk. Az mbed API alapértelmezetten nem tartalmazza az USB kommunikációt kezelő programkönyvtárakat. Projektjeinkhez - eszközosztálytól függetlenül - az USBDevice progamkönyvtárat kell importálnunk.

Az USBSerial objektumosztály legfontosabb saját és örökölt tagfüggvényeit az alábbi táblázatban foglaltuk össze. Az itt nem ismertetett tagfüggvények leírása az mbed.org honlapján található. A putc, puts, printf, getc, gets, scanf (a Stream objektumosztályból) öröklött tagfüggvények a hasonló nevű C stdio függvényeknek felelnek meg.

Függvénynév
Rövid leírás
USBSerial név(vid=0x1f00, pid=0x2012, release=0x0100, blocking=true)
Konstruktor függvény. Példányosítja és inicializálja az USBSerial objektumosztályt, s az opcionális paraméterek szerint módosítja a konfigurációt
putc(int c)
Egy karakter küldése a host felé, blokkoló típusú várakozással. (további lehetőségek: puts() vagy printf()
getc()
Egy karakter fogadása a host felől, blokkoló típusú várakozással.
writeBlock(*buf, size)
Adatblokk kiírása (max 64 karakter)
puts(s) Szövegkonstans karakterfüzér kiíratása
gets(s,n) n db karakter fogadása és eltárolása karakterfüzérként az s tömbbe
printf() Formázott kiíratás
scanf()
Formázott szöveg beolvasása
available()
Fogadott karakterek száma
readable()
Megvizsgálja, hogy van-e beérkezett karakter
writeable()
Megvizsgálja, hogy van-e szabad hely a kimeneti tárban

Megjegyzések:

Mintapélda: Kiíratás virtuális soros portra

Az alábbi, "helló világ" szintű programban az USB porton keresztül íratunk ki másodpercenként egy rövid szöveget.

Hardver követelmények:
1. lista: A 13_USBSerial_HelloWorld/main.cpp program listája
#include "mbed.h"
#include "USBSerial.h"

USBSerial serial; //Virtual serial port over USB
int main(void) {
while(1) {
serial.printf("I am a virtual serial port\r\n");
wait(1);
}
}

Összefoglalva: az USBSerial objektumosztály felhasználásával a MKL25Z128VLK4 mikrovezérlő az USB porton keresztül közvetlenül, az OpenSDA közreműködése nélkül kommunikálhat a PC-vel.