]> rtime.felk.cvut.cz Git - mf6xx.git/commitdiff
Diploma thesis text.
authorRostislav Lisovy <lisovy@gmail.com>
Sun, 10 Apr 2011 00:36:17 +0000 (02:36 +0200)
committerRostislav Lisovy <lisovy@gmail.com>
Sun, 10 Apr 2011 00:36:17 +0000 (02:36 +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 0ff5858256c9e802a1e89ba0d5ce65f1dcb8a65d..cca4f04b38ac2ed7b12f4df0ec46726c74da1ea4 100644 (file)
@@ -1,34 +1,66 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\chapter{Motivace, cíl}
+\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ích vývoj ovladačů (v tomto případě PCI zařízení) pro operační systém GNU/Linux.
 
 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. Text obsahuje pouze nezbytné množství teorie, která je podložená četnými příklady pro snadnější pochopení čtenářem. Pro čtenáře neznalého psaní programů těsně svázaných s hardwarem se snažím názorně vysvětlit 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}.
 
 Kromě samotného popisu vývoje PCI ovladačů je cílem práce částečně implementovat funkce karty Humusoft MF624 do emulačního programu Qemu tak, aby si případný zájemce mohl vše vyzkoušet, aniž by fyzicky vlastnil hardware.
+
+\section{Dostupné materiály}
+V českém jazyce dosud vyšla pouze jedna tištěná kniha, která se zabývá problematikou vývoje pro jádro Linux. Jedná se o knihu \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}
+
+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 studenta nižšího ročníku, neznalého vývoje jaderných ovladačů zařízení nemá příliš velký přínos.
+
+Za nejpřínosnější knihu, zabývající se psaním ovladačů pro Linux, považuji anglicky psanou knihu \cite{devicedriver} od autorů Jonathan Corbet, Alessandro Rubini a Greg Kroah-Hartman. Knihu je možné stáhnout zdarma ve formátu PDF\footnote{\url{http://lwn.net/Kernel/LDD3/}}.
+
+\begin{figure}[h!]
+       \begin{center}
+       \begin{minipage}[b]{0.4\linewidth}
+               \includegraphics[width=50mm]{img/jadro-systemu-linux.jpg}
+       \end{minipage}
+       \begin{minipage}[b]{0.4\linewidth}
+               \includegraphics[width=50mm]{img/lddrivers.jpg}
+       \end{minipage}
+       \caption{\textit{Vlevo}: Kniha Lukáše Jelínka (v českém jazyce). 
+               \textit{Vpravo}: kniha od autorů Jonathan Corbet, Alessandro Rubini a Greg Kroah-Hartman (v anglickém jazyce)}
+       \label{knihy}
+       \end{center}
+\end{figure}
+
+
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Hardware}
-\section{Komunikace s hardwarem}
-Jak je možné ovládat hardware pomocí programu (software) je nejsnazší ukázat na příkladu jednočipového počítače.
+\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.
 
-\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é. Příklady zařízení obsažených v mikrokontroléru: 
+\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}
-\item[GPIO piny (General Purpose Input/Output)] -- u těch je možné nastavit, zda chceme jejich hodnotu číst (a je k nim tedy připojeno jiné zařízení) nebo zda chceme jejich hodnotu nastavovat.
-\item[A/D převodník] -- Převádí analogový (spojitý) signál na diskrétní (nespojitý). Příklad: Na vstup A/D převodníku přivedeme napětí 2,4 V. Z registru odpovídajícímu tomuto převodníku si v digitální podobě mikroprocesor vyčte hodnotu odpovídající 2,4.
-\item[D/A převodník] -- Opačně od A/D převodníku převádí digitální signál na analogový. Příklad: Do registru odpovídajícímu D/A převodníku zapíše mikroprocesor hodnotu odpovídající např. 3,5 V. Na výstupu bude možné změřit napětí 3,5 V (s určitou malou odchylkou).
-\end{description}
+\item[GPIO piny (General Purpose Input/Output)] -- u těchto pinů je možné nastavit, zda má být jejich hodnota čtena (slouží jako vstupní piny -- skrze ně vstupuje informace) nebo zda chceme jejich hodnotu nastavovat (tj. výstupní piny).%
+%\item[A/D převodník] -- Převádí analogový (spojitý) signál na diskrétní (nespojitý). Příklad: Na vstup A/D převodníku přivedeme napětí 2,4 V. Z registru odpovídajícímu tomuto převodníku si v digitální podobě mikroprocesor vyčte hodnotu odpovídající 2,4.
+%\item[D/A převodník] -- Opačně od A/D převodníku převádí digitální signál na analogový. Příklad: Do registru odpovídajícímu D/A převodníku zapíše mikroprocesor hodnotu odpovídající např. 3,5 V. Na výstupu bude možné změřit napětí 3,5 V (s určitou malou odchylkou).
+\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}}
 
