pátek 20. června 2008

MapGen v2.2 - aktualizace

Díky připomínkám několika lidí jsem si konečně našel čas a opravil poměrně zásadní chybu v MapGenu - při stahování okrajových částí map se nevyrovnal s chybějícími daty (PNG obrázek "Pro toto přiblížení nemáme podklad k dispozici...") a při spojování souborů s nulovou délkou spadnul. Řešení je nakonec relativně snadné, všechny prázdné soubory nahradit bílým pozadím. Realizace už tak snadno nevypadá a zabrala hodně googlení, abych se vyhnul dalším programům a mohl použít jenom příkazový interpreter z Windows XP. Jen tak pro zajímavost, nahrazení nulových souborů je provedeno pomocí příkazu:

for /f %%A in ("img_baseimage.pnm") do if %%~zA equ 0 (pbmmake.exe -white 256 256 > img_baseimage.pnm)

No není to krása? ;-) Kromě odstranění této chyby jsem integroval do nové verze MapGenu kompletní funkci programu MapCoord. V INI souboru přibyly položky LinkBottomLeft a LinkTopRight, které mohou obsahovat link na levý dolní a pravý horní roh, zkopírovaný přes funkci Odkaz na tuto mapu ze serveru mapy.cz. Linky se MapGen pokusí rozparsovat a použít, bude-li libovolná ze specifikovaných souřadnic nulová. Kromě toho může být nulová hodnota také úrovně detailu (MapLevel), pak se použije detail specifikovaný v linku. Jinak má přednost prametr MapLevel z INI souboru. Program MapGen v2.2 je opět volně ke stažení zde.

úterý 17. června 2008

Vinculum: ovládání USB zařízení

V rámci jednoho z fakultních projektů jsem byl postaven před řešení problému, jak ovládat signálový generátor Rohde&Schwarz SM300. Požadavkem bylo řízení z autonomního systému (tedy bez PC jako prostředníka). Jako USB Host byl vybrán poměrně rozšířený a známý obvod Vinculum VNC1L firmy FTDI. Zapojení tohoto obvodu a zprovoznění není nijak extra záludné, pěkná série článků vyšla i v češtině na Pandatronu. Problémy se začnou objevovat ve chvíli, kdy chceme připojit zařízení, které není standardně podporováno, tj. nespadá mezi různé flashdisky, HID, tiskárny apod. Takovým zařízením je samozřejmě i zmíněný vektorový generátor.

Dalším problémem pak může být nezveřejněný/utajený komunikační protokol mezi USB periferií a počítačem. V tomto příspěvku bych rád nastínil vhodný software a postupy pro odhalení komunikačního protokolu neznámého zařízení a jeho implementaci do mikroprocesoru řídicího Vinculum. Nepředpokládám, že by někdo řešil komunikace konkrétně se SM300, stejně tak se rozhodně nesnažím o podrobný návod - spíš se jedná o náznaky, jaké postupy při tvorbě ovladačů realizujících komunikaci přes Vinculum použít.

Co bude potřeba: vhodný počítač, ke kterému lze požadované USB zařízení připojit, s nainstalovanými ovladači a aplikací k řízení tohoto zařízení, dále s programem UsbSnoop; bastldesku s Vinculem, připojeným přes RS232 k počítači; samotné USB zařízení a nějakou tu kabeláž. Z dokumentace pak rozhodně datasheet k VNC1L a k firmwaru VDAP, dále specifikaci USB 2.0 (ano, je to bible, ale občas se to toho člověk musí nakouknout) a samozřejmě Google. Mně zpočátku třeba velice pomohl dokument Reverse engineering Windows USB device drivers for the purpose of creating compatible device drivers for Linux.

Vinculum definuje ve firmwaru VDAP pro práci s obecným USB zařízením sadu příkazů, z nichž o komunikaci se starají Send/Read Data (DSD, DRD) a Send Setup Data (SSU). V první fázi je tedy nutné zjistit, jakým způsobem zařízení komunikuje. To lze vyčíst z logu programu UsbSnoop, ten je však extrémně rozsáhlý a nepřehledný. Pro první nástřel je lepší využít omezené demo některé z komerčních aplikací, např. SysNucleus USBTrace. Po vyfiltrování mnoha nepodstatných paketů se dostaneme k paketům, které odpovídají příkazům zadávaným z počítače. Pro zmíněný generátor SM300 jsou to pakety typu URB_FUNCTION_VENDOR_DEVICE, což představuje Setup pakety (SSU) s Request identifikátorem, který není definovaný standardem, viz USB 2.0 specifikace kap. 9.3 a Vinculum firmware manuál kap. 6.6.6. Ostatní pakety nejsou pro přenos podstatné, což se ovšem liší přístroj od přístroje - např. v ukázce komunikace s klávesnicí na Pandatronu se využívá klasického datového přenosu (DRD). Setup pakety představují vlastně "příkaz" (identifikátor Value), který může obsahovat další data, resp. o ně žádat.

Komunikaci pro jednotlivé příkazy lze zachytit programem UsbSnoop. Pro SM300 pak dojdeme např. při nastavení frekvence 300MHz k záznamu:

