]> rtime.felk.cvut.cz Git - mf6xx.git/commitdiff
Diploma thesis text corrections.
authorRostislav Lisovy <lisovy@gmail.com>
Sun, 8 May 2011 23:08:53 +0000 (01:08 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Sun, 8 May 2011 23:08:53 +0000 (01:08 +0200)
doc/diploma_thesis/text/dip_text.tex
doc/diploma_thesis/text/img/mmio.pdf
doc/diploma_thesis/text/img/src/mmio.svg
doc/diploma_thesis/text/lisovy_dip.tex
doc/diploma_thesis/text/reference.bib

index 3cdc1edb06de06cc70c7a8cd8220583d52b06e68..6b8c685995d261c96056a60e425e7139df469388 100644 (file)
@@ -8,30 +8,31 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Úvod}
 \section{Motivace, cíl}
-Zadání této práce vzešlo z akademického prostředí a reaguje na nedostatek studijních materiálů v českém jazyce pro začátečníky, popisující vývoj ovladačů (v tomto případě PCI zařízení) pro operační systém GNU/Linux.
+Tato práce vnikla na základě potřeby připravit, zdokumentovat a otestovat prostředí vhodné pro výuku hardwarově zaměřených předmětů. Jedná se především o seznámení s~nízko\-úrovňovým přístupem k hardwaru a vývoj ovladačů. Práce předkládá návod a vlastní řešení určené pro PCI karty a operační systém GNU/Linux. Vytvořená emulace hardwaru jedné z karet umožňuje vytváření a testování vlastních ovladačů bez nutnosti fyzického přístupu k~dané kartě a je přímo použitelná i při vývoji ovladačů pro jiné operační systémy.
 
-Text popisuje základní aspekty práce s PCI zařízeními v jádře Linux a uvádí dva konkrétní způsoby implementace ovladače zařízení PCI -- tzv. UIO a Comedi ovladač. Text obsahuje pouze nezbytné množství teorie, která je podložena četnými příklady pro snadnější pochopení. Pro čtenáře neznalého psaní programů těsně svázaných s hardwarem, jsou názorně vysvětleny základní principy a úskalí tohoto druhu programování.
+Zvolené vstupně výstupní karty jsou na Katedře řídicí techniky využívané i v mnoha dalších předmětech k propojení počítačů s řízenými modely fyzikálních soustav. Navržené ovladače a otestovaný přístup z operačního systému GNU/Linux tedy umožňuje použít i~variantu plně preemptivního jádra Linux pro řízení modelů s využitím i rozsáhlého matematického aparátu v reálném čase. Reálné nasazení pro přizpůsobený GNU/Linux umožní řízení s reálnými maximálními latencemi menšími než 200 mikrosekund. Robustnost řešení umožňuje další vývoj řídicích algoritmů a v budoucnu po delším testování i využití v reálných průmyslových aplikacích.
+
+
+Text popisuje základní aspekty práce s PCI zařízeními v jádře Linux a uvádí dva konkrétní způsoby implementace ovladače zařízení PCI -- pro přístup k hardwaru z uživatelského prostoru s minimální nutnou podporou z jádra (UIO ovladač) a plnohodnotný ovladač na úrovni jádra operačního systému začleněný do subsystému určeného pro měřící a řídicí vstupně-výstupní zařízení (Comedi).
+
+ Text obsahuje pouze nezbytné množství teorie, která je podložena četnými příklady pro snadnější pochopení. Pro čtenáře neznalého psaní programů těsně svázaných s hardwarem, jsou názorně vysvětleny základní principy a úskalí tohoto druhu programování.
 %V případě dalšího zájmu o problematiku může čtenář sáhnout po knize \cite{devicedriver}.
 
-Jako ukázková zařízení na sběrnici PCI byly zvoleny karty Humusoft MF624 a MF614. Podrobně je popsána jejich funkce, včetně způsobu obsluhy ovladačem. Tyto karty byly zvoleny z důvodu snadno pochopitelného způsobu obsluhy.
+Jako ukázková zařízení na sběrnici PCI byly zvoleny karty Humusoft MF624 a MF614. Podrobně je popsána jejich funkce, včetně způsobu obsluhy ovladačem. Tyto karty byly zvoleny také z důvodu snadno pochopitelného způsobu obsluhy.
   
-Výsledkem práce by měly být, kromě popisu vývoje PCI ovladačů, i ovladače typu UIO a Comedi podporující základní funkce (A/D, D/A převodníky a digitální vstupy a výstupy) karet Humusoft MF614 a MF624, které by mohly posloužit jako jednoduché ukázkové ovla\-dače.
+Výsledkem práce jsou, kromě popisu vývoje PCI ovladačů, i ovladače typu UIO a Comedi podporující základní funkce (A/D, D/A převodníky a digitální vstupy a výstupy) karet Hu\-musoft MF614 a MF624, které slouží jako jednoduché ukázkové ovla\-dače.
 
 Pro maximální možné zhodnocení návodů, je cílem práce implementovat některé funkce karty Humusoft MF624 do emulačního programu Qemu tak, aby bylo možné popsané postupy implementace ovladačů vyzkoušet i bez fyzického přístupu ke kartě.
 
 \section{Dostupné materiály}
 V českém jazyce dosud vyšla pouze jedna tištěná kniha, která se zabývá problematikou programování v prostředí jádra Linux. Jedná se o knihu Jádro systému Linux \cite{jadrosystemu} od Lukáše Jelínka. Je dělena do 3 základních částí:
-\begin{itemize}
-\item \textit{Vnější rozhraní jádra}
-\item \textit{Vývoj ovladačů}
-\item \textit{Pohled dovnitř jádra}
-\end{itemize}
+\textit{Vnější rozhraní jádra}, \textit{Vývoj ovladačů}, \textit{Pohled dovnitř jádra}.
 
 Jednotlivá témata jsou popsána pouze stručně (kniha je koncipována spíše jako příručka než jako učebnice) a pro čtenáře, neznalého vývoje ovladačů zařízení, nemá příliš velký přínos.
 
 Za nejpřínosnější knihu, zabývající se problematikou jaderného programování, považuji anglicky psanou knihu Linux Device Drivers \cite{devicedriver} od autorů Jonathan Corbet, Alessandro Rubini a Greg Kroah-Hartman. Tato kniha podrobně vysvětluje jak obecné principy a funkce používané u jaderných ovladačů, tak i způsob implementace ovladačů zařízení konkrétních typů.
 