-%\begin{figure}[h!]
-%      \begin{center}
-%      \includegraphics[width=80mm]{img/msp430g2x01.png}
-%      \caption{Architektura velmi jednoduchého mikroprocesoru MSP430G2x01 firmy Texas Instruments.}
-%      \label{microcontroller}
-%      \end{center}
-%\end{figure}
+\begin{figure}[h!]
+       \begin{center}
+       \includegraphics[width=130mm]{img/gpio.pdf}
+       \caption{Registr odpovídající GPIO pinům. Změnou tohoto registru je možné měnit chování GPIO pinů}
+       \label{gpio_pins}
+       \end{center}
+\end{figure}
 
-}
 
-V případě, že budeme chtít změnit hodnotu GPIO pinu, je první možností 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 mikrokontrolerů/\-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 jsme zapisovali, 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 výstupní hodnoty 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}}
+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 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. 
+
 
 \begin{figure}[h!]
        \begin{center}
@@ -38,17 +70,15 @@ V případě, že budeme chtít změnit hodnotu GPIO pinu, je první možností
        \end{center}
 \end{figure}
 
-Jiným přístupem je při zápisu/čtení do/ze zařízení použití jiné instrukce než kterou používáme pro paměťové operace -- tj. místo zápisu na adresu v paměťovém prostoru vyhrazenou pro GPIO, provedeme zápis do tzv. \textbf{vstupně-výstupní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 přesně vědět jak široká (kolikabitová) slova smíme zapisovat/číst. 
 
-\ibox{
 Hlavní rozdíly mezi chováním paměťové buňky a registru zařízení jsou:
 \begin{itemize}
-\item Zápisem do registru můžeme měnit stav zařízení odpovídajícího registru.
+\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í hodnoty registru může být spuštěn tzv. \textit{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).
-\item Při zápisu a čtení do/z registru si musíme být vědomi toho, kolikabitové operace zápisu/čtení smíme používat (8-, 16-, 32bitové).
+\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é).
 \end{itemize}
-}
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \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í.
@@ -59,6 +89,8 @@ Komunikace mezi zařízeními připojenými na sběrnici a procesorem zajišťuj
 
 \subsection{Historie}
 
+\subsection{Konektory}
+
 \begin{figure}[h!]
        \begin{center}
        \begin{minipage}[b]{0.4\linewidth}
@@ -111,7 +143,7 @@ V posledních letech je na poli osobních počítačů PCi sběrnice nahrazován
        \begin{center}
        \includegraphics[width=150mm]{img/mf624.jpg}
        \caption{Měřící karta Humusoft MF624}
-       \label{sa1}
+       \label{mf624}
        \end{center}
 \end{figure}
 
@@ -226,7 +258,9 @@ 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.
 \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 typu FIFO nebo mnohem jednodušší je čtení z jeho zrcadlených hodnot v registrech ADDATA0--ADDATA7 (v manuálu jsou označeny pouze jako \textit{BADR1 + 0x02} až \textit{BADR1 + 0x0E}).
+\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 vyčteme jednotlivé naměřené hodnoty z aktivovaných A/D převodníků v pořádí od 0 k 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 pouze 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 p 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}
 
 Hodnota vyčtená z A/D převodníků je ve formátu dvojkového doplňku -- příklad konkrétních hodnot je v tabulce \ref{tab_adval}.
