]> rtime.felk.cvut.cz Git - mf6xx.git/commitdiff
Diploma thesis text.
authorRostislav Lisovy <lisovy@gmail.com>
Thu, 21 Apr 2011 17:53:26 +0000 (19:53 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Thu, 21 Apr 2011 17:53:26 +0000 (19:53 +0200)
doc/diploma_thesis/text/dip_text.tex
doc/diploma_thesis/text/k336_thesis_macros_new.sty
doc/diploma_thesis/text/lisovy_dip.tex

index ec94f88f796fd71ad225cdf59bb4cdc4da062a56..5046bee294e0b99261fddbbf4905d4d198c72352 100644 (file)
@@ -55,7 +55,7 @@ Jak je možné ovládat hardwarové periferie pomocí programu (software) je nej
 \end{description}%
 }
 
-Prvním způsobem, jak změnit stav GPIO pinu (ať už nastavení, zda se má jednat o vstupní/výstupní pin nebo jakou hodnotu má mít v případě, že je výstupní) je provedení operace zápisu na určitou adresu v paměťovém adresním prostoru (ta je pevně daná a liší mezi jednotlivými architekturami mikrokontrolérů), tato adresa odpovídá \textbf{registru}\footnote{Registr může být pro zjednodušení považován za malou paměťovou buňku. Změna její hodnoty přímo ovliňuje stav hardware. V dokumentaci ke konkrétnímu mikrokontroleru/\-mikroprocesoru/\-programovatelnému integrovanému obvodu je uvedeno, jakou funkci mají jednotlivé bity registru.} GPIO pinu. Vnitřní uspořádání mikrokontroleru, dle adresy na kterou bylo zapisováno, rozpozná, že provedená operace zápisu nebyla určena pro změnu hodnoty vnitřní paměti, ale je určena pro změnu hodnoty registru a z toho plynoucí změny stavu určité části hardwaru. Zapsaná hodnota se tedy projeví změnou stavu GPIO pinu. Tato možnost je nejjednodušší a je možná v případě, že jsou hardwarové periferie mapovány do určité části tzv. \textbf{paměťového prostoru}.\footnote{Také označováno jako MMIO -- \textit{Memory-mapped input/output}}
+Prvním způsobem, jak změnit stav GPIO pinu (ať už nastavení, zda se má jednat o vstupní/výstupní pin nebo jakou hodnotu má mít v případě, že je výstupní) je provedení operace zápisu na určitou adresu v paměťovém adresním prostoru (ta je pevně daná a liší mezi jednotlivými architekturami mikrokontrolérů), tato adresa odpovídá \textbf{registru}\footnote{Registr může být pro zjednodušení považován za malou paměťovou buňku. Změna její hodnoty přímo ovlivňuje stav hardware. V dokumentaci ke konkrétnímu mikrokontroléru/\-mikroprocesoru/\-programovatelnému integrovanému obvodu je uvedeno, jakou funkci mají jednotlivé bity registru.} GPIO pinu. Vnitřní uspořádání mikrokontroléru, dle adresy na kterou bylo zapisováno, rozpozná, že provedená operace zápisu nebyla určena pro změnu hodnoty vnitřní paměti, ale je určena pro změnu hodnoty registru a z toho plynoucí změny stavu určité části hardwaru. Zapsaná hodnota se tedy projeví změnou stavu GPIO pinu. Tato možnost je nejjednodušší a je možná v případě, že jsou hardwarové periferie mapovány do určité části tzv. \textbf{paměťového prostoru}.\footnote{Také označováno jako MMIO -- \textit{Memory-mapped input/output}}
 
 \begin{figure}[h!]
        \begin{center}
@@ -75,7 +75,7 @@ Hlavní rozdíly mezi chováním paměťové buňky a registru zařízení jsou:
 \item Změnou hodnoty registru je možné měnit stav zařízení/periferie odpovídající danému registru.
 \item V případě zápisu do registru a jeho okamžitém čtení, nemusí být přečtená hodnota shodná se zapisovanou -- v tom případě byla hodnota registru změněna hardwarem.
 \item V případě čtení z registru může být spuštěn tzv. \textbf{side effect}, kdy hardware na toto čtení reaguje změnou stavu, podobně jako by byl proveden zápis do registru (Příklad: Ihned po vyčtení hodnoty registru A/D převodníku se spustí nový převod a původní hodnota se přepíše novou). Side effects mohou nastat i při zápisu do registru. 
-\item Při zápisu a čtení do/z registru si je nutné přesně rozlišovat, kolikabitové operace zápisu/čtení smějí být použity (8-, 16-, 32bitové).
+\item Při zápisu a čtení do/z registru si je nutné přesně rozlišovat, kolika-bitové operace zápisu/čtení smějí být použity (8-, 16-, 32bitové).
 \end{itemize}
 
 \begin{figure}[h!]
@@ -92,7 +92,7 @@ Hlavní rozdíly mezi chováním paměťové buňky a registru zařízení jsou:
 \section{PCI sběrnice}\label{pcich}
 %Přesný popis PCI sběrnice je mimo rozsah a zaměření této práce. Pokusím se však zmínit a názorně vysvětlit principy využívané touto sběrnicí, které je nutné alespoň částečně znát při implementaci ovladačů PCI zařízení.
 
-PCI (\textit{Peripheral Component Interconnect}) je standard paralelní sběrnice využívaný v počítačích různých architektur. Šířka paralelně přenášených dat je 32 nebo v modernější, méně často používané verzi, 64 bitů. Sběrnice je orientována na přenost zpráv oproti přímé komunikaci mezi zařízeními\footnote{Příklad: FIXME}
+PCI (\textit{Peripheral Component Interconnect}) je standard paralelní sběrnice využívaný v počítačích různých architektur. Šířka paralelně přenášených dat je 32 nebo v modernější, méně často používané verzi, 64 bitů. Sběrnice je orientována na přenos zpráv oproti přímé komunikaci mezi zařízeními\footnote{Příklad: FIXME}
 
 Komunikace mezi zařízeními připojenými na sběrnici a procesorem zajišťuje tzv. \textit{PCI most} (PCI bridge). Propojení více nezávislých sběrnic v jednom počítači jsou zajištěny také PCI mosty.
 
@@ -101,7 +101,7 @@ V roce 1990 začala práce na specifikaci PCI v laboratořích firmy Intel. Prvn
 
 V pozdějších letech se původní standard dočkal vylepšení -- zvýšení šířky paralelní sběrnice z 32 bitů na 64 bitů a zrychlení z 33 MHz na 66 Mhz a výše. Tyto pokročilejší verze se však příliš neujaly.
 \subsection{Konektory}
-Pro spojení mezi kartou a sběrnicí je potřeba pouze konektor na straně sběrnice -- tzv. slot. V závislosti na napájecím napětí (3,3 V nebo 5 V) jsou na kartách klíčovací zářezy -- tyto zařezy znemoňují zasunutí \textit{napěťově} nekompatibilní karty do slotu. Jsou však karty, které mají tyto zářezy oba, díky čemuž může být karta použita v libovolném slotu (Obr. \ref{pci}).
+Pro spojení mezi kartou a sběrnicí je potřeba pouze konektor na straně sběrnice -- tzv. slot. V závislosti na napájecím napětí (3,3 V nebo 5 V) jsou na kartách klíčovací zářezy -- tyto zářezy znemožňují zasunutí \textit{napěťově} nekompatibilní karty do slotu. Jsou však karty, které mají tyto zářezy oba, díky čemuž může být karta použita v libovolném slotu (Obr. \ref{pci}).
 
 \begin{figure}[h!]
        \begin{center}
@@ -118,21 +118,21 @@ Pro spojení mezi kartou a sběrnicí je potřeba pouze konektor na straně sbě
 
 
 \subsection{Dynamická konfigurace a konfigurační adresní prostor}\label{pci_conf}
-Mezi hlavní výhody PCI sběrnice (oproti její předchůdkyni -- sběrnicic ISA) patří dynamická konfigurace připojených zařízení: Ve většině případů probíhá komunikace mezi hostitelským systémem a připojenou (a nakonfigurovanou) PCI kartou zápisem/čtením do určité paměťové (nebo vstupně-výstupní) oblasti. U starší sběrnice ISA si každá karta pevně určila, kam se její část paměti namapuje -- v takovém případě mohl nastat problém, že více než jedna karta mapovala svoji paměť na stejnou adresu (nebo se jednolivá mapování překrývala). PCI sběrnice tomuto problému předchází takovým způsobem, že každá z karet nese informaci o tom, kolik jak velkých paměťových nebo I/O regionů potřebuje namapovat -- o samotné mapování se poté postará PCI most.
+Mezi hlavní výhody PCI sběrnice (oproti její předchůdkyni -- sběrnici ISA) patří dynamická konfigurace připojených zařízení: Ve většině případů probíhá komunikace mezi hostitelským systémem a připojenou (a nakonfigurovanou) PCI kartou zápisem/čtením do určité paměťové (nebo vstupně-výstupní) oblasti. U starší sběrnice ISA si každá karta pevně určila, kam se její část paměti namapuje -- v takovém případě mohl nastat problém, že více než jedna karta mapovala svoji paměť na stejnou adresu (nebo se jednotlivá mapování překrývala). PCI sběrnice tomuto problému předchází takovým způsobem, že každá z karet nese informaci o tom, kolik jak velkých paměťových nebo I/O regionů potřebuje namapovat -- o samotné mapování se poté postará PCI most.
 