-Knihu je možné stáhnout zdarma ve formátu PDF\footnote{\url{http://lwn.net/Kernel/LDD3/}}.
+Knihu je možné stáhnout zdarma ve formátu PDF.\footnote{\url{http://lwn.net/Kernel/LDD3/}}
 
 \begin{figure}[h!]
        \begin{center}
@@ -52,7 +53,7 @@ Knihu je možné stáhnout zdarma ve formátu PDF\footnote{\url{http://lwn.net/K
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Hardware}
 \section{Základní principy komunikace s hardwarem}
-Jak je možné ovládat hardwarové periferie pomocí programu (software) je nejsnazší ukázat na příkladu jednočipového počítače.
+Komunikace s periferiemi je v nejjednodušších případech založena na čtení a zápisu obsa\-hu registrů mapovaných do adresního prostoru procesoru. V případě jednočipového počítače (mikrokontroléru) již žádné další softwarové a systémové vrstvy do hry nevstupují a~princip lze snadno popsat.
 
 \ibox{Mikrokontrolér, neboli jednočipový počítač, má velikost pouze jednoho čipu. Obsahuje přitom procesor, paměť, vstupně-výstupní zařízení a jiné. Je obvyklé, aby mikrokontrolér obsahoval tzv. GPIO piny. 
 \begin{description}
@@ -62,7 +63,7 @@ Jak je možné ovládat hardwarové periferie pomocí programu (software) je nej
 \end{description}%
 }
 
-Prvním způsobem, jak změnit stav (obecného) 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/programo\-vatelné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 adresního prostoru}.\footnote{Také označováno jako MMIO -- \textit{Memory-mapped input/output}}
+Prvním způsobem, jak změnit stav (obecného) 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 pro konkrétní typ součástky -- nebo celou rodinu příbuzných typů -- pevně daná). 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/programo\-vatelnému integrovanému obvodu je uvedeno, jakou funkci mají jednotlivé bity registru.} GPIO pinu. Adresa zápisu je přivedena na adresový dekodér, který zjistí, do které oblasti (vnitřní paměť dat, programu, oblast periferních registrů) adresa náleží. Pokud se jedná o oblast periferií, provede další podrobnější určení, které periferii připojené ke sběrnici data náleží a pověří obvody vybrané periferie dalším zpracováním zapisovaných dat. 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 adresního prostoru}.\footnote{Také označováno jako MMIO -- \textit{Memory-mapped input/output}}
 
 \begin{figure}[h!]
        \begin{center}
@@ -73,18 +74,25 @@ Prvním způsobem, jak změnit stav (obecného) GPIO pinu (ať už nastavení, z
 \end{figure}
 
 
-Jiným způsobem změny stavu registru je použití jiné instrukce než která se používá pro paměťové operace -- tj. místo zápisu na adresu v paměťovém prostoru vyhrazenou pro GPIO registr, se provede zápis do tzv. \textbf{vstupně-výstupního adresního prostoru}\footnote{Také označován zkratkou PIO -- \textit{Programmed input/output} nebo jako I/O adresní prostor} na adresu (v~tomto případě označovanou jako \textbf{port}) odpovídající registru GPIO pinů. Adresy paměťového a~vstupně-výstupního prostoru spolu nijak nesouvisí. V případě zápisu a čtení do/z portu I/O adresního prostoru je potřeba z dokumentace \textbf{přesně vědět} jak široká (kolikabitová) slova je možné zapisovat/číst. 
+U některých procesorových architektur se změna hodnoty registru provede jiným způso\-bem -- použitím, při zápisu do registru, jiné instrukce než která se používá pro paměťové operace -- tj. místo zápisu na adresu v paměťovém prostoru vyhrazenou pro GPIO registr, se provede zápis do tzv. \textbf{vstupně-výstupního adresního prostoru}\footnote{Také označován zkratkou PIO -- \textit{Programmed input/output} nebo jako I/O adresní prostor} na adresu (v~tomto případě označovanou jako \textbf{port}) odpovídající registru GPIO pinů. Adresy paměťového a~vstupně-výstupního adresního prostoru jsou nezávislé. V případě zápisu a čtení do/z portu I/O adresního prostoru je potřeba z dokumentace \textbf{přesně vědět} jak široká (kolikabitová) slova je možné zapisovat/číst. 
+
+\ibox{V případě architektury IA-32 (označované také jako x86) máme k dispozici paměťový a vstupně-výstupní adresní prostor. Adresy vstupně výstupního adresního prostoru jsou pouze 16bitové, zatímco paměťového jsou (\textit{pro zjednodušení není brán ohled na PAE -- Physical Address Extension}) 32bitové. Toto rozdělení přetrvává z historických důvodů -- i~přesto je již možné některá zařízení mapovat do paměťového prostoru. (Znázorněno na obrázku \ref{mmio}.)
 
-\ibox{V případě architektury IA-32 (označované také jako x86) máme k dispozici paměťový a vstupně-výstupní adresní prostor. Vstupně výstupní adresní prostor je pouze 16bitový, zatímco paměťový je (\textit{pro zjednodušení není brán ohled na PAE -- Physical Address Extension}) 32bitový. Toto rozdělení přetrvává z historických důvodů -- i~přesto je již možné některá zařízení mapovat do paměťového prostoru. (Znázorněno na obrázku \ref{mmio}.)}
+\vspace{1mm}
+Informace o obsazenosti paměťového a vstupně-výstupního adresního prostoru je možné v GNU/Linuxu zjistit čtením souboru \texttt{/proc/iomem} a \texttt{/proc/ioports}.
+}
 
 Hlavní rozdíly mezi chováním paměťové buňky a registru zařízení jsou:
 \begin{itemize}
 \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, kolika-bitové operace zápisu/čtení smějí být použity (8-, 16-, 32bitové).
+\item Při zápisu a čtení do/z registru je nutné přesně rozlišovat, kolika-bitové operace zápisu/ čtení smějí být použity (8-, 16-, 32bitové).
+\item Při přístupu k registrům mapovaným do paměťového adresního prostoru (z jádra operačního systému nebo z uživatelského programu), je nutné o této skutečnosti \textit{upozornit} jak překladač, tak samotný procesor. Důvodem jsou optimalizace, které mohou být provedeny -- které při přístupu do obyčejné paměti mohou program zrychlit, ale při přístupu do registru mohou způsobit nesprávnou funkci programu. Podrobněji je tento problém popsán v kapitole \ref{iofce}.
 \end{itemize}
 
+\vspace{1.5cm}
+
 \begin{figure}[h!]
        \begin{center}
        \includegraphics[width=100mm]{img/mmio.pdf}
@@ -94,12 +102,12 @@ Hlavní rozdíly mezi chováním paměťové buňky a registru zařízení jsou:
 \end{figure}
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%\clearpage
+\clearpage
 %\newpage
 \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řenos zpráv oproti přímé komunikaci mezi zařízeními.\footnote{Tj. místo toho, aby PCI most přistupoval přímo k paměti jednotlivých zařízení, vyšle se na sběrnici zpráva s požadavkem. V případě, že je některé zařízení schopno požadavek obsloužit, umístí na datovou sběrnici požadovaná data.}
+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{Tj. místo toho, aby PCI most přistupoval přímo k paměti jednotlivých zařízení, vyšle se na sběrnici zprá\-va s požadavkem. V případě, že je některé zařízení schopno požadavek obsloužit, umístí na datovou sběrnici požadovaná data. (Takto probíhá komunikace na úrovni sběrnice -- ze strany procesoru se jedná pouze o~zápis/ čtení paměťového/vstupně-výstupního adresního prostoru.)}
 
 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.
 
@@ -125,9 +133,9 @@ 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ě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é dynamicky 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 bylo při návrhu karty nebo propojkami na kartě, při jejím zapojení do PC, pevně určeno, 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é dynamicky postará BIOS počítače nebo PCI subsystém operač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{Informace o velikosti požadované oblasti je v registru uložena takovým způsobem, že je pouze jeho část určena k zápisu a zbytek je pouze pro čtení. PCI most se pokusí do registru zapsat hodnotu 0xFFFFFFFF, poté je hodnota zpět vyčtena -- z bitů náležejících do zapisovatelné části registru, je přečtena $1_2$, zbývající část obsahuje hodnoty $0_2$.}. 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.
+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{Informace o velikosti požadované oblasti je v registru uložena takovým způsobem, že je pouze jeho část určena k zápisu a zbytek je pouze pro čtení. PCI most se pokusí do registru zapsat hodnotu 0xFFFFFFFF, poté je hodnota zpět vyčtena -- z bitů náležejících do zapisovatelné části registru, je přečtena $1_2$, zbývající část obsahuje hodnoty $0_2$.}. Poté co se (při konfiguraci) podaří tuto hodnotu přečíst a požadovanou paměť alokovat, zapíše se zpět do daného registru adresa, 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í registry:
@@ -150,16 +158,19 @@ Registry Vendor ID, Device ID (příp. ještě Subsystem Vendor ID a Subsystem I
        \end{center}
 \end{figure}
 
-Výše popsané registry (spolu s ostatními, které zde nebyly popsány) se nacházejí v~256bito\-vém tzv. \textbf{konfiguračním adresním prostoru} karty (obr. \ref{sa1}).\footnote{Po paměťovém a vstupně-výstupním adresním prostoru je zde třetí -- konfigurační -- adresní prostor.} Pro \textit{konfigurační} adresní prostor není hardwarová podpora v téměř žádné procesorové architektuře -- přístup do něj je například na architektuře IA-32 možný pomocí zapsání adresy (\textit{kam má být v~konfiguračním prostoru zapisováno}) a dat (\textit{která mají být do konfiguračního prostoru zapsána}) do dvou speciálních I/O portů, které jsou pro tuto operaci vyhrazeny.
+Výše popsané registry (spolu s ostatními, které zde nebyly popsány) se nacházejí v~256bito\-vém tzv. \textbf{konfiguračním adresním prostoru} karty (obr. \ref{sa1}).\footnote{Po paměťovém a vstupně-výstupním adresním prostoru je zde třetí -- konfigurační -- adresní prostor.} Pro \textit{konfigurační} adresní prostor není hardwarová podpora v téměř žádné procesorové architektuře -- přístup do něj je například na architektuře IA-32 možný pomocí zapsání adresy (\textit{kam má být v~konfiguračním prostoru zapisováno}) a dat (\textit{která mají být do konfiguračního prostoru zapsána}) do dvou speciálních I/O portů, které jsou pro tuto operaci vyhrazeny.\footnote{Toto je možné považovat za \textit{klasický} způsob přístupu. Na moderních procesorech architektury IA-32 je již možné konfigurační adresní prostor namapovat do paměťového adresního prostoru.}
 
 
 \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í, jsou přerušení ú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.
+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žadavek 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 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.
+V posledních letech je na poli osobních počítačů PCI sběrnice nahrazována její nástupkyní -- sběrnicí PCIe (\textit{PCI Express}). Ta je na rozdíl od PCI sériová a dosahuje rychlostí až 16 GiB/s. I~přesto je sběrnice PCI stále využívána mnohými zařízeními -- převážně v průmyslu.
+
+PCI Express zařízení využívají, podobně jako PCI, konfigurační prostor (o velikosti 4 KiB). Prvních 256 bajtů je totožných s konfiguračním prostorem PCI zařízení (registry jako Vendor ID, BAR, apod. jsou totožné). PCIe sběrnice umožňuje nejen připojení jiné PCI sběrnice pomocí PCIe--PCI mostu, ale také připojení zařízení na sběrnici PCIe, jehož logická funkce je totožná s PCI zařízením. Postupy týkající se PCI sběrnice, popsané v této práci, jsou tedy přímo aplikovatelné i na zařízení typu PCIe.
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \newpage
 \section{Humusoft MF624}
@@ -177,9 +188,11 @@ Měřící karta Humusoft MF624 (obr. \ref{mf624}), připojitelná k počítači
 \item Je možné si ověřit správnou funkci napsaného ovladače -- např. připojením LED diody k digitálnímu výstupu nebo měřením napětí na výstupu D/A převodníku.
 \end{itemize}
 
-Karta MF624 najde své uplatnění hlavně v laboratorním prostředí -- v případech, když je potřeba vytvořit styk mezi počítačem a senzorem/jiným zařízením, které poskytuje analogový, resp. digitální signál (v tom případě jsou použity A/D převodníky, resp. digitální vstupy). Kartu je možné použít i pro řízení akčního členu/zařízení -- k dispozici jsou D/A převodníky a digitální výstupy.
+Karta MF624 najde své uplatnění hlavně v laboratorním prostředí -- v případech, kdy je potřeba zpřístupnit měřené hodnoty senzorů. V případě analogových, resp. digitálních signálů jsou použity A/D převodníky, resp. digitální vstupy. Kartu je možné použít i pro řízení akčního členu/zařízení -- k dispozici jsou D/A převodníky a digitální výstupy.
+
+~\\~\\
 
-Karta disponuje následujícícmi funkcemi (v popisu implementace ovladačů se omezím pouze na A/D, D/A převodníky a digitální vstupy/výstupy):
+Karta disponuje následujícími funkcemi (v popisu implementace ovladačů se omezím pouze na A/D, D/A převodníky a digitální vstupy/výstupy):
 \begin{itemize}
 \item 8 digitálních vstupů (TTL kompatibilní logické úrovně)
 \item 8 digitálních výstupů (TTL kompatibilní logické úrovně)
@@ -218,7 +231,7 @@ Z ní je patrné, že karta využívá 3 regiony\footnote{V manuálu je uvedeno,
 Pro čtení/zápis z/do nich je potřeba používat 32-, 16- a 32bitové operace.\footnote{V manuálu je uvedeno, že za určitých podmínek je možné k BAR1 přistupovat i pomocí 32bitových operací. V této práci bych se tomuto složitějšímu přístupu raději vyhnul. Částečná implementace karty MF624 do emulátoru Qemu (popsaná v kapitole \ref{qemu}) umožňuje \textbf{pouze} 16bitový přístup do BAR1 paměťového regionu.}
 
 \subsection{Digitální vstupy a výstupy}
-Z tabulky \ref{tab_bar} lze vyčíst informaci, že registry ovládající digitální vstupy a výstupy leží v regionu BAR1 (sloupec 2). Dále je potřeba se podívat na přehled registrů náležejících tomuto paměťovému regionu -- tomu odpovídá tabulka (s menšími úpravami) \ref{tab_bar1}.
+Z tabulky \ref{tab_bar} lze vyčíst informaci, že registry ovládající digitální vstupy a výstupy leží v~regionu BAR1 (sloupec 2). Dále je potřeba se podívat na přehled registrů náležejících tomuto paměťovému regionu -- tomu odpovídá tabulka (s menšími úpravami) \ref{tab_bar1}.
 
 \begin{table}[h!]
        \begin{center}
@@ -288,7 +301,7 @@ Karta MF624 obsahuje osm 14bitových A/D převodníků s pevně stanoveným mě
 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 úspěšně 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 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.
+\item Výslednou hodnotu je možné přečíst z registru ADDATA, který je typu FIFO. To zna\-mená, že opětovným čtením jednoho registru jsou vyčítány jednotlivé naměřené hod\-noty 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}
@@ -562,7 +575,7 @@ Informace o PCI zařízeních se nacházejí ve složce \texttt{/sys/bus/pci/dev
 \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ů využívaných zařízením (také označováno jako \textit{obsah} BAR registrů).
+\item[\texttt{resource}] -- Soubor obsahuje popis jednotlivých regionů využívaných zařízením (také ozna\-čo\-váno jako \textit{obsah} BAR registrů).
 \end{description}
 
 Struktura souboru \texttt{resource} může vypadat následovně:
@@ -615,7 +628,8 @@ Z čeho se modul skládá:
 Pro jednoduchost je možné s funkcí \texttt{printk()} pracovat jako s, jistě známou, funkcí \texttt{printf()} dostupnou v uživatelském prostoru -- 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}.\\O to, že se tato funkce vykoná ihned po zavedení modulu do jádra, se postará příkaz na $\rightarrow$
 \item[řádku 15] -- ten obsahuje makro \texttt{module\_init()}, kterému je sděleno 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 tomto 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.
+\item[řádcích 10--13.] Tato funkce nemá na starost pouze výpis krátkého textu do logu jádra.
+
 \item[Na řádku 18] je použito makro udávající licenci definující práva a povinnosti pro šíření/ používání zdrojových kódů daného modulu. Uvedení licence je důležité z toho důvodu, že jaderné moduly nevyužívající některou z opensource licencí nemají dostupná všechna jaderná volání (to platí i pro případ, že není uvedena žádná licence).
 \end{description}
 
@@ -639,7 +653,7 @@ Linux využívá při kompilaci systému \texttt{KBUILD}. Ten je tvořen větš
 \item[Na pátém řádku] (uvozeném tabelátorem) se volá (pomocí přepínače \texttt{-C}) Makefile ze sys\-tému \texttt{KBUILD}, který se nachází v adresáři spolu se zdrojovými kódy jádra. Parametr \texttt{M} určuje, které moduly mají být vytvořeny -- v tomto případě jsou to ty, které jsou uvedeny v Makefile, nacházejícím se v aktuálním adresáři (tj. \texttt{PWD}).
 \end{description}
 
-V případě, že se 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:
+V případě, že se 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:
 \begin{verbatim}
   $ make
   make -C /lib/modules/`uname -r`/build M=/tmp/kernel_module_example modules
@@ -680,8 +694,7 @@ Pro plné otestování funkčnosti ukázkového modulu, je potřeba ho ještě z
   $ dmesg | tail -1
   [ 9612.256929] Goodbye, cruel world!
 \end{verbatim}
-V logu je opět nachází text vypisovaný modulem při uvolňování z jádra.
-
+V logu se opět nachází text vypisovaný modulem při uvolňování z jádra.
 
 \ibox{V případě, že má být do jádra zaveden modul, jehož funkčnost a stabilita není jistá, je vhodné si veškerou práci uložit (případně zálohovat) a před zavedením/uvolněním modulu do/z jádra spustit program \texttt{sync}, který uloží obsah diskových bufferů na disky.}
 
@@ -724,7 +737,7 @@ Příklad pro lepší názornost:
 
 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()}. V případě, že by tyto funkce byly volány z více míst, došlo by k duplikaci kódu, která vede k nepřehlednosti a může způsobovat chyby (v případě, že se omylem místo všech výskytů dealokační sekvence opraví pouze některé).
+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 kromě funkce \texttt{pci\_disable\_device()} ještě funkce \texttt{pci\_release\_regions()}. V případě, že by tyto funkce byly volány z více míst, došlo by k duplikaci kódu -- ta vede k nepřehlednosti a může způsobovat chyby (v případě, že se omylem místo všech výskytů dealokační sekvence opraví pouze některé).
 
 Za pomoci volání \texttt{goto} je výše popsaný problém elegantně vyřešen.
 
@@ -765,7 +778,7 @@ Příklad nastavení typu zprávy a použití formátovacího řetězce:
 
 
 \subsection{Funkce \texttt{kzalloc()} pro alokaci paměti}
-Problematika alokace paměti v prostředí jádra Linux je velice rozsáhlá. Pomocí speciálních funkcí je možné alokovat logickou paměť, velké bloky virtuální paměti nebo celé paměťové stránky.
+Problematika alokace paměti v prostředí jádra Linux je velice rozsáhlá. Pomocí speciálních funkcí je možné alokovat fyzickou paměť, velké bloky virtuální paměti nebo celé paměťové stránky.
 
 \ibox{\texttt{void *kzalloc(size\_t size, gfp\_t flags);}}
 Základní funkce pro alokaci malé paměťové oblasti (např. pro strukturu obsahující privátní data ovladače) je \texttt{kzalloc()}. Prvním parametrem je velikost alokované paměti (maximálně však 128 KB), druhým je příznak určující o jaký druh alokace se jedná. Nejuniverzálnější možností je \texttt{GFP\_KERNEL}.
@@ -792,16 +805,25 @@ Když již alokovaná paměť není potřeba, je nutné ji voláním \texttt{kfr
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\vspace{1cm}
 \section{Ovladače PCI zařízení}\label{pci_driv}
-\ibox{Jako nejlepší reference jednotlivých funkcí slouží zdrojové kódy jádra. Jednou z~možností jejich prohlížení je pomocí online nástroje \textit{The Linux Cross Reference} -- \\
-\url{http://lxr.linux.no/linux/}.}
+\ibox{Jako nejlepší reference jednotlivých funkcí slouží zdrojové kódy jádra. Pro snadné procházení je vhodné využít nástroje vytvářející křížové odkazy (mezi voláním a~defi\-nicí funkce, použitím a deklarací proměnné apod.). 
+
+\vspace{1mm}
+Nejpohodlnějším způsobem je použití online nástroje \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, 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.
+\vspace{1mm}
+Jinou možností je přímé čtení a procházení zdrojových kódů jádra. Pro vytváření indexu křížových odkazů poslouží programy \texttt{ctags} a \texttt{cscope}. Samotné procházení je poté možné například pomocí programů \texttt{vim} a \texttt{Kscope}.}
+
+
+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}) -- ten také zajistí i načtení modulů potřebných pro splnění případných závislostí načítaného modulu. 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}). Tento subsystém poté na základě získaných informací, jako je Vendor ID a Device ID, rozhodne, který ovladač má být pro dané zařízení načten. Seznam, dle kterého je ovladač vybírán, je v souboru \texttt{/lib/modules/\$(uname -r)/modules.pcimap}.
 
 Proto, aby mohl být ovladač součástí výše popsaného seznamu, musí ve struktuře \texttt{struct pci\_device\_id} obsahovat informaci o tom, pro které zařízení je určen.
 
+
+
 \subsection{Struktura \texttt{struct pci\_device\_id}}\label{pci_dev_id}
 Struktura \texttt{struct pci\_device\_id} slouží k identifikaci, pro která zařízení je ovladač určen. Mezi hlavní položky struktury patří \texttt{vendor}, \texttt{device}, \texttt{subvendor}, \texttt{subdevice} (typu \texttt{\_\_u32}) -- jejichž hodnota odpovídá hodnotě stejnojmenných registrů v konfiguračním prostoru daného PCI zařízení. Jelikož může být ovladač napsán pro více zařízení, je tato struktura inicializována jako prvek pole, které je vždy zakončeno prázdným prvkem. Různé způsoby inicializace mohou vypadat následovně:
 
@@ -858,7 +880,7 @@ Příklad, jak může být struktura \texttt{pci\_driver} inicializována a nás
 
 
 \subsection{Funkce \texttt{probe()}}\label{pci_init}
-\ibox{\texttt{int probe(struct pci\_dev *dev, const struct pci\_device\_id *id);}}
+\ibox{\texttt{int (*probe) (struct pci\_dev *dev, const struct pci\_device\_id *id);}}
 
 Funkce \texttt{probe()} náležící danému ovladači zařízení je volána poté, co jaderný subsystém PCI zařízení zjistí, že se v systému nachází zařízení, pro které je tento ovladač určen. Tato funkce má na starosti inicializaci zařízení.
 
@@ -958,22 +980,22 @@ V případě, že se na paměť ve vstupně-výstupním adresním prostoru zavol
 nebo v případě PCI zařízení funkce
 \ibox{\texttt{void *pci\_iomap(struct pci\_dev *dev, int bar, unsigned long maxlen);}}
 
-se paměť chová jakoby byla v paměťovém adresním prostoru a je nutné pro přístup k ní používat volání popsaná v této kapitole.
-
+se rozsah I/O portů chová jakoby byl součástí paměťového adresního prostoru. Pro přístup je poté nutné používat volání popsaná v této kapitole, která zakryjí rozdílný charakter přístupu do vstupně-výstupního adresního prostoru.
 
-Pro přístup k paměti zařízení z uživatelského prostoru bohužel žádná sada funkcí není. Je potřeba nadefinovat funkce vlastní, které přistupují k paměti skrze ukazatel, který je ale označen jako \texttt{volatile}. To opět zabrání překladači v optimalizaci kódu manipulujícího s~ukazatelem.
+Na procesorových architekturách využívajících reorganizaci pořadí přístupu k operandům na úrovni CPU je nutné definovat i vlastní sadu operací pro tvorbu paměťových bariér. Archi\-tektury IA-32 se tyto potíže netýkají, při portaci na architektury jiné bude třeba tyto funkce podle požadavků příslušné architektury doplnit. Bohužel přenositelné hlavičkové soubory nejsou ve standardních GNU/Linuxových distribucích založených na GNU LibC pro uživatelský prostor (na rozdíl od jádra) k dispozici.
 
-Příklad jak takové funkce mohou vypadat:
+Příklad jak takové funkce (používané na architektuře IA-32) mohou vypadat:
 
 \begin{verbatim}
   1 |  static inline void mf624_write32(uint32_t val, uint32_t *ptr)
   2 |  {
   3 |      *(volatile uint32_t*) ptr = val;
   4 |  }
-  5 |  static inline uint32_t mf624_read32(uint32_t *ptr)
-  6 |  {
-  7 |      return (volatile uint32_t) *ptr;
-  8 |  }
+  5 |
+  6 |  static inline uint32_t mf624_read32(uint32_t *ptr)
+  7 |  {
+  8 |      return (volatile uint32_t) *ptr;
+  9 |  }
 \end{verbatim}
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -981,7 +1003,7 @@ 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 USB zařízení. Tato volba určí, kterou sadu pomocných funkcí bude moci ovladač používat a jakým způsobem bude zařízení zpřístupněno do uživatelského prostoru.
 
-V~případě, že zařízení nelze snadno zařadit do žádné kategorie (jedná-li se například o~neobvyklou průmyslovou PCI 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živatel\-ském prostoru (viz diagram ma obrázku \ref{uio_diagram}).
+V~případě, že zařízení nelze snadno zařadit do žádné kategorie (jedná-li se například o~neobvyklou průmyslovou PCI 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živatel\-ském prostoru (viz diagram na obrázku \ref{uio_diagram}).
 
 \begin{figure}[h!]
        \begin{center}
@@ -1009,7 +1031,7 @@ Většina z těchto úkonů již byla popsána v kapitole \ref{pci_driv} a jsou
 
 \ibox{\texttt{int uio\_register\_device(struct device *parent, struct uio\_info *info);}}
 
-Registrace UIO ovladače PCI zařízení 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.
+Registrace UIO ovladače PCI zařízení se provede zavoláním funkce \texttt{uio\_register\_device()}, které se jako první parametr předá ukazatel na strukturu obecného zařízení \texttt{dev} vnořenou do struktury \texttt{struct pci\_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}}
@@ -1072,7 +1094,7 @@ Příklad, jak taková jednoduchá inicializace struktury \texttt{struct uio\_in
 
 \ibox{\texttt{void pci\_set\_drvdata(struct pci\_dev *pdev, void *data);}}
 
-Na posledním řádku je, dosud nepopsané, volání \texttt{pci\_set\_drvdata()}. To (v tomto případě) zajistí, že struktura \texttt{struct uio\_info} se stane součástí struktury reprezentující zařízení (\texttt{struct pci\_dev}) -- což umožní pozdější přístup ke struktuře \texttt{struct uio\_info} z funkcí jako je například \texttt{remove()}, která jako parametr získá ukazatel na strukturu \texttt{struct pci\_dev}.
+Na posledním řádku je, dosud nepopsané, volání \texttt{pci\_set\_drvdata()}. To (v tomto pří\-pa\-dě) zajistí, že struktura \texttt{struct uio\_info} se stane součástí struktury reprezentující zařízení (\texttt{struct pci\_dev}) -- což umožní pozdější přístup ke struktuře \texttt{struct uio\_info} z funkcí jako je například \texttt{remove()}, která jako parametr získá ukazatel na strukturu \texttt{struct pci\_dev}.
 
 \ibox{\texttt{static inline void *pci\_get\_drvdata(struct pci\_dev *pdev);}}
 
@@ -1107,10 +1129,9 @@ Tento soubor tvoří rozhraní mezi jaderným subsystémem UIO a uživatelským
 
 Tato funkce slouží k \textit{namapování} souboru nebo zařízení do operační paměti. V případě, že je funkce zavolána na soubor, proběhne-li vše správně, návratová hodnota bude obsahovat ukazatel do paměti, kam je možné přistu\-povat k obsahu souboru pomocí ukazatelové aritmetiky -- stejně, jako by to byla paměť.
  
-Popis jednotlivých parametrů:
+Popis jednotlivých parametrů:\begin{description}
+\item[\texttt{addr}]~\\V případě, že není nulový, určí na jakou adresu ve virtuálním adresním prostoru apli\-kace by měla být paměť mapována. Není-li adresa určena, volnou oblast vybere pod\-půrná C knihovna (LibC).
 
-\begin{description}
-\item[\texttt{addr}]~\\V případě, že není nulový, určí na jakou adresu by měla být paměť mapována.
 \item[\texttt{length}]~\\ Udává velikost mapované paměti v násobcích velikosti paměťové stránky. 
 \item[\texttt{prot}]~\\ Obsahuje příznaky definující, zda bude mapovaná paměť pro čtení/zápis, apod.
 \item[\texttt{flags}]~\\ Pomocí příznaků 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}).
@@ -1118,6 +1139,7 @@ Popis jednotlivých parametrů:
 \item[\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}
 
+\newpage
 Příklad, jak takové volání může vypadat (bez ošetření chybových stavů):
 \begin{verbatim}
   1 |  #define BAR2_offset       (1 * sysconf(_SC_PAGESIZE))
@@ -1132,7 +1154,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 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řeba udělat \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ěť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řeba udělat \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ěť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):
 \begin{verbatim}
   mf624_BAR2 += (BAR2_phys_addr & (sysconf(_SC_PAGESIZE) - 1));
     |                \-- Fyzická adresa