@@ -483,7 +517,63 @@ Tato funkce by se měla postarat o úklid všech naalokovaných prostředků apo
 \item[\texttt{pci\_disable\_device()}]~\\Opak k volání \texttt{pci\_enable\_device()}.
 \end{description}
 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\section{Přístup k paměti zařízení}
+Poté co se ovladači podařilo získat přístup ke zdrojům zařízení, je nutné využít speciálních volání pro zápis/čtení do/z těchto zdrojů.
+
+\subsection{Vstupně-výstupní adresní prostor}
+Stejně jako program v jazyku symbolických instrukcí využívá pro přístup k vstupně-výstupnímu adresnímu prostoru (tj. I/O portům) zvláštní instrukce, je nutné využít speciální funkce v programech psaných ve \textit{vyšších} programovacích jazycích. V případě čtení jsou v jádře k dispozici tři volání:
+
+\ibox{\texttt{unsigned inb(unsigned port);}}
+
+\ibox{\texttt{unsigned inw(unsigned port);}}
+
+\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.
+
+Pro zápis je možné využít volání:
+\ibox{\texttt{void outb(unsigned char byte, unsigned port);}}
+
+\ibox{\texttt{void outw(unsigned char byte, unsigned port);}}
+
+\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á.
+
+Stejná volání je možné používat i z uživatelského prostoru (potřebný hlavičkový soubor je \texttt{<sys/io.h>}).
+\subsection{Paměťový adresní prostor}
+I přesto, že se k přístupu k paměti zařízení mapované do paměťového adresního prostoru používá virtuální adresa, stejně jako k přístupu do operační paměti, není možné k paměti zařízení přistupovat přímo \textit{přes ukazatel}. Důvodem je to, že buď překladač (při kompilaci) nebo procesor (za běhu) zoptimalizují\footnote{Tyto optimalizace, v případě přístupu k operační paměti, urychlují vykonávání programu, aniž by negativně ovlivnily jeho funkci. V případě zápisu/čtení do/z registrů, u kterých mohou tyto operace vyvolávat tzv. \textit{side effects}, již může dojít k nesprávné funkci programu.
+
+Příklad optimalizace: V programu se do jedné paměťové buňky ihned po sobě zapíší dvě různé hodnoty, poté se výsledná hodnota přečte -- optimalizace možná u klasického programu je taková, že se ve skutečnosti provede pouze druhý zápis, protože ten první nemá žádný efekt (hodnota je ihned přepsána druhým zápisem). V případě přístupu do registru zařízení může zápis například spouštět převod A/D převodníků -- po optimalizaci se však provede pouze jednou, nikoliv dvakrát.} sekvenci zápisů/čtení do/z paměti zařízení takovým způsobem, že se výsledek bude lišit od toho, jak to bylo v programu zamýšleno.
+
+Těmto optimalizacím lze nejsnáze zabránit použitím volání:
+
+\ibox{\texttt{unsigned int ioread8(void *addr);}}
+
+\ibox{\texttt{unsigned int ioread16(void *addr);}}
+
+\ibox{\texttt{unsigned int ioread32(void *addr);}}
+
+pro čtení a volání
+
+\ibox{\texttt{void iowrite8(u8 value, void *addr);}}
+
+\ibox{\texttt{void iowrite16(u16 value, void *addr);}}
+
+\ibox{\texttt{void iowrite32(u32 value, void *addr);}}
+
+pro zápis. Číslo na konci funkce označuje o kolikabitový 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);}} 
+nebo v případě PCI zařízení funkce
+\ibox{\texttt{void \_\_iomem *pci\_iomap(struct pci\_dev *dev, int bar, unsigned long maxlen);}}
+
+je tato paměť \textit{přemapována} do paměťového adresního prostoru a je nutné pro přístup k ní používat výše popsaná volání.
+
+Z uživatelského prostoru je potřeba používat volání FIXME.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{UIO ovladač}
@@ -607,18 +697,53 @@ Příklad, jak takové volání může vypadat (bez ošetření chybný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řeba udělat \textit{posun} pomůže zjistit soubor \texttt{/sys/class/uio/ /ui0/maps/map1/addr}\footnote{Pro názornost uvádím konkrétní cestu -- 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 uvádím konkrétní cestu -- 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
   \-- Ukazatel vrácený voláním mmap()                 
 \end{verbatim}
+
+\subsection{Přístup k paměti zařízení}
+Podobně jakou u jaderného modulu komunikujícího s pamětí zařízení, je potřeba i v uživatelském prostoru k této paměti přistupovat pomocí speciálních funkcí.
+FIXME
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \section{Comedi ovladač}
 UIO ovladač dává uživateli možnost využít 100 \% všech funkcí zařízení -- daní za to je pomalejší odezva než v případě plnohodnotného jaderného ovladače.
 
 Pro ovladače měřících karet existuje v Linuxu subsystém -- tzv. Comedi (Control and Measurement Device Interface).
 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\chapter{Testování}
+\section{UIO ovladač, Comedi ovladač}
+Jednotlivé ovladače jsou tvořeny samostatnými jadernými moduly, které pouze využívají volání jednotlivých subsystémů -- neexportují žádné \textit{symboly} ani nemění globální proměnné. V tomto případě nebylo nutné provádět regresní testování.
+
+Testování správnosti funkce ovladačů probíhala přímo na hardware, za pomoci \textit{univerzální svorkovnice TB620} (obrázek \ref{svorkovnice}).
+
+\begin{figure}[h!]
+       \begin{center}
+       \includegraphics[width=120mm]{img/svorkovnice.jpg}
+       \caption{Svorkovnice TB620.}
+       \label{svorkovnice}
+       \end{center}
+\end{figure}
+
+\vspace{1cm}
+Základní nastavení bylo:
+\begin{itemize}
+\item 2 $\times$ LED pro nejnižší bity DOUT
+\item 2 $\times$ 1k$\Omega$ rezistory mezi 5 V a nejnižšími bity DIN
+\item 2. bit DIN dynamicky spojován s GND nebo pomocí 1k$\Omega$ rezistoru s 5 V
+\item Měření multimetrem výstupní hodnoty z DAC (většinou DAC0 nebo DAC1)
+\item ADC0 spojen s GND, ADC1 spojen pomocí 1k$\Omega$ rezistoru s DAC0
+\end{itemize}
+
+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í}
+
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Závěr}
 