-Informaci o tom, kolik (a jaké) paměti karta bude potřebovat má před nakonfigurováním uloženu v tzv. \textbf{Base Address Registrech} -- BAR0--BAR5\footnote{FIXME Ve skutečnosti funguje vyčtení požadované velikosti z registru karty PCI mostem takovým způsobem, že se PCI most snaží do každého BAR registru zapsat 0xFF a poté zapsanou hodnotu přečíst -- do BAR registru je možné zapsat pouze .... bla bla}. Poté co se PCI mostu podaří tuto hodnotu přečíst a požadovanou paměť alokovat, zapíše zpět do daného registru adresu, na které se alokovaná paměť nachází. Tu si poté pro potřeby komunikace vyčteovladač zařízení, který je součástí opračního systému.
+Informaci o tom, kolik (a jaké) paměti karta bude potřebovat má před nakonfigurováním uloženu v tzv. \textbf{Base Address Registrech} -- BAR0--BAR5\footnote{FIXME Ve skutečnosti funguje vyčtení požadované velikosti z registru karty PCI mostem takovým způsobem, že se PCI most snaží do každého BAR registru zapsat 0xFF a poté zapsanou hodnotu přečíst -- do BAR registru je možné zapsat pouze .... bla bla}. Poté co se PCI mostu podaří tuto hodnotu přečíst a požadovanou paměť alokovat, zapíše zpět do daného registru adresu, na které se alokovaná paměť nachází. Tu si poté pro potřeby komunikace vyčte ovladač zařízení, který je součástí operačního systému.
 
 
-Kromě výše zmíněných 6 BAR registrů, obsahují PCI zařízení i následujícíc registry:
+Kromě výše zmíněných 6 BAR registrů, obsahují PCI zařízení i následující registry:
 \begin{description}
 \item[Vendor ID]~\\Obsahuje unikátní 16bitové číslo identifikující výrobce zařízení. Za poplatek je udělováno PCI-SIG (\textit{PCI Special Interest Group}) organizací.\footnote{V Debianu, po nainstalování balíčku \texttt{hwdata}, se seznam těchto identifikátorů nachází v souboru \texttt{/usr/share/hwdata/pci.ids}}
 \item[Device ID]~\\Obsahuje 16bitové číslo identifikující model zařízení. Hodnotu tohoto identifikátoru si volí sám výrobce zařízení.
-\item[Class code]~\\Označuje druh zařízení -- zda se jedná např. o grafickou kartu, zvukovou kartu nebo kartu zpracovávající signál.
-\item[Subsystem Vendor ID] -- Podobá se \texttt{Vendor ID}. V případě, že karta využívá PCI řadič třetí strany, jako \texttt{Vendor ID} se zobrazí ID výrobce tohoto řadiče. Aby bylo možné zařízení odlišit od jiného, které využívá stejný řadič, skutečné ID zařízení bude uloženo v tomot registru.
-\item[Subsystem ID]~\\Opět se jedná o údaj podobný \texttt{Device ID} sloužící k rolišení karet postavených na univerzálním řadiči.
+\item[Class code]~\\Označuje (ve 24 bitech) druh zařízení -- zda se jedná např. o grafickou kartu, zvukovou kartu nebo kartu zpracovávající signál.
+\item[Subsystem Vendor ID] -- Podobá se \texttt{Vendor ID}. V případě, že karta využívá PCI řadič třetí strany, jako \texttt{Vendor ID} se zobrazí ID výrobce tohoto řadiče. Aby bylo možné zařízení odlišit od jiného, které využívá stejný řadič, skutečné ID zařízení bude uloženo v tomto registru.
+\item[Subsystem ID]~\\Opět se jedná o údaj podobný \texttt{Device ID} sloužící k rozlišení karet postavených na univerzálním řadiči.
 \end{description}
 
-Registry \texttt{Vendor ID}, \texttt{Device ID} (pÅ\99íp. jeÅ¡tÄ\9b \texttt{Subsystem Vendor ID} a \texttt{Subsystem ID}) slouží operaÄ\8dnímu systému k jednoznaÄ\8dné identifikaci zažízení, při volbě správného ovladače.
+Registry \texttt{Vendor ID}, \texttt{Device ID} (pÅ\99íp. jeÅ¡tÄ\9b \texttt{Subsystem Vendor ID} a \texttt{Subsystem ID}) slouží operaÄ\8dnímu systému k jednoznaÄ\8dné identifikaci zaÅ\99ízení, při volbě správného ovladače.
 
 
 \begin{figure}[h!]