@@ -1154,7 +1176,7 @@ Comedi se skládá ze tří částí:
 \begin{description}
 \item[Comedi] -- jsou jednotlivé nízkoúrovňové ovladače zařízení, včetně hlavního ovladače \texttt{comedi}, který poskytuje základní funkce.
 \item[Comedilib] -- je knihovnou v uživatelském prostoru, která poskytuje jednotné rozhraní pro ovládání jednotlivých zařízení. 
-\item[Kcomedilib] -- je jaderný modul, který poskytuje stejné rozhraní jako Comedilib v uživatelském prostoru. Používá se v případě potřeby ovládat zařízení v reálném čase.
+\item[Kcomedilib] -- je jaderný modul, který poskytuje stejné rozhraní jako Comedilib v uživatel\-ském prostoru. Používá se v případě potřeby ovládat zařízení v reálném čase.
 \end{description}
 
 
@@ -1162,7 +1184,7 @@ Comedi se skládá ze tří částí:
 Pro správnou funkci je potřeba, aby byl ovladač ihned po načtení modulu (tj. v \textit{init} funkci) zaregistrován -- jak do PCI subsystému, tak do subsystému Comedi. Registrace do PCI subsystému je popsána v kapitole \ref{pci_reg}. Registrace mezi Comedi ovladače se provede voláním \texttt{comedi\_driver\_register()}, kde jako parametr se předá ukazatel na strukturu \texttt{struct comedi\_driver}.
 
 \subsection{Struktura \texttt{struct comedi\_driver}}
