next up previous contents
Next: Final Up: Plotterul PLINT Previous: Bufferul de comenzi   Cuprins

Executia efectiva

Pentru intarzieri de ordinul sutelor de microsecunde si de ordinul milisecundelor se foloste ceasul in timp real (RTC) al calculatorului, la o frecventa dee 4096Hz. Pentru comandare RTC se foloste interfata driverului care vine odata cu nucleul de Linux. Din pacat, acesta nu ofera suport pentru aplicatii nucleu (cum este acest driver plint), ci doar pentru spatiul utilizator (adica nu exporta simboluri). Din fericire, s-au realizat patch-uri anume pentru comanda motoarelor care necesita timpi de acest ordin de intarziere.

Mai intai, pentru a folosi RTC procesul care print-un apel sistem sau intrerupere a ajuns in mod nucleu trebuie sa se inregistreze la driver. Doar un singur proces poate folosi driverul RTC la un moment dat (asa si driverul plint). Apoi, cand se doreste o anumita intarziere se activeaza intreruperile periodice (PIEnable) si se seteaza un contor in functie de raportul dintr 4096Hz si intarzierea dorita (calculul e foarte usor, doar prin niste shiftari pe biti); procesul intra apoi in ``sleep'', pe o coada proprie de asteptare. La inregistrare s-a specificat o functie callback care e apelata la fiecare intrerupere de la RTC. Pe aceasta functie se decrementeaza contorul (bineinteles, in context utilizator altul decat al procesului de desenare, dar in mod nucleu, pe intrerupere); cand ajunge la 0, procesul se desteapta, folosind argumentul de pe stiva, care identifica coada de asteptare.

Beneficiind de acest tip de intarzieri, calculatorul va merge in paralel cu desenarea.

Fazele anterioara in care s-au aflat alimentarile motoarelor se memoreaza de la o deplasare la alta. Exista posibilitatea folosirii mai multor moduri de succesiune a fazelor. S-a ales modalitatea numita in semipasi. Caracteristicile plotterului sunt stocate intr-o structura de forma:
\begin{lstlisting}{language=C}
static struct
{
\par char ver[4];
int xadv, xste...
...e[PLOT_AX_NO][16];
unsigned long wait[4]; /* microseconds */
}
\end{lstlisting}

Cele folosite cu succes sunt:
\begin{lstlisting}[language=C]
''1.2''
1500, 200, 1500, 200,
8, {
{1<<0,1<<0...
...7,1<<7,1<<7\vert 1<<4}
},
{ 64, 2048+1024, 1024*64, 1024*16 }
\end{lstlisting}

Odata stabilit plotterul curent printr-un pointer ``p'' la aceasta structura, modul de comanda a fazei urmatoare, functie de directie, uziteaza de urmatoarele macrouri:


\begin{lstlisting}{language=C}
typedef enum
{
\par PLOT_CMD_BACKWARD = -1,
PLO...
...>phase[a][i[a]]; \
NEXT (PLOT_CMD(a)); \
} \
phase (h); \
})
\end{lstlisting}


next up previous contents
Next: Final Up: Plotterul PLINT Previous: Bufferul de comenzi   Cuprins
Sebastian Glita 2002-06-19