[1920707 ms]  >>>  URB 1618 going down  >>>
-- URB_FUNCTION_VENDOR_DEVICE:
TransferFlags = 00000002 (USBD_TRANSFER_DIRECTION_OUT, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000008
TransferBuffer = 00000000
TransferBufferMDL = 85c951f0
00000000: 00 00 00 00 a3 e1 b1 41
UrbLink = 00000000
RequestTypeReservedBits = 00000000
Request = 00000035
Value = 00002010
Index = 00000000

[1920711 ms] <<< URB 1618 coming back <<<
-- URB_FUNCTION_CONTROL_TRANSFER:
PipeHandle = 85e64748
TransferFlags = 0000000a (USBD_TRANSFER_DIRECTION_OUT, USBD_SHORT_TRANSFER_OK)
TransferBufferLength = 00000008
TransferBuffer = 00000000
TransferBufferMDL = 85c951f0
UrbLink = 00000000
SetupPacket =
00000000: 40 35 10 20 00 00 08 00

Z paketu je patrné, že nastavení frekvence je identifikováno pomocí vendor request 0x0035, value 0x2010, následované daty 00 00 00 00 a3 e1 b1 41, což je double reprezentace hodnoty 300 ve tvaru LSB first. Položka SetupPacket pak obsahuje celý zaslaný paket bez dat, odpovídající požadavek k nastavení frekvence, posílaný po USB, tedy bude: 40 35 10 20 00 00 08 00 00 00 00 00 a3 e1 b1 41. Tohle je jen jeden příklad z mnoha, pro SM300 dále musí následovat příkaz pro provedení nastavení (value 0x37ff).

Poslední částí realizace je pak komunikace pomocí samotného Vincula. Po připojení VNC1L k počítači, napájení a USB zařízení ve vhodném terminálu zkontrolujeme uvítací hlášku Vincula (Ver něco On-Line) a pomocí příkazů IPH a SCS nastavíme binární zkrácený režim příkazů (viz kap. 6.6 manuálu k firmware Vincula). Dále přes 2c 0d (QP2 / Query Port 2) ověříme připojení "neznámého zařízení" na portu 2 a provedeme listing připojených zařízení přes 85 20 nn 0d (QD / Query Device), kde nn je index od 0 do 15. Vinculum vrací stavovou strukturu, obsahující VID a PID daného zařízení, při nalezení správného zařízení jej vybereme ke komunikaci pomocí 86 20 nn 0d (SC / Set Device). Vyhledání dle VID/PID je důležité zejména u komplexních zařízení, jako je zmíněný generátor SM300, které na USB sběrnici obsahují hub a více zařízení rozlišených podle PID.

Nyní již je možné komunikovat se samotným zařízením pomocí příkazů SSU, pro příklad zmíněný výše (nastavení frekvence) bude tedy příkaz vypadat: 9a 20 40 35 10 20 00 00 08 00 0d 00 00 00 00 a3 e1 b1 41. Červeně je značený příkaz Vinculu (SSU + CR), modře setup paket, zeleně zasílaná data. Při úspěšném provedení odpoví Vinculum promptem ('>' + CR), podobným tvarem lze také používat setup pakety na čtení z USB zařízení, potom před promptem vrátí Vinculum data přečtená z USB zařízení.

Jak bylo už řečeno na začátku, nejedná se o žádný návod ani konkrétní postup, vše je to o "hraní si" se zkoumaným zařízením, o jeho hackování v původním významu tohoto slova. Takže pokud budete tvořit vlastní ovladače do jednočipu, který přes Vinculum bude spolupracovat s USB zařízením, přeji hodně úspěchů!

neděle 1. června 2008

Externí HDD a Ferguson D-880HX

Konečně máme po zkouškách, tak jsem se rozhodl, že si udělám radost a svůj postarší DVD/DivX přehrávač Yamada DVX-6700 vyměním za novější kousek železa. Volba padla na Ferguson D-880HX, zejména pro jeho podporu USB2.0, vynikající možnosti nastavení titulků a příznivou cenu. Recenzi tohoto přístroje si můžete přečíst třeba na serveru DIGIlidi, je to opravdu pěkná mašinka. Přehrávání z USB flashdisku fungovalo krásně, nicméně při připojení 2,5" 80GB HDD Hitachi v USB šuplíku, samozřejmě bez externího napájení, se ozvalo jen charakteristické cvakání. Inu nelenil jsem, rozloučil se se zárukou a pustil se do kuchání Ferdových vnitřností.

Cvakání disku je způsobeno poklesem napění na USB portu při vyšším proudovém odběru, vznikajícím při roztáčení disku. Pohledem na základní desku je patrné, že mezi +5V systému a USB jsou zařazeny dva prvky - dioda v propustném směru (D6) a vratná pojistka (F1). Na diodě vzniká právě onen vražedný úbytek napětí - neměřil jsem ji, ale předpokádám, že to bude obyčejná křemíková dioda, tj. s úbytkem 0,6-0,7V, což už je pro HDD moc. Tato dioda ovšem není nezbytná. Má zřejmě zabránit napájení elektroniky přehrávače z vnějšího zařízení, ovšem z principu se na tomto USB portu nikdy externí napájení neocitne, připojovaná zařízení (flash, čtečka, HDD) jsou pasivní. Proto není nic jednoduššího, než diodu D6 přemostit drátovou propojkou. A ejhle, disk bez problémů a odmlouvání najede.

Další drobností, která se mi nelíbí, je fakt, že USB port je napájen i při vypnutí přehrávače, tj. pokud je ve stand-by režimu. Tohle vyřeším hned, jak se mi pod ruku dostane nějaky P-MOSFET, kterým bude možné napájení spínat. Domácí zásoby zklamaly.