-Jednotlivé položky struktury \texttt{struct comedi\_driver} popisují daný ovladač. Mezi nejdůležitější položky patří:
+Jednotlivé položky struktury \texttt{struct comedi\_driver} popisují daný ovladač. Mezi nej\-důle\-ži\-tější položky patří:
 \begin{description}
 \item[\texttt{const char *driver\_name;}]~\\Obsahuje textový název ovladače.
 \item[\texttt{struct module *module;}]~\\Ukazatel na modul, kterému tato struktura náleží. Inicializuje se makrem \texttt{THIS\_MODULE}.
@@ -1170,7 +1192,7 @@ Jednotlivé položky struktury \texttt{struct comedi\_driver} popisují daný ov
 \item[\texttt{int (*detach) (struct comedi\_device *);}]~\\Ukazatel na funkci, která má být zavolána při deaktivaci ovladače.
 \end{description}
 
-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.
+Na rozdí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. Dříve než dojde na popis inicializačních kroků je nutné vysvětlit názvosloví, které je u Comedi ovladačů používáno.
@@ -1317,7 +1339,7 @@ Qemu je emulátor různých procesorových architektur. Od klasických virtualiz
 \subsection{Kompilace, instalace}
 Po stažení a rozbalení zdrojových kódů některé ze stabilních verzí emulátoru Qemu je potřeba spustit příkaz (pro emulaci architektury IA-32):
 \begin{verbatim}