index f0ab6d2d22a6546ec5aac0f6ae356ba1d5435fe2..70ce828a5e2b02c6fba6111612b1fb753c022de3 100644 (file)
@@ -42,7 +42,7 @@
 %=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=%
 
 \setcounter{secnumdepth}{3}
-\setcounter{tocdepth}{3}
+\setcounter{tocdepth}{2}
 
 \def\ifndef#1{\expandafter\ifx\csname#1\endcsname\relax} % check whether macro is defined
 
index 0316f37455390def45c9e2468083f3d99dc4b16c..34cdbf0553c1f836dbeecd78702c77500a78e1a7 100644 (file)
@@ -14,7 +14,7 @@
  % \newcommand{\efig}{\end{center}\end{figure}}
  % umoznuje pouzit prikaz \bfig namisto \begin{figure}\begin{center} atd.
 
-\newcommand{\ibox}[1]{ \begin{center} \fbox{\parbox{14cm}{ #1 }} \end{center}}
+\newcommand{\ibox}[1]{\begin{center}\fbox{\parbox{14cm}{ #1 }}\end{center}}
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 % Pouzijete-li pdflatex, tak je prijemne, kdyz bude mit vase prace
 % funkcni odkazy i v pdf formatu
-       %\usepackage[
-       %pdftitle={\WorkTitle},
-       %pdfauthor={\FirstandFamilyName},
-       %bookmarks=true,
-       %colorlinks=true,
-       %breaklinks=true,
-       %urlcolor=red,
-       %citecolor=blue,
-       %linkcolor=blue,
-       %unicode=true,
-       %]
-       %{hyperref}
+       \usepackage[
+       pdftitle={Prostredi pro vyuku vyvoje PCI ovladacu do OS GNU/Linux}, %\WorkTitle
+       pdfauthor={\FirstandFamilyName},
+       bookmarks=true,
+       colorlinks=true,
+       breaklinks=true,
+       urlcolor=red,
+       citecolor=blue,
+       linkcolor=blue,
+       unicode=true,
+       ]
+       {hyperref}
 \usepackage{url}