diff --git a/Logsys-Linux.tex b/Logsys-Linux.tex index eb97daceb2d838089ee281ecbbcd420ec5829505..a54b275860fd1431b30dfdb3588020d8e6c0d05a 100644 --- a/Logsys-Linux.tex +++ b/Logsys-Linux.tex @@ -128,13 +128,13 @@ Az ötlet a következő volt: futtassuk a Windowsos programot egy VM-ben (Window \begin{figure}[h] \label{fig:vm} \centering - \includegraphics[width=300px]{vm} + \includegraphics[width=250px]{vm} \caption{A mérési elrendezés} \end{figure} Azonban akadt egy kis probléma: néha a VM-en belül nem lehetett megnyitni a JTAG interfészt. Ezért kénytelen voltam egy régi Windows XP-re telepíteni a Logsys toolchaint és a WireSharkot. Azonban a Windowsos WireShark nem támogatja az USB folyam lehallgatását, így erre egy újabb segédprogramot, az USBPcap-et kellett telepítenem. De végül sikerült elegendő mérési adatot összegyűjtenem, ami alapján el tudtam kezdeni a Logsys GUI és az LDC közti protokoll felderítését. -A protokoll visszafejtését kezdetben szisztematikus teszteléssel végeztem: elindítottam a WireShark (vagy az USBPcap) csomagelkapását, megnyomtam egy gombot a Logsys GUI-n, leállítottam a csomagelfogást, és kielemeztem. Ezzel a módszerrel sikeresen megfejtettem az alap funkciók (tápfeszültség állítása, aszinkron reset, adatátviteli módok be-/kikapcsolása, JTAG lánc le\textit{tap}ogatása). Azonban bizonyos funkciókat nem lehetett ily módon megfejteni (ilyenek tipikusan az adatátvitelek, így például az egyik legfontosabb funkció, a JTAG interfészen keresztüli FPGA konfiguráció). +A protokoll visszafejtését kezdetben szisztematikus teszteléssel végeztem: elindítottam a WireShark (vagy az USBPcap) csomagelkapását, megnyomtam egy gombot a Logsys GUI-n, leállítottam a csomagelfogást, és kielemeztem. Ezzel a módszerrel sikeresen megfejtettem az alap funkciók (tápfeszültség állítása, aszinkron reset, adatátviteli módok be-/kikapcsolása, JTAG lánc letapogatása). Azonban bizonyos funkciókat nem lehetett ily módon megfejteni (ilyenek tipikusan az adatátvitelek, így például az egyik legfontosabb funkció, a JTAG interfészen keresztüli FPGA konfiguráció). Így a későbbiekben nekiálltam a Logsys GUI "hagyományos" úton történő visszafejtésének is (decompile az ILSpy nevű program segítségével), amivel kiegészíthettem hiányos ismereteimet. Emellett időközben Raikovich Tamástól kaptam egy PDF-et, amiben leírja a (csomagelkapásból megfejthetetlen, bináris adatfolyamként érkező) struktúrák kiosztását. Ezenfelül fejlesztés közben jómagam is kutattam az Interneten további dokumentáció után, így akadtam például Wacha Gábor Qt alapú Logsys GUI-rekreációjára, aminek forráskódját készségesen rendelkezésemre bocsájtotta. @@ -161,8 +161,9 @@ A saját implementációm hivatkozásánál a fájlok nevei és a sorszámok a k \subsubsection{Státusz lekérése} A Logsys GUI működése közben figyeli az LDC állapotleíróit (kimeneti feszültségek, kifolyó áram, túláram védelem bitje stb.), ezeket az információkat másodpercenként többször is lekérdezi az eszköztől. -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|} \hline \textit{Művelet} & \textit{Lekérdezés}\\ \hhline{|=|=|} irány & IN\\ \hline @@ -210,8 +211,9 @@ A tápfeszültséget lehet be- illetve kikapcsolni, a túláram- és visszáram Tápfeszültség állapota: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|l|} \hline \textit{Művelet} & \textit{Lekérdezés} & \textit{Beállítás}\\ \hhline{|=|=|=|} irány & IN & OUT\\ \hline @@ -233,8 +235,9 @@ Az IN kérés egy egybájtos logikai értéket (bool) ad vissza. \noindent Túláramvédelem: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|l|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|l|l|l|} \hline \textit{Művelet} & \textit{Lekérdezés} & \textit{Beállítás 450 mA-ra} & \textit{Beállítás 700 mA-ra} & \textit{Beállítás 950 mA-ra}\\ \hhline{|=|=|=|=|=|} irány & IN & OUT & OUT & OUT\\ \hline @@ -255,10 +258,13 @@ Az IN kérés egy 0-2 közötti számot ad vissza, ami a 450, 700 illetve 950 mA \vspace{1em} +\pagebreak % FIXME + Áramerősség-mérés korrekciós faktorai: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|} +\noindent\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|} \hline \textit{Művelet} & \textit{Lekérdezés}\\ \hhline{|=|=|} irány & IN\\ \hline @@ -295,8 +301,9 @@ Az IN kérés által visszaadott struktúrát nem implementáltam, de a követke Visszáram-tolerancia -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|l|} +\underline{URB Control blokk:} + +\noindent\noindent\begin{tabular}{|l|l|l|} \hline \textit{Művelet} & \textit{Lekérdezés} & \textit{Beállítás}\\ \hhline{|=|=|=|} irány & IN & OUT\\ \hline @@ -317,8 +324,11 @@ Az IN kérés egy 10 bites, fixpontos kettes komplemens számot ad vissza, az OU \subsubsection{Aktív átviteli mód lekérdezése} Új adatátviteli mód megnyitása előtt célszerű megnézni, hogy van-e ütközés a korábban megnyitottakkal (bár ilyen esetben az LDC jelzi, hogy nem nyitható meg az átvitel). Az éppen aktív átviteli módot a következőképp kérdezhetjük le: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|} +\pagebreak % FIXME + +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|} \hline \textit{Művelet} & \textit{Lekérdezés}\\ \hhline{|=|=|} irány & IN\\ \hline @@ -339,10 +349,11 @@ A visszaadott bájt jelzi az aktív átviteli módot (és 0 ha nincs megnyitva e A kétféle JTAG módról a JTAG-ot tárgyaló fejezetben írok. Az egyes átviteli módok megnyitása/lezárása a róluk szóló fejezetben leírt kérésekkel történik. \subsubsection{Órajel generálás} -Ha a CLK lábat nem használja egyetlen megnyitott átvitel sem, az LDC beépített négyszögjel-generátorának köszönhetően ki tudunk adni rajta egy órajelet. +Ha a CLK lábat nem használja egyetlen megnyitott átvitel sem, az LDC beépített négyszögjel-generátorának köszönhetően ki tudunk adni rajta egy órajelet (0,2 Hz és 8MHz között). + +\underline{URB Control blokk:} -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|l|l|} +\noindent\begin{tabular}{|l|l|l|l|} \hline \textit{Művelet} & \textit{Leállítás} & \textit{Lekérdezés} & \textit{Beállítás}\\ \hhline{|=|=|=|=|} irány & IN & IN & IN\\ \hline @@ -362,8 +373,9 @@ Leállításkor és elindításkor a sikerességet jelző (S) logikai változót \subsubsection{Aszinkron reset} Ha nincs a RST lábat használó átvitel megnyitva, lehetőségünk van aszinkron bitbang módban vezérelni. -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|l|l|} \hline \textit{Művelet} & \textit{Alacsonyra állítás} & \textit{Magasba állítás} & \textit{Lekérdezés}\\ \hhline{|=|=|=|=|} irány & IN & IN & IN\\ \hline @@ -382,8 +394,9 @@ Az első és talán legfontosabb implementált átviteli mód a JTAG. Ez a 0. in A JTAG megnyitásához két Control blokkot kell kiadnunk: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|l|} \hline \textit{Művelet} & \textit{JTAG inicializálás} & \textit{Adatátvitel megnyitása}\\ \hhline{|=|=|=|} irány & IN & OUT\\ \hline @@ -403,8 +416,9 @@ Megnyitott JTAG átvitel közben fel tudjuk deríteni a JTAG láncot (\textit{Bo Az átvitel bezárásához a következő kérést használjuk: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|} \hline \textit{Művelet} & \textit{JTAG bezárás}\\ \hhline{|=|=|} irány & OUT\\ \hline @@ -434,10 +448,13 @@ Visszaolvasás módban működik pl. a Boundary Scan, mert ott az eszköz ID cod \vspace{1em} +\pagebreak % FIXME + \noindent Az ellenőrzést a következő kéréssel végezzük: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|} \hline \textit{Művelet} & \textit{JTAG bezárás}\\ \hhline{|=|=|} irány & IN\\ \hline @@ -451,8 +468,9 @@ Visszaolvasás módban működik pl. a Boundary Scan, mert ott az eszköz ID cod A módot megnyitott átvitel esetén is átválthatjuk: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|l|} \hline \textit{Művelet} & \textit{Lekérdezés} & \textit{Beállítás}\\ \hhline{|=|=|=|} irány & IN & OUT\\ \hline @@ -509,6 +527,8 @@ TMS írás visszaolvasás módban: 2. oktett & \multicolumn{8}{c|}{kiírandó TMS bitek}\\\hline \end{tabular} +\pagebreak % FIXME + TMS írás ellenőrzés módban: \noindent\begin{tabular}{|l|c|c|c|c|c|c|c|c|} @@ -544,14 +564,14 @@ RUNTEST ellenőrzés módban: 4. oktett & \multicolumn{8}{c|}{pulzusok száma}\\\hline \end{tabular} -Ebben a módban TCK vonalra a megadott számú órajelpulzust lehet kiküldeni és a TMS vonal értéke a \textit{TMS} bit lesz.\cite{RT-dipterv} Ez a RUNTEST SVF parancsoknál hasznos. Ezt a módot nem használom, mivel a libxsvf elabsztrahálja előlem a RUNTEST parancsot. +Ebben a módban TCK vonalra a megadott számú órajelpulzust lehet kiküldeni és a TMS vonal értéke a \textit{TMS} bit lesz.\cite{RT-dipterv} Ez a RUNTEST SVF parancsoknál hasznos. Ezt a módot nem használom, mivel a libxsvf elfedi előlem a RUNTEST parancsot. Ellenőrzés módban a számítógépnek ugyanannyi bájtot kell visszaolvasnia, mint amennyit elküldött. A visszaolvasott bájtok közül csak minden második a hasznos TDO adat, a többi bájt értéke 0.\cite{RT-dipterv} \noindent\textbf{FPGA konfigurációs fájlok} -A libxsvf-nek köszönhetően SVF és XSVF formátumú fájlokat képes a program natívan kezelni. Azonban a BIT (és JED) formátumok nem nyíltak, így azok kezeléséhez a Xilinx egyik segédprogramjával (iMPACT) át kell konvertálnom SVF-re. (ugyanezt teszi egyébként a Logsys GUI is). +A libxsvf-nek köszönhetően SVF és XSVF formátumú fájlokat képes a program natívan kezelni. Azonban a BIT (és JED) formátumok nem nyíltak, így azok kezeléséhez a Xilinx egyik segédprogramját használva (iMPACT) át kell konvertálnom SVF-re (ugyanezt teszi egyébként a Logsys GUI is). A segédprogrammal való kommunikációhoz a libc \texttt{popen} metódusát használom, ami a Unix pipe-okat használja (a Logsys GUI pedig temporális fájlokat hoz létre ugyanerre a célra). Azonban az iMPACT-nak nem lehet megmondani, hogy ne hozzon létre logfájlt, így hogy ne szemetelje tele a munkakönyvtárat, a szubprocessz elindítása előtt átlépek a \texttt{/tmp} könyvtárba, ami Unix-szerű rendszereken általában bárki által írható és nem perzisztens tároló. Ennek következtében azonban elveszítjük a relatív útvonalak használatának lehetőségét (hiszen mappát váltunk, és az így a \texttt{/tmp}-hez képest értelmeződne). @@ -575,8 +595,9 @@ Az adatátvitel történhet 8, 4, 2 vagy 1 MHz-es órajel mellett, ezenfelül t Az átvitel a következő két kéréssel nyitható meg: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|l|} \hline \textit{Művelet} & \textit{Inicializálás} & \textit{Átvitel indítása}\\ \hhline{|=|=|=|} irány & IN & OUT\\ \hline @@ -620,8 +641,9 @@ Ezt a műveletsort végzi el nekünk a \texttt{logsys\_spi\_cmd} függvény. Az átvitel bezárásához a következő kérést használjuk: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|} \hline \textit{Művelet} & \textit{SPI bezárás}\\ \hhline{|=|=|} irány & OUT\\ \hline @@ -651,8 +673,9 @@ Az USART (Universal Synchronous/Asynchronous Receive \& Transmit) adatátvitelle Az átvitel indítása a következő kérésekkel történik: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|l|l|} \hline \textit{Művelet} & \textit{Inicializálás} & \textit{Órajel megadása} & \textit{Vonali kódolás beállítása}\\ \hhline{|=|=|=|=|} irány & IN & OUT & OUT\\ \hline @@ -672,8 +695,9 @@ A portra való írás egy egyszerű Bulk átvitellel történik a 0x05-ös végp Az átvitelt ezzel a kéréssel zárhatjuk be: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|} \hline \textit{Művelet} & \textit{Bezárás}\\ \hhline{|=|=|} irány & OUT\\ \hline @@ -685,10 +709,11 @@ Az átvitelt ezzel a kéréssel zárhatjuk be: \vspace{1em} -Illetve lehetőségünk van a soros port képességeinek lekérésére (minimális és maximális baudráta, órajel stb.) +Illetve lehetőségünk van a soros port képességeinek lekérésére (minimális és maximális baud\-ráta, órajel stb.) -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|} \hline \textit{Művelet} & \textit{Képességek lekérdezése}\\ \hhline{|=|=|} irány & IN\\ \hline @@ -728,8 +753,9 @@ A LDC képes a MISO, MOSI, CLK, RST és IOREF lábait használva szinkron BitBan Az LDC vezérli a MOSI, CLK és RST lábakat, és a CLK fel- illetve lefutó éleire mintavételezi ezeket és a MISO lábat. Az órajel elindításához és az adatátvitel megkezdéséhez a következő két kérést kell elküldenünk: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|l|} \hline \textit{Művelet} & \textit{Inicializálás} & \textit{Átvitel indítása}\\ \hhline{|=|=|=|} irány & IN & OUT\\ \hline @@ -745,8 +771,9 @@ Az IN által visszaadott bájt jelzi a kérés sikerességét, és 0, ha már eg Az órajel-frekvenciát adatátvitel közben is megváltoztathatjuk: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|} \hline \textit{Művelet} & \textit{Órajel változtatás}\\ \hhline{|=|=|} irány & OUT\\ \hline @@ -766,14 +793,15 @@ Az órajel-frekvenciát adatátvitel közben is megváltoztathatjuk: mező & (00CR OI00) & (00cr oi00)\\ \hline \end{tabular} -\noindent, ahol az első oktett a CLK felfutó, a második a lefutó élén vett értékek és C=CLK, R=RST, O=MOSI és I=MISO. +Az első oktett a CLK felfutó, a második a lefutó élén vett értékek és C=CLK, R=RST, O=MOSI és I=MISO. \vspace{1em} Az átvitelt lezárni pedig a következőképpen lehet: -\noindent\textbf{URB Control blokk:}\\ -\begin{tabular}{|l|l|} +\underline{URB Control blokk:} + +\noindent\begin{tabular}{|l|l|} \hline \textit{Művelet} & \textit{Átvitel bezárása}\\ \hhline{|=|=|} irány & OUT\\ \hline @@ -832,7 +860,7 @@ A libxsvf ezt a függvényt hívja az SVF olvasásához. Nekünk csupán egy kar Mivel az LDC nem rendelkezik TRST kivezetéssel, nem használja JTAG átvitel közben a soros kommunikáció CLK vonalát és nem támogatja a TCK frekvenciájának állítását, így ezeket a függvényeket nem kell implementálnom. \subsubsection{\texttt{report\_*}} -Ezek a függvények a felhasználó tájékoztatására szolgálnak. Főleg debug információkat írnak ki, ezért nem implementáltam (kivétel ezalól a \texttt{report\_error}, amit hibaállapotban hív meg a libxsvf, és ennek hatására STDERR-re kiírom a hibaüzenetet). +Ezek a függvények a felhasználó tájékoztatására szolgálnak. Főleg debug információkat írnak ki, ezért nem implementáltam (kivétel ez alól a \texttt{report\_error}, amit hibaállapotban hív meg a libxsvf, és ennek hatására STDERR-re kiírom a hibaüzenetet). \subsubsection{\texttt{udelay} és \texttt{realloc}} A \texttt{udelay} hívás arra szolgál, hogy adott mikroszekundum időtartamig, a TMS-t megadott értékre állítva kiadjak néhány TCK pulzust. Erre szolgálna a RUNTEST mód, amit azonban relatív ritkasága és körülményes implementációja miatt nem használok, ehelyett ezt a \texttt{pulse\_tck} függvénnyel (lásd lejjebb) oldom meg. @@ -855,7 +883,7 @@ A függvény feladata "összevárni" a homogén adatokat (legfeljebb 8-at), majd A TMS írás feltétele, hogy a TDI "Don't Care" legyen (a kódban -1), a TMS pedig 0 vagy 1. A \texttt{dbit} egy ring countert valósít meg, ami az éppen írandó bitet jelöli ki. A \texttt{data} tárolja a kiírandó adatot, a \texttt{chk} a várt TDO értékeket, a \texttt{cmask} pedig a TDO maszkot. -Amíg a TMS írás feltétele fennáll, \texttt{data}-ban eltároljuk a kiírandó TMS értéket (a \texttt{dbit} által kijelölt biten), valamint ha TDO nem "Don't Care", akkor őt eltárojluk \texttt{chk}-ben és bebillentjük \texttt{cmask} megfelelő bitjét. +Amíg a TMS írás feltétele fennáll, \texttt{data}-ban eltároljuk a kiírandó TMS értéket (a \texttt{dbit} által kijelölt biten), valamint ha TDO nem "Don't Care", akkor őt eltároljuk \texttt{chk}-ben és bebillentjük \texttt{cmask} megfelelő bitjét. Ha már összegyűjtöttünk 8 TCK pulzust, vagy már nem TMS írás történik, akkor \texttt{bulk\_out}-ban létrehozunk egy keretet a kiszámított értékek számára. @@ -863,7 +891,7 @@ Ha már összegyűjtöttünk 8 TCK pulzust, vagy már nem TMS írás történik, A TDI írás feltétele, hogy a TDI 0 vagy 1 legyen, a TMS pedig az utolsó bit kivételével 0 (az utolsó bitnél lehet más is, az lesz az 1. bájt 6. bitje, lást \ref{ssssec:JTAG xfer}/JTAG adatátvitel). A \texttt{dbit} itt is az éppen írandó bitet jelöli ki. A \texttt{data} tárolja a kiírandó adatot, a \texttt{chk} a várt TDO értékeket, a \texttt{cmask} pedig a TDO maszkot. Különbség csupán a \texttt{tmsAfter} változó jelenléte. -Amíg a TDI írás feltétele fennáll, \texttt{data}-ban eltároljuk a kiírandó TDI értéket (a \texttt{dbit} által kijelölt biten), valamint ha TDO nem "Don't Care", akkor őt eltárojluk \texttt{chk}-ben és bebillentjük \texttt{cmask} megfelelő bitjét. +Amíg a TDI írás feltétele fennáll, \texttt{data}-ban eltároljuk a kiírandó TDI értéket (a \texttt{dbit} által kijelölt biten), valamint ha TDO nem "Don't Care", akkor őt eltároljuk \texttt{chk}-ben és bebillentjük \texttt{cmask} megfelelő bitjét. Ha már összegyűjtöttünk 8 TCK pulzust, vagy már nem TDI írás történik, esetleg elértünk egy TDI+TMS íráshoz (ami csak a TDI írás utolsó bitjeként szerepelhet), akkor \texttt{bulk\_out}-ban létrehozunk egy keretet a kiszámított értékek számára.