@@ -145,13 +145,14 @@ Registry \texttt{Vendor ID}, \texttt{Device ID} (příp. ještě \texttt{Subsyst
 
 Výše popsané registry (spolu s ostatními, které zde nebyly popsány) se nacházejí v 256bitovém tzv. \textbf{konfiguračním adresním prostoru} karty\footnote{Po paměťovém a vstupně-výstupním adresním prostoru je zde třetí -- konfigurační -- adresní prostor.}. Přístup do konfiguračního adresního prostoru je na architektuře IA-32 možný pomocí zapsání adresy (\textit{kam chceme v konfiguračním prostoru zapisovat}) a dat (\textit{která chceme do konfiguračního prostoru zapsat}) do dvou speciálních I/O portů, které jsou pro tuto operaci vyhrazeny.
 
+
 \subsection{Přerušení}
 Sběrnice PCI obsahuje čtyři linky přerušení a všechny z nich jsou dostupné každému zařízení. Přerušení mohou být sdílená, tudíž o jedno přerušení se může dělit více zařízení. Pro snazší sdílení přerušení jsou úrovňově spouštěná (oproti hranovému spouštění nedochází k promeškání přerušení).
 
 V pozdějších revizích PCI specifikací je přidána podpora pro přerušení signalizované zprávou. V tomto případě zařízení oznamuje svůj požadavek na obsloužení zápisem do paměti PCI mostu -- ten poté tento požadavak směruje dále k procesoru.
 
 \subsection{Budoucnost}
-V posledních letech je na poli osobních počítačů PCI sběrnice nahrazována její nástupkyní -- sběrnicí PCIe (PCI Express). Ta je narozdíl od PCI seriová a dosahuje rychlostí až 16 GB/s. I přesto je sběrnice PCI stále využívána mnohými zařízeními -- převážně v průmyslu.
+V posledních letech je na poli osobních počítačů PCI sběrnice nahrazována její nástupkyní -- sběrnicí PCIe (PCI Express). Ta je na rozdíl od PCI sériová a dosahuje rychlostí až 16 GB/s. I přesto je sběrnice PCI stále využívána mnohými zařízeními -- převážně v průmyslu.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Humusoft MF624}
 \begin{figure}[h!]
@@ -241,7 +242,7 @@ Z tabulky \ref{tab_bar} lze vyčíst informaci, že registry ovládající digit
 Na devátém řádku jsou zmíněny \texttt{DIN} (Digital input) a \texttt{DOUT} (Digital output) registry. Z této tabulky je patrná pozice těchto registrů v paměťovém prostoru (t.j. offset v bytech vůči adrese BAR1).
 
 Jak jsou data v registrech reprezentována, je možné si přečíst (v oficiálním manuálu) na straně 16, kde jsou tyto dva registry podrobně popsány (zde tabulka \ref{tab_din} a \ref{tab_dout}). 
-První sloupec určuje, kterých bitů se daný řádek týká. V druhém sloupci je informace o funkci. Třetí sloupec udává výchozí hodnotu. Z toho, co je v tabulkách uvedeno, plyne, že pro čtení 8bitového digitálního vstupu stačí přečíst spodních 8 bitů DIN registru, horních 8 bitů je potřeba ignorovat. Stejně tak pro nastavení 8bitového digitálního výstupu se zapíše požadovaná hodnota do spodních 8bitů registru DOUT, horních 8 bitů je potřeba ignorovat.
+První sloupec určuje, kterých bitů se daný řádek týká. V druhém sloupci je informace o funkci. Třetí sloupec udává výchozí hodnotu. Z toho, co je v tabulkách uvedeno, plyne, že pro čtení 8bitového digitálního vstupu stačí přečíst spodních 8 bitů DIN registru, horních 8 bitů je potřeba ignorovat. Stejně tak pro nastavení 8bitového digitálního výstupu se zapíše požadovaná hodnota do spodních 8 bitů registru DOUT, horních 8 bitů je potřeba ignorovat.
 
 \begin{table}[h!]
        \begin{center}
@@ -278,7 +279,7 @@ Karta MF624 obsahuje osm 14bitových A/D převodníků s pevně stanoveným rozs
 Každý z A/D převodníků je reprezentován jedním bitem. Zápisem 1 do daného bitu se nastaví, že bude daný A/D převodník aktivní -- 0 ho deaktivuje. Je možné zvolit více než jeden A/D převodník.
 \item Čtením registru ADSTART se spustí převod na zvolených A/D převod\-nících. Přečtená hodnota se dále nepoužívá.
 \item V případě, že se provedl převod na všech zvolených A/D převodnících, je EOLC bit (17. bit) GPIOC registru nastaven na 0 (jinak je v 1).
-\item Výslednou hodnotu je možné přečíst z registru ADDATA, který je typu FIFO. To znamná, že opětovným čtením jednoho registru jsou vyčítány jednotlivé naměřené hodnoty z měřených A/D převodníků v pořádí od 0 do 7.
+\item Výslednou hodnotu je možné přečíst z registru ADDATA, který je typu FIFO. To znamená, že opětovným čtením jednoho registru jsou vyčítány jednotlivé naměřené hodnoty z měřených A/D převodníků v pořadí od 0 do 7.
 
 Jinou možností je místo čtení registru ADDATA číst některý z jeho \textit{zrcadlených registrů} (celkem je jich 7, v manuálu jsou označeny jako \textit{BADR1 + 0x02} až \textit{BADR1 + 0x0E}). Tyto registry se chovají \textbf{zcela stejně} jako registr ADDATA, pouze leží na jiných adresách. Příklad: pokud byly aktivovány první čtyři A/D převodníky, po převodu je možné výslednou hodnotu vyčíst opakovaným čtením registru ADDATA nebo čtením registru ADDATA, ADDATA1, ADDATA2, ADDATA3 přesně v tomto pořadí. Čtení z registrů v jiném pořadí bude stále vracet hodnoty převodníků 0--4.
 \end{itemize}
@@ -304,7 +305,7 @@ Hodnota vyčtená z A/D převodníků je ve formátu dvojkového doplňku -- př
 \subsection{D/A převodníky}
 Karta MF624 obsahuje také osm 14bitových D/A převodníků s rozsahem $\pm$10 V.
 
-Nastavení výstupních hodnot D/A převodníků může probíhat následujícícm způsobem:
+Nastavení výstupních hodnot D/A převodníků může probíhat následujícím způsobem:
 
 \begin{itemize}
 \item Hodnota v aditivním kódu (tabulka \ref{tab_daval}) se zapíše do jednoho z osmi registrů DA0--DA7 odpovídajícího D/A převodníku, který má být nastaven.
@@ -339,7 +340,7 @@ Nastavení výstupních hodnot D/A převodníků může probíhat následující
        \end{center}
 \end{figure}
 
-Karta Humusoft MF614 má podobné funkce a využití jako karta MF624. Ve skutečnosti se jedná o jeji předchůdkyni. 
+Karta Humusoft MF614 má podobné funkce a využití jako karta MF624. Ve skutečnosti se jedná o její předchůdkyni. 
 
 Karta disponuje následujícími funkcemi:
 
@@ -398,7 +399,7 @@ Po nahlédnutí do manuálu (dostupný ze stránek výrobce: \url{http://www2.hu
        \hline BADR2 + 0x10 & \textbf{STATUS} -- Status register & \\   
        \hline 
        \end{tabular} 
-       \caption{Registry karty MF614 názežící digitálním vstupům/výstupům a analogovým vstupům/výstupům}
+       \caption{Registry karty MF614 náležící digitálním vstupům/výstupům a analogovým vstupům/výstupům}
        \label{tab_mf614_regs}
        \end{center}
 \end{table}
@@ -412,7 +413,7 @@ Jednotlivé registry v těchto regionech jsou 8bitové, proto je potřeba při 
 \end{verbatim}
 
 \subsection{Digitální vstupy a výstupy}
-Pro nastavení hodnoty digitálních výstupů se zapíše požadovaná hodnota do registru DOUT, kde jeden bit odpovídá jednomu digitálnímu výstupu. Pro čtení ditigálních vstupů je potřeba přečíst registr DIN.
+Pro nastavení hodnoty digitálních výstupů se zapíše požadovaná hodnota do registru DOUT, kde jeden bit odpovídá jednomu digitálnímu výstupu. Pro čtení digitálních vstupů je potřeba přečíst registr DIN.
 
 \subsection{A/D převodníky}
 Čtení A/D převodníků je u karty MF614 oproti MF624 trochu složitější, hlavně díky tomu, že je u převodníků potřeba nastavit, v jakém rozsahu bude provedeno měření. Je možné vybírat mezi rozsahy -10--10 V, -5--5 V, 0--10 V, 0--5 V. 
@@ -507,10 +508,69 @@ Hodnota je zapsána v aditivním kódu (tab. \ref{tab_mf614_dac}).
 Jako cílový operační systém, na kterém bude vysvětlena implementace základních ovladačů, byl zvolen GNU/Linux\footnote{Operační systém sestávající z GNU nástrojů a jádra Linux je označován jako GNU/Linux.}. Hlavním důvodem je dostupnost zdrojových kódů, velké množství kvalitní dokumentace, rozšířenost a vysoká kvalita. Distribucí použitou při vývoji je Debian GNU/Linux (verze jádra Linux 2.6.35) -- popsané postupy by však měly fungovat i pro jiné distribuce.
 
 \subsection{Práce s PCI zařízeními z uživatelského prostoru}
-FIXME popsat lspci (parametry a příklady) a /sys/bus/pci
+Pro výpis všech zařízení v systému připojených pomocí sběrnice PCI slouží program \texttt{lspci}.
+Po jeho spuštění bez udání parametrů bude vypsán základní seznam PCI zařízení. 
+
+Mezi důležité parametry, použitelné při spuštění programu, patří:
+\begin{description}
+\item[\texttt{-t}] Zobrazí diagram znázorňující jednotlivé PCI sběrnice a mosty.
+\item[\texttt{-v}, \texttt{-vv}, \texttt{-vvv}]
+ Umožňuje vypisování podrobných informací o zařízeních. (Postupně od \textit{střední podrobnosti} k \textit{vysoké podrobnosti}).
+\item[\texttt{-nn}] Zobrazí Vendor ID a Device ID v číselné a zároveň i textové podobě
+\item[\texttt{-d [<vendor>]:[<device>]}] Zobrazí informace pouze o zařízeních odpovídajících Vendor ID, případně i Device ID
+\end{description}
+
+Příklad, jak takový výpis může vypadat:
+\begin{verbatim}
+$ lspci -nn -d 186c:0624 -vvv
+01:0b.0 Signal processing controller [1180]: Humusoft, s.r.o. MF624 
+             Multifunction I/O Card [186c:0624]
+        Subsystem: Humusoft, s.r.o. MF624 Multifunction I/O Card [186c:0624]
+        Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- 
+             Stepping- SERR- FastB2B- DisINTx-
+        Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- 
+             <MAbort- >SERR- <PERR- INTx-
+        Interrupt: pin A routed to IRQ 22
+        Region 0: Memory at d2dffc00 (32-bit, non-prefetchable) [size=128]
+        Region 1: I/O ports at b800 [size=128]
+        Region 2: Memory at d2dff800 (32-bit, non-prefetchable) [size=128]
+        Region 4: Memory at d2dff400 (32-bit, non-prefetchable) [size=128]
+        Kernel driver in use: mf624
+\end{verbatim}
+
+
+Jinou možností, jak zjistit informace o PCI zařízení, je nahlédnutí do souborového systému \textit{sysfs}, kde jsou pro jednotlivá zařízení (nejen na PCI sběrnici) soubory\footnote{Tyto soubory ve skutečnosti nejsou uloženy nikde na disku, ale jsou dynamicky vytvářeny operačním systémem.}, které obsahují informace o zařízeních.
+
+\ibox{Fyzická adresa PCI zařízení je tvořena adresou \textit{sběrnice}, adresou \textit{zařízení} a adresou \textit{logického zařízení}. PCI specifikace umožňuje, aby jeden systém obsahoval až 256 sběrnic. Každá sběrnice může obsahovat až 32 zařízení. Jedno fyzické zařízení může obsahovat až 8 logických.}
+
+Informace o PCI zařízeních se nacházejí ve složce \texttt{/sys/bus/pci/devices/} -- jednotlivá zařízení jsou reprezentována podsložkou, jejíž název je tvořen fyzickou adresou PCI zařízení. Mezi nejdůležitější soubory, které tato podsložka obsahuje patří:
+
+\begin{description}
+\item[\texttt{vendor}] -- Obsahuje Vendor ID zařízení.
+\item[\texttt{device}] -- Obsahuje Device ID zařízení.
+\item[\texttt{class}] -- Obsahuje 24bitový identifikátor třídy zařízení.
+\item[\texttt{subsystem\_vendor}] -- Obsahuje Subsystem Vendor ID.
+\item[\texttt{subsystem\_device}] -- Obsahuje Subsystem ID.
+\item[\texttt{resource}] -- Soubor obsahuje popis jednotlivých regionů (reprezentovaných BAR registry) využívaných zařízením.
+\end{description}
+
+Struktura souboru \texttt{resource} může vypadat následovně:
+\begin{verbatim}
+0x00000000d2dffc00 0x00000000d2dffc7f 0x0000000000020200
+0x000000000000b800 0x000000000000b87f 0x0000000000020101
+0x00000000d2dff800 0x00000000d2dff87f 0x0000000000020200
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+0x00000000d2dff400 0x00000000d2dff47f 0x0000000000020200
+0x0000000000000000 0x0000000000000000 0x0000000000000000
+\end{verbatim}
+
+První sloupec označuje adresu začátku regionu, druhý jeho konec. Třetí sloupec obsahuje příznaky daného regionu. Díky nim je možné zjistit, zda se např. jedná o paměťový nebo I/O region. Tyto příznaky jsou popsány v souboru \texttt{include/linux/ioport.h} (ve zdrojových souborech jádra Linux). 
+
+
+
 
 \subsection{Základní jaderný modul}
-Jádro operačního systému GNU/Linux je monolitické -- to znamená, že po zkompilování a slinkvání je tvořeno jedním kusem kódu. Tento druh jádra je léty prověřen a mezi výhody patří jeho snadná implementace. Aby běžící jádro nemuselo obsahovat veškeré dostupné ovladače zařízení (nebo abychom v případě potřeby přidat do jádra ovladač pro nový hardware nemuseli celé jádro znovu kompilovat), existuje mechanismus načítání jaderných modulů za běhu, tzv. LKM -- Loadable Kernel Module. V praxi to vypadá tak, že jsou v běžícím jádře zakompilovány pouze nejnutnější ovladače, všechny ostatní si může systém nebo uživatel za běhu do jádra načíst -- v případě, že již nejsou potřeba, je možné je z jádra uvolnit.
+Jádro operačního systému GNU/Linux je monolitické -- to znamená, že po zkompilování a slinkování je tvořeno jedním kusem kódu. Tento druh jádra je léty prověřen a mezi výhody patří jeho snadná implementace. Aby běžící jádro nemuselo obsahovat veškeré dostupné ovladače zařízení (nebo abychom v případě potřeby přidat do jádra ovladač pro nový hardware nemuseli celé jádro znovu kompilovat), existuje mechanismus načítání jaderných modulů za běhu, tzv. LKM -- Loadable Kernel Module. V praxi to vypadá tak, že jsou v běžícím jádře zakompilovány pouze nejnutnější ovladače, všechny ostatní si může systém nebo uživatel za běhu do jádra načíst -- v případě, že již nejsou potřeba, je možné je z jádra uvolnit.
 
 Jak se takový jaderný modul může vypadat, je nejlepší si ukázat na příkladu:
 \begin{verbatim}
@@ -534,19 +594,19 @@ Jak se takový jaderný modul může vypadat, je nejlepší si ukázat na přík
 18 |  MODULE_LICENSE("Dual BSD/GPL");
 \end{verbatim}
 
-První věc, na kterou je potřeba upozornit je, že většina jaderných modulů (stejně jako zdrojových kódů jádra samotného) je psána v programovacím jazyce C (jedná se o mírně modifikovaný standard C90).
+Z příkladu je patrné, že je modul napsán v programovacím jazyce C. To platí pro většinu všech jaderných modulů (stejně jako zdrojových kódů jádra samotného). Ve skutečnosti se jedná o mírně modifikovaný standard C90.
 \begin{description}
 \item[Řádky 1 a 2] obsahují vložení hlavičkových souborů -- obsahují prototypy volaných funkcí a jsou nutné pro tvorbu jaderného modulu.
 \item[Na řádcích 4--8] je funkce, která bude spuštěna ihned po zavedení našeho modulu do jádra. Ta obsahuje pouze volání funkce \texttt{printk()}.
 
-Pro jednoduchost můžeme s funkcí \texttt{printk()} pracovat jako s, pro čtenáře známou, funkcí \texttt{printf()} -- narozdíl od standardního výstupu se však text vypsaný funkcí \texttt{printk()} zapíše do \textit{logu} jádra. Jedním ze způsobů, jak ho zobrazit je pomocí programu \texttt{dmesg}.\\Jak se zařídí, že se tato funkce vykoná ihned po zavedení modulu do jádra? O to se postará příkaz na $\rightarrow$
+Pro jednoduchost můžeme s funkcí \texttt{printk()} pracovat jako s, pro čtenáře známou, funkcí \texttt{printf()} -- na rozdíl od standardního výstupu se však text vypsaný funkcí \texttt{printk()} zapíše do \textit{logu} jádra. Jedním ze způsobů, jak ho zobrazit je pomocí programu \texttt{dmesg}.\\Jak se zařídí, že se tato funkce vykoná ihned po zavedení modulu do jádra? O to se postará příkaz na $\rightarrow$
 \item[řádku 15] -- ten obsahuje makro \texttt{module\_init()}, kterému řekneme právě to, která funkce se má po načtení spustit.
 \item[Řádek 16] obsahuje naopak makro, které udává, která funkce se má zavolat v případě, že se bude modul uvolňovat z jádra. V našem případě je to funkce na $\rightarrow$
 \item[řádcích 10--13.] Tato funkce nemá na starost nic jiného než výpis krátkého textu do logu jádra.
 \end{description}
 
 \subsection{Kompilace modulu}
-Dále je potřeba jaderný modul přeložit\footnote{Před samotným překladem jádra je potřeba mít k dispozici zdrojové kódy jádra. Ty buď stáhneme přímo z \texttt{kernel.org} nebo v distribuci Debian nainstalujeme pomocí příkazu\\\texttt{apt-get install ... FIXME}}. K tomu poslouží následující \texttt{Makefile}:
+Dále je potřeba jaderný modul přeložit\footnote{Před samotným překladem jádra je potřeba mít k dispozici zdrojové kódy jádra. Ty je možné stáhnout z \texttt{kernel.org} nebo v distribuci Debian nainstalovat pomocí příkazu \texttt{apt-get install linux-source}}. K tomu poslouží následující \texttt{Makefile}:
 \begin{verbatim}
 1 |  KERNEL_VER=`uname -r`
 2 |  obj-m += hello.o
@@ -561,7 +621,7 @@ Linux využívá při kompilaci systému \texttt{KBUILD}. Ten je tvořen množst
 \begin{description}
 \item[Na prvním řádku] se do proměnné \texttt{KERNEL\_VER} přiřadí verze aktuálně běžícího jádra (po zavolání příkazu \texttt{uname -r}, který tuto informaci vrací)
 \item[Druhý řádek] říká, že modul bude vytvářen ze zdrojového souboru \texttt{hello.c} (pod tímto názvem jsme uložili náš ukázkový modul)
-\item[Na pátém řádku] (uvozeném tabelátorem) se volá (pomocí přepínače \texttt{-C}) Makefile ze systému \texttt{KBUILD}, který se nachází v adresáří spolu se zdrojovými kódy jádra. Parametrem \texttt{M} říkáme, které moduly si přejeme vytvořit -- v tomto případě jsou to ty, jejichž zdrojové soubory jsou v aktuálním adresáři (tj. \texttt{PWD}).
+\item[Na pátém řádku] (uvozeném tabelátorem) se volá (pomocí přepínače \texttt{-C}) Makefile ze systému \texttt{KBUILD}, který se nachází v adresáři spolu se zdrojovými kódy jádra. Parametrem \texttt{M} říkáme, které moduly si přejeme vytvořit -- v tomto případě jsou to ty, jejichž zdrojové soubory jsou v aktuálním adresáři (tj. \texttt{PWD}).
 \end{description}
 
 V případě, že v adresáři, ve kterém se nachází zdrojový soubor modulu \texttt{hello.c} a výše popsaný soubor \texttt{Makefile}, spustí příkaz \texttt{make}, měl by proběhnout samotný překlad:
@@ -576,7 +636,7 @@ make[1]: Entering directory `/usr/src/linux-headers-2.6.35-28-generic'
   LD [M]  /tmp/hello.ko
 make[1]: Leaving directory `/usr/src/linux-headers-2.6.35-28-generic'
 \end{verbatim}
-A v aktuálním adresáři se nachází kromě různých souborů, které vzniky při překladu, i potřebný \texttt{hello.ko}
+V aktuálním adresáři by se měl nacházet kromě různých souborů, které vzniky při překladu, i potřebný \texttt{hello.ko} -- t.j. zkompilovaný jaderný modul připravený na zavedení do jádra.
 
 \begin{verbatim}
 $ ls
@@ -614,22 +674,59 @@ Při psaní základního modulu pro jádro Linux nejsou patrné větší rozdíl
 
 \begin{description}
 \item[Žádná ochrana paměti]~\\Libovolný jaderný modul má přístup k veškeré paměti počítače. V případě, že se chybně pokusí zapsat do paměti, do které by zapisovat neměl, není zde žádný mechanismus, který by mu v tom zabránil nebo ho na to alespoň upozornil.
-\item[Uvolňování paměti]~\\Stejně jako pro programy psané v uživatelském prostoru platí, že nepotřebná dynamicky alokovaná paměť by měla být dealokována. V případě neuvolňování paměti programem v uživatelském prostoru je zde stále operační systém, který po skončení programu veškerou paměť uvolní. Nic takového však v jádře operačního systému nefunguje -- po uvolnění modulu z jádra není nikdo, kdo by se postaral o naalokovanou paměť. FIXME
+\item[Uvolňování paměti]~\\Stejně jako pro programy psané v uživatelském prostoru platí, že nepotřebná dynamicky alokovaná paměť by měla být dealokována. V případě neuvolňování paměti programem v uživatelském prostoru je zde stále operační systém, který po skončení programu veškerou paměť uvolní. Nic takového však v jádře operačního systému nefunguje -- po uvolnění modulu z jádra není nic, co by se postaralo o alokovanou.
 \item[Přímý přístup k hardwaru]~\\Základní jaderný modul psaný například nezkušeným studentem má zcela stejné možnosti přístupu k hardware jako subsystémy jádra, které se starají o správnou funkci jednotlivých ovladačů. V lepším případě může špatný ovladač způsobit pád systému, v horším např. zničení dat na disku nebo dokonce zničení hardware\footnote{Například velmi těžko opravitelné poškození firmware síťových karet Intel e1000e: \\ \url{http://www.abclinuxu.cz/clanky/jaderne-noviny/jaderne-noviny-22.-10.-2008\#pricina-chyby-poskozujici-e1000e}}.
-\item[Globální proměnné]~\\Každý ovladač může být spuštěn ve více instancích, proto by v kódu neměly být globální proměnné. Proměnné, které je potřeba zpřístupnit z více míst ovladače se vloží do jedné struktury, která je poté přístupná skrze ukazatel na \textit{privátní data} ovladače. FIXME.
+\item[Globální proměnné]~\\Každý ovladač může být spuštěn ve více instancích, proto by v kódu neměly být globální proměnné. Proměnné, které je potřeba zpřístupnit z více míst ovladače se vloží do jedné struktury, která je poté přístupná skrze ukazatel na \textit{privátní data} ovladače. Struktura reprezentující daný ovladače většinou obsahuje ukazatel s názvem \texttt{private} nebo \texttt{priv}, který slouží k tomuto účelu.
+
+V případě ukončení funkce ovladače musí být tato paměť uvolněna.
 \end{description}
 
 \subsection{Příkaz GOTO}
-Obecně je doporučováno příkaz \texttt{goto} nepoužívat. Najdou se ale případy, kdy jeho použití usnadní práci a i přesto neznepřehlední kód. V jádře Linux se tento příkaz používá při postupné dealokace. FIXME
+Obecně je doporučováno příkaz \texttt{goto} nepoužívat. Najdou se ale případy, kdy jeho použití usnadní práci a i přesto neznepřehlední kód. V jádře Linux se tento příkaz používá při postupném uvolňování zdrojů zařízení.
+
+Příklad pro lepší názornost:
+\begin{verbatim}
+ 1 |  int mf614_attach(...)
+ 2 |  {
+ 3 |      if(pci_enable_device(devpriv->pci_dev))
+ 4 |          goto out_exit;
+ 5 |  
+ 6 |      if(pci_request_regions(devpriv->pci_dev, "mf614"))
+ 7 |          goto out_disable;
+ 8 |  
+ 9 |      if (!pci_iomap(devpriv->pci_dev, 0, 0))
+10 |          goto out_release;
+11 |   
+12 |  out_release:
+13 |      pci_release_regions(devpriv->pci_dev);
+14 |  out_disable:
+15 |      pci_disable_device(devpriv->pci_dev);
+16 |  out_exit:
+17 |      return -ENODEV;
+18 |  }
+\end{verbatim}
+
+Na řádcích 3, 6 a 9 jsou volány funkce, které mají za následek alokaci zdrojů zařízení. Po skončení funkce ovladače je potřeba zavolat jiné funkce, které tyto zdroje uvolní.
+
+V případě, že by volání na řádku 6 skončilo neúspěchem, musela by být zavolána funkce \texttt{pci\_disable\_device()}, která deaktivuje zařízení (aktivované příkazem na řádku 3). V případě, že by poslední volání proběhlo neúspěšně, musela by být zavolána jak funkce \texttt{pci\_disable\_device()}, tak funkce \texttt{pci\_release\_regions()} -- to způsobuje duplikaci kódu, která vede k nepřehlednosti a může způsobovat chyby (v případě, že se omylem změní volání funkce pouze na jednom místě).
+
+Za pomoci volání \texttt{goto} je výše popsaný problém elegantně vyřešen.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Základní funkce v prostředí jádra Linux}
+\subsection{Funkce \texttt{printk()}}
+FIXME
+\subsection{Funkce \texttt{kalloc()}}
+\subsection{Funkce \texttt{kfree()}}
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Ovladače PCI zařízení}\label{pci_driv}
 \ibox{Jako nejlepší reference jednotlivých funkcí slouží zdrojové kódy jádra. Pro prohlížení zdrojových kódů jádra mohu doporučit online \textit{The Linux Cross Reference} -- \\
 \url{http://lxr.linux.no/linux/}.}
 
-Ovladače PCI zařízení jsou ve většině případů kompilovány jako jaderné moduly, dynmicky načítané za běhu jádra. Takový modul je možné buď načíst ručně, pomocí příkazu \texttt{insmod} (se zadanou absolutní cestou) nebo, nachází-li se v adresáři \texttt{/lib/modules/\$(uname -r)/} a je součástí seznamu \texttt{modules.dep}\footnote{Tento seznam je aktualizován pomocí příkazu \texttt{depmod}.} (v témže adresáři), je možné ho načíst pomocí příkazu \texttt{modprobe} (kde se jako parametr předá pouze název modulu bez koncovky \texttt{.ko}). Druhá varianta se týká všech ovladačů standardně zkompilovaných s jádrem.
+Ovladače PCI zařízení jsou ve většině případů kompilovány jako jaderné moduly, dynamicky načítané za běhu jádra. Takový modul je možné buď načíst ručně, pomocí příkazu \texttt{insmod} (se zadanou absolutní cestou) nebo, nachází-li se v adresáři \texttt{/lib/modules/\$(uname -r)/} a je součástí seznamu \texttt{modules.dep}\footnote{Tento seznam je aktualizován pomocí příkazu \texttt{depmod}.} (v témže adresáři), je možné ho načíst pomocí příkazu \texttt{modprobe} (kde se jako parametr předá pouze název modulu bez koncovky \texttt{.ko}). Druhá varianta se týká všech ovladačů standardně zkompilovaných s jádrem.
 
-V případě, že se v systému objeví nové PCI zařízení, je jádrem informován subsystém v uživatelském prostoru, který má na starosti správu \textit{hotplug} zařízení (např. \textit{udev}), o tomto zařízení. Hotplug subsystém (v uživatelském prosotru) poté na základě informací od jádra, jako je Vendor ID a Device ID , rozhodne, který ovladač má být pro dané zařízení načten. Seznam, dle kterého se rozhodne, který ovladač bude načten je v souboru \texttt{/lib/modules/\$(uname -r)/modules.pcimap}.
+V případě, že se v systému objeví nové PCI zařízení, je jádrem informován subsystém v uživatelském prostoru, který má na starosti správu \textit{hotplug} zařízení (např. \textit{udev}), o tomto zařízení. Hotplug subsystém (v uživatelském prostoru) poté na základě informací od jádra, jako je Vendor ID a Device ID , rozhodne, který ovladač má být pro dané zařízení načten. Seznam, dle kterého se rozhodne, který ovladač bude načten je v souboru \texttt{/lib/modules/\$(uname -r)/modules.pcimap}.
 
 Každý ovladač by měl tedy obsahovat informaci o tom, pro které zařízení je určen. To je uvedeno ve struktuře \texttt{struct pci\_device\_id}.
 
@@ -717,7 +814,7 @@ V případě, že je potřeba zjistit velikost daného paměťového nebo I/O re
 
 \ibox{\texttt{void \_\_iomem *pci\_ioremap\_bar(struct pci\_dev *pdev, int bar);}}
 
-S ukazatelem, který vrátí funkce \texttt{pci\_request\_regions()} však není možné přímo pracovat -- je to toiž \textbf{fyzická adresa} daného regionu, ke které neumí procesor přímo přistupovat. Aby tato fyzická adresa byla přemapována na adresu \textbf{virtuální}, je potřeba zavolat funkci \texttt{pci\_ioremap\_bar()}.
+S ukazatelem, který vrátí funkce \texttt{pci\_request\_regions()} však není možné přímo pracovat -- je to totiž \textbf{fyzická adresa} daného regionu, ke které neumí procesor přímo přistupovat. Aby tato fyzická adresa byla přemapována na adresu \textbf{virtuální}, je potřeba zavolat funkci \texttt{pci\_ioremap\_bar()}.
 
 K ukazateli, který vrátí volání \texttt{pci\_ioremap\_bar()} je již možné pomocí speciálních funkcí (popsány v kap. \ref{iofce}) přistupovat.
 
@@ -747,7 +844,7 @@ Stejně jako program v jazyku symbolických instrukcí využívá pro přístup
 
 \ibox{\texttt{unsigned inl(unsigned port);}}
 
-Třetí písmeno značí o \textit{kolikabitové} čtení se jedná: b = 8 b, w = 16 b, l = 32 b.
+Třetí písmeno značí o \textit{kolika-bitové} čtení se jedná: b = 8 b, w = 16 b, l = 32 b.
 
 Pro zápis je možné využít volání:
 \ibox{\texttt{void outb(unsigned char byte, unsigned port);}}
@@ -757,7 +854,7 @@ Pro zápis je možné využít volání:
 \ibox{\texttt{void outl(unsigned char byte, unsigned port);}}
 
 
-Třetí písmeno, stejně jako u funkcí pro čtení, značí o kolikabitový přístup se jedná.
+Třetí písmeno, stejně jako u funkcí pro čtení, značí o kolika-bitový přístup se jedná.
 
 Funkce se stejným \textit{prototypem} jsou k dispozici i v uživatelském prostoru (potřebný hlavičkový soubor je \texttt{<sys/io.h>}).
 
@@ -782,7 +879,7 @@ a pro zápis:
 
 \ibox{\texttt{void iowrite32(u32 value, void *addr);}}
 
-Číslo na konci funkce označuje o kolikabitový přístup se jedná.
+Číslo na konci funkce označuje o kolika-bitový přístup se jedná.
 
 V případě, že se na paměť ve vstupně-výstupním adresním prostoru zavolá funkce 
 \ibox{\texttt{void *ioport\_map(unsigned long port, unsigned int count);}} 
@@ -809,11 +906,11 @@ Příklad jak takové funkce mohou vypadat:
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{UIO ovladač}
-V případě, že je vytvářen ovladač pro linuxové jádro, mělo by být rozhodnuto, kterého subsystému se stane součástí -- např. zda jde o jednoduché znakové zařízení, síťovou kartu nebo zvukovou kartu. Tato volba uřčí, kterou sadu pomocných funkcí bude moci ovladač používat a jakým způsobem bude zpřístupněno zařízení do uživatelského prostoru.
+V případě, že je vytvářen ovladač pro linuxové jádro, mělo by být rozhodnuto, kterého subsystému se stane součástí -- např. zda jde o jednoduché znakové zařízení, síťovou kartu nebo zvukovou kartu. Tato volba určí, kterou sadu pomocných funkcí bude moci ovladač používat a jakým způsobem bude zpřístupněno zařízení do uživatelského prostoru.
 
 V případě, že jde o PCI zařízení, které nelze snadno zařadit do žádné kategorie (jedná-li se například o neobvyklou průmyslovou kartu), je možné vytvořit tzv. UIO (\textit{Userspace I/O}) ovladač. Tento ovladač se skládá ze dvou částí: jednoduchého jaderného modulu a aplikace v uživatelském prostoru. 
 
-Mezi jeho hlavní výhody patří to, že v jádře je obsažena pouze malá obecná část, která zpřístupňuje zdroje zařízení do uživatelského prostoru (její implementace je poměrně snadná). Druhou částí je aplikace v uživateském prostoru, která přistupuje k jednotlivým zdrojům karty a tvoří hlavní logiku ovladače. Většina vývoje tedy probíhá v uživatelském prostoru, čímž klesá riziko narušení stability jádra.
+Mezi jeho hlavní výhody patří to, že v jádře je obsažena pouze malá obecná část, která zpřístupňuje zdroje zařízení do uživatelského prostoru (její implementace je poměrně snadná). Druhou částí je aplikace v uživatelském prostoru, která přistupuje k jednotlivým zdrojům karty a tvoří hlavní logiku ovladače. Většina vývoje tedy probíhá v uživatelském prostoru, čímž klesá riziko narušení stability jádra.
 
 \subsection{Jaderný modul}
 Jaderný modul UIO ovladače PCI zařízení by měl obsahovat:
@@ -824,11 +921,12 @@ Jaderný modul UIO ovladače PCI zařízení by měl obsahovat:
 \item Funkce pro \textit{úklid} a uvolnění regionů karty
 \end{itemize}
 
-VÄ\9btÅ¡ina z tÄ\9bchto Ãºkonů již byla popsána v kapitole \ref{pci_driv} a jsou zcela standardní pro jakýkoliv ovladaÄ\8d PCI zažízení. Co nebylo dosud popsáno je pouze úkon \textit{registrace do UIO subsystému}.
+VÄ\9btÅ¡ina z tÄ\9bchto Ãºkonů již byla popsána v kapitole \ref{pci_driv} a jsou zcela standardní pro jakýkoliv ovladaÄ\8d PCI zaÅ\99ízení. Co nebylo dosud popsáno je pouze úkon \textit{registrace do UIO subsystému}.
 
 \ibox{\texttt{int uio\_register\_device(struct device *parent, struct uio\_info *info);}}
 
-Registrace UIO ovladače se provede zavoláním funkce \texttt{uio\_register\_device()}, které se jako první parametr předá \textit{rodič} FIXME struktury \texttt{struct pci\_dev} struktury -- tj. ukazatel na její položku \texttt{dev}. Druhý parametr předá ukazatel na strukturu \texttt{struct uio\_info}.
+Registrace UIO ovladače se provede zavoláním funkce \texttt{uio\_register\_device()}, které se jako první parametr předá ukazatel na \textit{rodiče} struktury \texttt{struct pci\_dev} -- tj. ukazatel na její položku \texttt{dev}. Důvod je ten, že ovladač typu UIO může být vytvořen i pro jiná zařízení než ta na sběrnici PCI.
+Druhý parametr předá ukazatel na strukturu \texttt{struct uio\_info}.
 
 \subsubsection{Struktura \texttt{struct uio\_info}}
 
@@ -842,7 +940,7 @@ Mezi její hlavní položky patří:
 \end{description}
 
 \subsubsection{Struktura \texttt{struct uio\_mem} a \texttt{struct uio\_port}}\label{uio_mem_port}
-Tyto struktury obsahují imformace o regionech zařízení. Které (a kolik) z těchto dvou struktur budou inicializovány záleží na tom, zda karta mapuje regiony do paměťového nebo vstupně-výstupního prostoru.
+Tyto struktury obsahují informace o regionech zařízení. Které (a kolik) z těchto dvou struktur budou inicializovány záleží na tom, zda karta mapuje regiony do paměťového nebo vstupně-výstupního prostoru.
 
 Struktura \texttt{struct uio\_mem} obsahuje položky:
 \begin{description}
@@ -915,7 +1013,7 @@ Poté, co je jaderná část UIO ovladače úspěšně zkompilována a zavedena
 \subsubsection{Obsah složky \texttt{/sys/class/uio/uio0}}
 Tato složka obsahuje soubory převážně pouze pro čtení. Obsahuje podsložku \texttt{maps}, ve které se nachází pro každý region PCI zařízení mapovaný do paměti (zpřístupněný jaderným ovladačem) složka obsahující soubory popisující tyto regiony (Soubor \texttt{addr} obsahuje fyzickou adresu regionu; \texttt{name} slovní pojmenování; \texttt{size} velikost regionu).
 
-V případě, že jsou zpřístupněny regiony rařízení, které jsou mapovány do vstupně-výstupního adresního prostoru, nacházejí se jednotlivé podsložky a soubory popisující regiony ve složce \texttt{portio}.
+V případě, že jsou zpřístupněny regiony zařízení, které jsou mapovány do vstupně-výstupního adresního prostoru, nacházejí se jednotlivé podsložky a soubory popisující regiony ve složce \texttt{portio}.
 
 \subsubsection{Soubor \texttt{/dev/uio0}}
 Tento soubor tvoří rozhraní mezi jaderným subsystémem UIO a uživatelským prostorem. Skrze něj je přistupováno k regionům karty. K souboru se přistupuje pomocí volání \texttt{mmap()}.
@@ -930,7 +1028,7 @@ Tato funkce slouží k \textit{namapování} souboru nebo zařízení do operač
 \item[Parametr \texttt{prot}]~\\ Obsahuje příznaky definující, zda bude mapovaná paměť pro čtení/zápis, apod.
 \item[Parametr \texttt{flags}]~\\ Pomocí příznaku určuje, zda se mají změny zapisovat pouze do \textit{lokální kopie} (příznak \texttt{MAP\_PRIVATE}) nebo zda mají být zapisovány do původního souboru/zařízení (příznak \texttt{MAP\_SHARED}).
 \item[Parametr \texttt{fd}]~\\ Obsahuje \textit{filedescriptor} na zařízení, které má být namapováno (v tomto případě file\-desc\-riptor vrácený voláním \texttt{open("/dev/uio0", ... );}).
-\item[Parametr \texttt{offset}]~\\ Určuje, zda se zaný soubor/zařízení začne mapovat od posunuté adresy. V případě UIO ovladače je možné jako offset používat násobky velikosti paměťové stránky -- tento offset určí, který z regionů zpřístupněných jadernou částí ovladače má být namapován.
+\item[Parametr \texttt{offset}]~\\ Určuje, zda se daný soubor/zařízení začne mapovat od posunuté adresy. V případě UIO ovladače je možné jako offset používat násobky velikosti paměťové stránky -- tento offset určí, který z regionů zpřístupněných jadernou částí ovladače má být namapován.
 \end{description}
 
 Příklad, jak takové volání může vypadat (bez ošetření chybových stavů):
@@ -947,7 +1045,7 @@ Příklad, jak takové volání může vypadat (bez ošetření chybových stav
 
 S adresou vrácenou voláním \texttt{mmap()} však není možné vždy ihned pracovat. Může se stát, že mapovaný region PCI zařízení (reprezentovaný zařízením \texttt{/dev/uio0}, na které je \texttt{mmap()} volán) je menší než je velikost celé stránky, \texttt{mmap()} však vrací ukazatel zarovnaný na velikost stránky. Je tedy potřeba se v rámci této stránky posunout na tu část, která odpovídá požadovanému regionu.
 
-Jak velký je potÅ\99eba udÄ\9blat \textit{posun} pomůže zjistit soubor \texttt{/sys/class/uio/uio0/maps/map1/addr}\footnote{Pro názornost je uvedena konkrétní cesta -- jedná se tedy o \textit{druhý} pamÄ\9bÅ¥ový region zažízení \textit{uio0}.} -- ten obsahuje fyzickou adresu požadovaného regionu. Z té je možné následujícím trikem získat ukazatel, se kterým je již možné pracovat (nejnižší bity totiž budou zachovány z fyzické adresy):
+Jak velký je potÅ\99eba udÄ\9blat \textit{posun} pomůže zjistit soubor \texttt{/sys/class/uio/uio0/maps/map1/addr}\footnote{Pro názornost je uvedena konkrétní cesta -- jedná se tedy o \textit{druhý} pamÄ\9bÅ¥ový region zaÅ\99ízení \textit{uio0}.} -- ten obsahuje fyzickou adresu požadovaného regionu. Z té je možné následujícím trikem získat ukazatel, se kterým je již možné pracovat (nejnižší bity totiž budou zachovány z fyzické adresy):
 \begin{verbatim}
 mf624_BAR2 += (BAR2_phys_addr & (sysconf(_SC_PAGESIZE) - 1));
   |                \-- Fyzická adresa
@@ -990,11 +1088,11 @@ Položky struktury jsou:
 Narozdíl od předchozích příkladů je v tomto případě tou hlavní \textit{inicializační} funkcí nikoliv funkce \texttt{probe()} volaná PCI subsystémem v případě, že se v systému nachází hardware, který umí ovladač obsloužit, ale funkce \texttt{attach()}, která je volána Comedi subsystémem v závislosti na tom, zda má být ovladač použit nebo ne.
 
 \subsection{Funkce \texttt{attach}}
-Funkce \texttt{attach} je volána v případě aktivace Comedi ovladače. \texttt{struct comedi\_subdevice}. Dříve než dojde na popis incializačních kroků je nutné vysvětlit názvosloví, které je u Comedi ovladačů používáno.
+Funkce \texttt{attach} je volána v případě aktivace Comedi ovladače. Dříve než dojde na popis inicializačních kroků je nutné vysvětlit názvosloví, které je u Comedi ovladačů používáno.
 
 \begin{description}
 \item[Board] označuje konkrétní zařízení -- měřící kartu. Některé ovladače podporují celou sadu zařízení (např. od stejného výrobce).
-\item[Subdevice] je jedna z mnoha funkcí zařízení. V případě ovladače karty Humusoft MF614 budou implementovány 4 \textit{subdevices}: digitální vstupy, digitální výstupy, analogové vstupy, analogové výstupy.
+\item[Subdevice (\textit{podzažízení})] je jedna z mnoha funkcí zařízení. V případě ovladače karty Humusoft MF614 budou implementovány 4 podzařízení: digitální vstupy, digitální výstupy, analogové vstupy, analogové výstupy.
 \end{description}
 
 Kromě obvyklých operací, jako je \textit{aktivace zařízení}, žádos o \textit{výhradní přístup} ke zdrojům zařízení a \textit{mapování} paměťových nebo I/O regionů, popsaných v kapitole \ref{pci_driv}, je nutné alokovat a inicializovat struktury \texttt{struct comedi\_subdevice}.
@@ -1010,15 +1108,16 @@ Každé podporované funcki zařízení/karty by měla odpovídat jedna struktur
 
 \item[\texttt{int n\_chan}]~\\ Počet kanálů podzařízení (např. pro 8 digitálních vstupů bude tato hodnota 8).
 
-\item[\texttt{unsigned int maxdata}]~\\ Maximální hodnota, která může být do podzařízení zapsaána/čtena.
+\item[\texttt{unsigned int maxdata}]~\\ Maximální hodnota, která může být do podzařízení zapsána/čtena.
 \item[\texttt{const struct comedi\_lrange *range\_table}]~\\Označuje rozsah, ve kterém dané podzařízení měří (např. u A/D převodníku 0--10 V). K dispozici jsou definované struktury (staří pouze předat jejich ukazatel):\\
 \texttt{range\_digital},\\ \texttt{range\_bipolar10},\\ \texttt{range\_bipolar5},\\ \texttt{range\_unipolar10},\\ \texttt{range\_unipolar5}.\\ Jejich názvy jsou samovysvětlující.
 
-\item[\texttt{int (*insn\_read) ( ... );}]
-\item[\texttt{int (*insn\_write) ( ... );}]
-\item[\texttt{int (*insn\_bits) ( ... );}]
-\item[\texttt{int (*insn\_config) ( ... );}]
+\item[\texttt{int (*insn\_read) ( ... );}]~\\Ukazatel na funkci, která má na starosti čtení z podzařízení (většinou se používá pro A/D převodníky).
+\item[\texttt{int (*insn\_write) ( ... );}]~\\Ukazatel na funkci, která má na starosti zápis do zařízení (většinou se používá pro A/D převodníky).
+\item[\texttt{int (*insn\_bits) ( ... );}]~\\Ukazatel na funkci použitou pro zápis a čtení digitálních výstupů a vstupů,
+\item[\texttt{int (*insn\_config) ( ... );}]~\\Ukazatel na funkci, která má na starosti konfiguraci podazařízení.
+
+Poslední čtyři funkce mají parametry: \\ \texttt{(struct comedi\_device *, struct comedi\_subdevice *, struct comedi\_insn *, unsigned int *);}. První z nich je ukazatel na strukturu popisující Comedi ovladač. Druhý je ukazatelem na strukturu odpovídající podzařízení. Třetí obsahuje ukazatel na strukturu popisující \textit{instrukci}, která má být provedena. Poslední obsahuje ukazatel na proměnnou, ze které je vyčtena zapisovaná hodnota nebo je do ni čtená hodnota zapsána.
  
 \end{description}
 
@@ -1032,8 +1131,74 @@ V případě dealokace zdrojů ovladače není potřeba tuto paměť dealokovat
 
 \subsection{Funkce \texttt{detach}}
 
-\subsection{Konfigurace z uživatelského prostoru}
+\subsection{Přístup z uživatelského prostoru}
+Pro správnou funkci konkrétního Comedi ovladače je nejprve potřeba načíst modul Comedi (\texttt{modprobe comedi}). Poté je již možné načíst ovladač zařízení (v případě ručně kompilovaného ovladače, pomocí příkazu \texttt{insmod}, jinak opět pomocí \texttt{modprobe}).
+
+V případě, že proběhlo načtení modulu a spuštění funkce \textit{attach} bez problémů, měl by se ve složce \texttt{/dev} objevit nový soubor odpovídající načtenému ovladači zařízení -- comedi0\footnote{Pro názornost je uveden konkrétní příklad, v případě načtení více ovladačů budou odpovídající soubory číslovány od 0 výše.} K tomuto souboru je poté možné pomocí knihovních funkcí Comedilib přistupovat.
+
+Pro přístup k zařízení je potřeba zavolat na soubor \texttt{/dev/comedi0} funkci \texttt{comedi\_open()}. Ta vrací ukazatel datového typu \texttt{comedi\_t}, reprezentujícího dané zařízení. K němu je možné přistupovat pomocí funkcí\\
+\texttt{comedi\_data\_read()},\\
+\texttt{comedi\_data\_write()},\\
+\texttt{comedi\_dio\_read()},\\
+\texttt{comedi\_dio\_write()}.
+
+První dvě slouží pro zápis/čtení A/D a D/A převodníků, zatímco poslední dvě slouží pro přístup k digitálním vstupům/výstupům.
+Prvním parametrem všech funkcí je ukazatel na \texttt{comedi\_t}. Druhým je číslo \textit{podzařízení}. Třetí parametr určuje kanál (t.j. např. který z osmi A/D převodníků má být čten). Posledním parametrem je ukazatel na proměnnou, kam mají být zapsána přečtena data nebo hodnota, která má být zapsána.
+
+Ukázka jednoduchého userspace programu:
+\begin{verbatim}
+  1 |  #include <stdio.h>
+  2 |  #include <comedilib.h>
+  3 |  #define MF614_DO_SUBDEV      1 /* Je potřeba vědět, jak je 
+  4 |                                    implementováno v ovladači */
+  5 |  
+  6 |  int main(int argc, char* argv[])
+  7 |  {
+  8 |      comedi_t* comedi_dev;
+  9 |  
+ 10 |      comedi_dev = comedi_open("/dev/comedi0");
+ 11 |      if (comedi_dev == NULL) {
+ 12 |          comedi_perror("comedi_open");
+ 13 |          return 1;
+ 14 |      }
+ 15 |
+ 16 |      /* Zápis 1 na 0. kanál digitálního výstupu */  
+ 17 |      comedi_dio_write(comedi_dev, MF614_DO_SUBDEV, 0, 1);
+ 18 |      sleep(1);
+ 19 |      comedi_dio_write(comedi_dev, MF614_DO_SUBDEV, 0, 0);
+ 20 |      sleep(1);
+ 21 |      comedi_dio_write(comedi_dev, MF614_DO_SUBDEV, 0, 1);
+ 22 |      
+ 23 |      return 0;
+ 24 |  }
+\end{verbatim}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\chapter{Implementace Humusoft MF624 v Qemu}\label{qemu}
+Měřící karta Humusoft MF624 je hardware vhodný pro výklad principů implementace ovladače -- je ale poměrně drahý. Pro účely výuky proto byly do emulačního software Qemu implementovány základní funkce této měřící karty -- konkrétně se jedná o A/D převodníky, D/A převodníky a digitální vstupy a výstupy. Takto modifikovaná verze qemu může pří implementaci základního ovladače plně nahradit původní kartu.
+
+Kromě částečné implementace karty MF624 do Qemu je součástí tohoto \textit{virtuálního hardware} grafická aplikace, která má na starosti nastavování vstupních hodnot a zobrazování výstupních hodnot do/z karty.
+
+
+\section{Qemu}
+\subsection{Kompilace, instalace}
+Nejprve je potřeba řádně zkompilovat některé ze stabilních vydání emulátoru Qemu.
+
+\subsection{Použití}
+Komunikace mezi virtuální kartou implementovanou v Qemu a grafickým programem probíhá pomocí TCP/IP protokolu.
+
+\section{Qt grafiké rozhraní}
+Na obrázku \ref{qt_gui} je 
 
+Aplikaci je nutné spouštět až po spuštění Qemu ....
+
+\begin{figure}[h!]
+       \begin{center}
+       \includegraphics[width=70mm]{img/qt_gui.png}
+       \caption{(FIXME aktualni verzi). Vzhled grafikcé aplikace pro ovládání vstupů virtuální karty MF624}
+       \label{qt_gui}
+       \end{center}
+\end{figure}
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Testování}
@@ -1065,36 +1230,20 @@ Základní propojení na svorkovnici, které se osvědčilo, bylo:
 Konzistence jádra byla testována opětovným načítáním a uvolňováním jednotlivých ovladačů.
 
 \section{Qemu virtuální hardware, Qt grafické rozhraní}
+Správnost implementace virtuálního hardware byla testována spouštěním implementovaných ovladačů v systému virtualizovaného v Qemu. Zároveň byla ověřena funkčnost grafického rozhraní, reprezentujícího vstupy a výstupy do/z virtuální karty. 
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Závěr}
+V této práci se mi podařilo vysvětlit základní aspekty psaní ovladačů PCI ovladačů -- jak na obecné úrovni, tak u konkrétních ovladačů typu UIO a Comedi.
 
+Součástí práce jsou základní (pokrývající pouze A/D, D/A převodníky a digitální vstupy/výstupy) ovladače pro karty Humusoft MF624 a Humusoft 614. V budoucnu by tyto ovladače mohly být rozšířeny tak, aby pokrývaly všechny funkce těchto karet.
 
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\appendix
-\chapter{Qemu a Humusoft MF624}\label{qemu}
-Měřící karta Humusoft MF624 je hardware vhodný pro výklad principů implementace ovladače -- je ale poměrně drahý. Pro účely výuky proto byly do emulačního software Qemu implementovány základní funkce této měřící karty -- konkrétně se jedná o A/D převodníky, D/A převodníky a digitální vstupy a výstupy. Takto modifikovaná verze qemu může pří implementaci základního ovladače plně nahradit původní kartu.
-
-Kromě částečné implementace karty MF624 do Qemu je součástí tohoto \textit{virtuálního hardware} grafická aplikace, kterámá na starosti nastavování vstupních hodnot a zobrazování výstupních hodnot do/z karty.
-
-
-\section{Qemu}
-\subsection*{Kompilace, instalace}
-Nejprve je potřeba řádně zkompilovat některé ze stabilních vydání emulátoru Qemu.
-
-\subsection*{Použití}
-Komunikace mezi virtuální kartou implementovanou v Qemu a grafickým programem probíhá pomocí TCP/IP protokolu.
+Pro potřeby výuky byly implementovány základní funkce karty Humusoft MF614 do emulátoru Qemu. Tato implementace by mohla být v budoucnu rozšířena, případně by mohla posloužit jako příklad pro implementaci jiných jednoduchých PCI zařízení sloužících pro výuku implementace PCI ovladačů. I když tak nebylo původně zamýšleno, mohla by částečná implementace karty MF614 do Qemu posloužit i při výuce psaní ovladačů pro jiné operační systémy, jako například systémy rodiny Microsoft Windows.
 
-\section{Qt grafiké rozhraní}
-Na obrázku \ref{qt_gui} je 
 
-Aplikaci je nutné spouštět až po stuštění Qemu ....
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%\appendix
+%\chapter{Hudaqlib}
 
-\begin{figure}[h!]
-       \begin{center}
-       \includegraphics[width=70mm]{img/qt_gui.png}
-       \caption{(FIXME aktualni verzi). Vzhled grafikcé aplikace pro ovládání vstupů virtuální karty MF624}
-       \label{qt_gui}
-       \end{center}
-\end{figure}
+%\chapter{Obsah přiloženého CD}
index bdd4a8b8e43349ddacf0ee7b013b5d1ee492fefe..50cb8eb5e838f56e88815b6c001e5dffb7a734b1 100644 (file)
 }}
 \vspace{3ex}\par
 \noindent
+%\iflanguage{czech}{%
+%Prohlašuji, že jsem práci vypracoval samostatně a použil jsem pouze podklady uvedené v~přiloženém seznamu.\\
+%Nemám závažný důvod proti užití tohoto školního díla ve smyslu \S 60 Zákona č.~121/2000 Sb., o právu autorském, o právech souvisejících s právem autorským a o změně některých zákonů (autorský zákon).%
+
 \iflanguage{czech}{%
-Prohlašuji, že jsem práci vypracoval samostatně a použil jsem pouze podklady uvedené v~přiloženém seznamu.\\
-Nemám závažný důvod proti užití tohoto školního díla ve smyslu \S 60 Zákona č.~121/2000 Sb., o právu autorském, o právech souvisejících s právem autorským a o změně některých zákonů (autorský zákon).%
+Prohlašuji, že jsem svou diplomovou práci vypracoval samostatně a použil jsem pouze podklady (literaturu, projekty, SW atd.) uvedené v přiloženém seznamu.%
 }{%
 \noindent
 I hereby declare that I have completed this thesis independently and that I have listed all the literature and publications used.\\
index cea18cdfcae7e0b3b7377da98bb138edbf464e36..0191a3daea46066769f18c191a5e066bd9f0e036 100644 (file)
@@ -191,7 +191,7 @@ Rád bych poděkoval Ing. Pavlu Píšovi, Ph.D., za věcné rady, připomínky 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%   Prohlaseni / Declaration 
 
-\declaration{V Praze dne 1.\,5.\,2011}
+\declaration{V Praze dne 12.\,4.\,2011}
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%    Abstract