-  $ ./configure --enable-system  --target-list=i386-softmmu
+  $ ./configure --enable-system --target-list=i386-softmmu
 \end{verbatim}
 
 Neohlásí-li spuštěný skript žádné chybějící knihovny, je možné spustit kompilaci:
@@ -1326,7 +1348,7 @@ Neohlásí-li spuštěný skript žádné chybějící knihovny, je možné spus
 \end{verbatim}
 
 \subsection{Kompilace virtuální karty Humusoft MF624}
-V případě, že je potřeba zkompilovat virtuální kartu MF624, je nejprve potřeba překopírovat zdrojový soubor implementující zařízení do složky \texttt{/hw} a do souboru \texttt{Makefile.objs} (nachází se v kořenovém adresáři se zdrojovými kódy) přidat řádek:
+V případě, že je potřeba zkompilovat virtuální kartu MF624, je nejprve potřeba překopíro\-vat zdrojový soubor implementující zařízení do složky \texttt{/hw} a do souboru \texttt{Makefile.objs} (nachází se v kořenovém adresáři se zdrojovými kódy) přidat řádek:
 
 \begin{verbatim}
   hw-obj-$(CONFIG_PCI) += mf624.o
@@ -1366,7 +1388,7 @@ Příklad ovládání vstupů a zobrazování výstupů karty pomocí aplikace \
 \end{verbatim}
 
 \section{Qt grafiké rozhraní}\label{qt_gui_ch}
-Pro komunikaci s virtuální kartou MF624 bylo implementováno jednoduché grafické rozhraní, které má na starosti vykreslování hodnot výstupů karty (nastavovaných ovladačem běžícím v operačním systému virtualizovaném Qemu) a posílání nastavovaných vstupních hodnot zpět virtuální kartě.
+Pro komunikaci s virtuální kartou MF624 bylo implementováno jednoduché grafické roz\-hraní, které má na starosti vykreslování hodnot výstupů karty (nastavovaných ovladačem běžícím v operačním systému virtualizovaném Qemu) a posílání nastavovaných vstupních hodnot zpět virtuální kartě.
 
 Komunikace mezi virtuální kartou a grafickou aplikací probíhá pomocí TCP/IP protokolu. Přenášené informace jsou textového charakteru, ve formátu \texttt{REGISTR=HODNOTA}.
 
@@ -1439,50 +1461,15 @@ Pro potřeby výuky byly implementovány základní funkce karty Humusoft MF614
 \begin{verbatim}
 .
 |-- doc
-|   |-- diploma_thesis
-|   |   |-- kernel_module_example
-|   |   `-- text
-|   `-- hw
-|       |-- mf614
-|       |   |-- datasheet
-|       |   `-- sys_bus_pci_device
-|       `-- mf624
-|           |-- datasheet
-|           |-- sys_bus_pci_device
-|           `-- sys_class_uio_uio0
+|   |-- diploma_thesis  Text diplomové práce
+|   `-- hw              Informace k použitým kartám MF614 a MF624
 `-- src
-    |-- comedi
-    |   |-- fpoulain
-    |   |   |-- code_configuration
-    |   |   |-- comedi+rtai
-    |   |   `-- documentation
-    |   |-- mf614_simple_driver
-    |   |   |-- kernel
-    |   |   `-- userspace
-    |   |       `-- dout_example
-    |   `-- mf624_simple_driver
-    |       |-- kernel
-    |       `-- userspace
-    |           |-- dac_example
-    |           `-- dout_example
-    |-- qemu
-    |   |-- hw
-    |   `-- mf624_interface
-    |       `-- untitled-build-desktop
-    |-- qemu_qt_gui
-    |   `-- untitled
-    `-- uio
-        |-- mf614
-        |   `-- kernel
-        `-- mf624
-            |-- kernel
-            |   `-- udev_rules
-            `-- userspace
-                `-- test_application
+    |-- comedi          Zdrojové kódy Comedi ovladačů pro karty MF614 a MF624
+    |-- qemu            Implementace funkcí karty MF624 do Qemu
+    |-- qemu_qt_gui     Grafické rozhraní pro virtuální kartu MF624 v Qemu
+    `-- uio             Zdrojové kódy UIO ovladačů karet MF614 a MF624
 \end{verbatim}
 
-To be done.
-
 
 %\chapter{Hudaqlib}
 
index 3dc3d6582dc906b0140eb3ef8fa64f3732fca02c..ff411d88efc195d0920de44894c1010536daa93a 100644 (file)
Binary files a/doc/diploma_thesis/text/img/mmio.pdf and b/doc/diploma_thesis/text/img/mmio.pdf differ
index bc8a18c804ec2d52a8365ee63260a386789af956..dbc3cc99b45c3a93080c8b956f542891e3a7c4a7 100644 (file)
@@ -15,7 +15,7 @@
    height="1052.3622047"
    id="svg2"
    version="1.1"
-   inkscape:version="0.48.0 r9654"
+   inkscape:version="0.48.1 r9760"
    sodipodi:docname="mmio.svg"
    inkscape:export-filename="/mnt/data/_dokumenty_/_thk_/_DIP/text/img/mmio.png"
    inkscape:export-xdpi="271.92184"
          height="260"
          width="260" />
     </pattern>
-    <pattern
-       inkscape:stockid="Stripes 1:1"
-       id="Strips1_1"
-       patternTransform="translate(0,0) scale(10,10)"
-       height="1"
-       width="2"
-       patternUnits="userSpaceOnUse"
-       inkscape:collect="always">
-      <rect
-         id="rect4727"
-         height="2"
-         width="1"
-         y="-0.5"
-         x="0"
-         style="fill:black;stroke:none" />
-    </pattern>
   </defs>
   <sodipodi:namedview
      id="base"
      borderopacity="1.0"
      inkscape:pageopacity="0.0"
      inkscape:pageshadow="2"
-     inkscape:zoom="2.8"
-     inkscape:cx="202.41228"
-     inkscape:cy="738.43714"
+     inkscape:zoom="1.979899"
+     inkscape:cx="271.10281"
+     inkscape:cy="723.17191"
      inkscape:document-units="px"
-     inkscape:current-layer="g3940"
+     inkscape:current-layer="layer1"
      showgrid="false"
      inkscape:window-width="1680"
      inkscape:window-height="979"
         <dc:format>image/svg+xml</dc:format>
         <dc:type
            rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
+        <dc:title></dc:title>
       </cc:Work>
     </rdf:RDF>
   </metadata>
          y="439.67078"
          style="font-size:14px;text-align:center;text-anchor:middle"
          id="tspan3798">prostor</tspan></text>
-    <g
-       id="g3940"
-       transform="translate(15.314316,2.1428528)">
-      <rect
-         y="199.50504"
-         x="84.285713"
-         height="202.85715"
-         width="102.85714"
-         id="rect2985"
-         style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
-      <g
-         id="g3963">
-        <rect
-           style="fill:#ffffff;fill-opacity:1;stroke:#000080;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
-           id="rect3804"
-           width="100.7062"
-           height="61.176441"
-           x="85.464966"
-           y="339.75711" />
-        <text
-           xml:space="preserve"
-           style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
-           x="120.40987"
-           y="375.44836"
-           id="text3806"
-           sodipodi:linespacing="125%"><tspan
-             sodipodi:role="line"
-             id="tspan3808"
-             x="120.40987"
-             y="375.44836"
-             style="font-size:14px">RAM</tspan></text>
-      </g>
-      <g
-         id="g3860">
-        <rect
-           style="fill:#ffffff;fill-opacity:1;stroke:#800080;stroke-width:1.17395353;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
-           id="rect3804-2"
-           width="100.7062"
-           height="10.883288"
-           x="85.607124"
-           y="215.42989" />
-        <text
-           xml:space="preserve"
-           style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
-           x="112.58522"
-           y="223.78365"
-           id="text3856"
-           sodipodi:linespacing="125%"><tspan
-             sodipodi:role="line"
-             id="tspan3858"
-             x="112.58522"
-             y="223.78365"
-             style="font-size:8px">PCI DEVICE</tspan></text>
-      </g>
-      <g
-         id="g6305">
-        <rect
-           style="fill:none;fill-opacity:1;stroke:#000080;stroke-width:1;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
-           id="rect3804-0"
-           width="100.7062"
-           height="38.948009"
-           x="85.350388"
-           y="274.18423" />
-        <text
-           xml:space="preserve"
-           style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
-           x="120.29529"
-           y="298.76126"
-           id="text3806-0"
-           sodipodi:linespacing="125%"><tspan
-             sodipodi:role="line"
-             id="tspan3808-5"
-             x="120.29529"
-             y="298.76126"
-             style="font-size:14px">RAM</tspan></text>
-      </g>
-      <g
-         transform="translate(-0.25673537,108.60396)"
-         id="g3860-2">
-        <g
-           id="g3995">
-          <rect
-             y="217.42989"
-             x="85.607124"
-             height="10.883288"
-             width="100.7062"
-             id="rect3804-2-8"
-             style="fill:#ffffff;fill-opacity:1;stroke:#800080;stroke-width:1.17395353;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
-          <text
-             sodipodi:linespacing="125%"
-             id="text3856-29"
-             y="225.78365"
-             x="117.14967"
-             style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
-             xml:space="preserve"><tspan
-               style="font-size:8px"
-               y="225.78365"
-               x="117.14967"
-               id="tspan3858-96"
-               sodipodi:role="line">IO PORTS</tspan></text>
-        </g>
-      </g>
-    </g>
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.75572538;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="rect2985"
+       width="101.01596"
+       height="202.85715"
+       x="100.52061"
+       y="201.64789" />
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke:#1162ff;stroke-width:1.74105036;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="rect3804"
+       width="97.241943"
+       height="61.185974"
+       x="102.40762"
+       y="341.90488" />
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+       x="135.62039"
+       y="377.59122"
+       id="text3806"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3808"
+         x="135.62039"
+         y="377.59122"
+         style="font-size:14px">RAM</tspan></text>
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke:#a90021;stroke-width:1.74702513;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="rect3804-2"
+       width="97.241943"
+       height="10.884984"
+       x="102.40762"
+       y="217.55829" />
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+       x="128.38016"
+       y="225.9265"
+       id="text3856"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3858"
+         x="128.38016"
+         y="225.9265"
+         style="font-size:8px">PCI DEVICE</tspan></text>
+    <rect
+       style="fill:none;stroke:#1162ff;stroke-width:1.74105036;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="rect3804-0"
+       width="97.241943"
+       height="38.954079"
+       x="102.40762"
+       y="276.32178" />
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+       x="135.62039"
+       y="300.90411"
+       id="text3806-0"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3808-5"
+         x="135.62039"
+         y="300.90411"
+         style="font-size:14px">RAM</tspan></text>
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke:#a90021;stroke-width:1.74702513;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="rect3804-2-8"
+       width="97.241943"
+       height="10.884984"
+       x="102.40762"
+       y="328.17947" />
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+       x="135.98953"
+       y="336.53046"
+       id="text3856-29"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3858-96"
+         x="135.98953"
+         y="336.53046"
+         style="font-size:8px">IO MEM</tspan></text>
     <g
        transform="translate(201.9358,161.75951)"
        id="g3860-9" />
-    <g
-       id="g3930"
-       transform="translate(-13.879333,-2.1428528)">
-      <rect
-         y="203.79074"
-         x="285.71429"
-         height="202.85715"
-         width="102.85714"
-         id="rect2985-3"
-         style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
-      <rect
-         style="fill:#ffffff;fill-opacity:1;stroke:#800080;stroke-width:1.17395353;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
-         id="rect3804-2-0"
-         width="100.7062"
-         height="10.883288"
-         x="84.853966"
-         y="215.42989"
-         transform="translate(201.9358,161.75951)" />
-      <text
-         xml:space="preserve"
-         style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
-         x="290.09793"
-         y="385.34314"
-         id="text3856-4"
-         sodipodi:linespacing="125%"><tspan
-           sodipodi:role="line"
-           id="tspan3858-8"
-           x="290.09793"
-           y="385.34314"
-           style="font-size:8px">Program. interval timer</tspan></text>
-      <g
-         id="g3860-5"
-         transform="translate(201.18264,141.05139)">
-        <rect
-           style="fill:#ffffff;fill-opacity:1;stroke:#800080;stroke-width:1.17395353;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
-           id="rect3804-2-1"
-           width="100.7062"
-           height="10.883288"
-           x="85.607124"
-           y="215.42989" />
-        <text
-           xml:space="preserve"
-           style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
-           x="113.61647"
-           y="223.78365"
-           id="text3856-2"
-           sodipodi:linespacing="125%"><tspan
-             sodipodi:role="line"
-             id="tspan3858-9"
-             x="113.61647"
-             y="223.78365"
-             style="font-size:8px">8250 UART</tspan></text>
-      </g>
-    </g>
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1.75578213;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="rect2985-3"
+       width="101.02946"
+       height="202.84319"
+       x="272.74881"
+       y="201.65488" />
+    <rect
+       y="375.05664"
+       x="274.52075"
+       height="10.884984"
+       width="97.485542"
+       id="rect3804-2-0"
+       style="fill:#ffffff;fill-opacity:1;stroke:#a90021;stroke-width:1.74921203;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+    <text
+       sodipodi:linespacing="125%"
+       id="text3856-4"
+       y="383.20029"
+       x="276.2186"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;stroke-width:3.54330709;stroke-miterlimit:4;stroke-dasharray:none"
+       xml:space="preserve"><tspan
+         style="font-size:8px;stroke-width:3.54330709;stroke-miterlimit:4;stroke-dasharray:none"
+         y="383.20029"
+         x="276.2186"
+         id="tspan3858-8"
+         sodipodi:role="line">Program. interval timer</tspan></text>
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke:#a90021;stroke-width:1.749;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+       id="rect3804-2-1"
+       width="97.485542"
+       height="10.884984"
+       x="274.52075"
+       y="354.34531" />
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
+       x="300.91977"
+       y="362.6922"
+       id="text3856-2"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3858-9"
+         x="300.91977"
+         y="362.6922"
+         style="font-size:8px">8250 UART</tspan></text>
     <text
        xml:space="preserve"
        style="font-size:8px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:DejaVu Sans;-inkscape-font-specification:DejaVu Sans"
index 9c223163ac04afc7cb3536aacaf598398e36402d..f14a26ce65b6c524edd9fb2869e85e9ade5d37ac 100644 (file)
@@ -25,6 +25,9 @@
 % Against footnote breaking into more pages
 \interfootnotelinepenalty=10000
 
+\clubpenalty 10000 % prvni radek odstavce nebude sam na konci stranky
+\widowpenalty 10000 % posl. radek odstavce nepujde na novou stranku 
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Zvolte jednu z moznosti 
 % Choose one of the following options
@@ -201,7 +204,16 @@ Rád bych poděkoval Ing. Pavlu Píšovi, Ph.D., za věcné rady a připomínky.
  
 \abstractpage
 
-FIXME
+The goal of this article is to describe the main principles of PCI driver
+development for the GNU/Linux operating system. Apart from the general PCI
+driver development, implementation of UIO and Comedi drivers is also described.
+
+Humusoft MF624 and MF614 cards were chosen as exemplary devices. Basic
+functions (D/A, A/D converters, digital inputs/outputs) of Humusoft
+MF624 card were implemented into the Qemu emulator, so that it is possible
+to try out all of the described procedures without physical access to the card.
+
+
 \vglue60mm
 
 \noindent{\Huge \textbf{Abstrakt}}
index 18d5572e37cedd3bea204f35e005195e44f4a4e0..7881b6574d62485a25625b7f461c7123e94e9624 100644 (file)
@@ -40,7 +40,7 @@
 }
 
 @MISC{uio_doc,
-       author = {Hans-Jürgen Koch},
+       author = {{Hans-Jürgen} Koch},
        title = {{The Userspace I/O HOWTO}},
        year = {2006--2009},    
        note = {\\\url{http://www.kernel.org/doc/htmldocs/uio-howto.html}},