Linux Parino-mini-HOWTO
v2.2, 11 september 2004
Bart Geverts <web(at)sys1(dot)ath(dot)cx>
Licentie: GFDL 1.2
Deze howto beschrijft hoe je de Parino onder Linux kan gebruiken.
Inhoud
1. Introductie
2. Algemene informatie
3. De uitgangen
4. De ingangen
5. Toegang
6. inb() en outb()
7. Software
8. Toepassingen
9. Links
10. Download
1. Introductie
Parino is een afkorting welke staat voor:
PARallel
||| INput
||| || Output
||| || |
||| || |
------------+
PAR-IN-O = PARINO
De PARINO (meer hierover) is een kaart waarmee de PC grip kan krijgen op zijn omgeving. Het geheel wordt op een printerpoort van de PC aangesloten en kan via twaalf relais en vijf ingangen respectievelijk actie ondernemen en waarnemingen doen.
De PARINO wordt geleverd met besturingssoftware welke alleen geschikt is voor DOS. Om de PARINO ook onder Linux te kunnen gebruiken heb ik een stukje software ontwikkeld en deze korte 'HOWTO' geschreven.
De PARINO kaart heeft 12 relaisuitgangen. Dat houdt in dat er 12 aparte schakelaars op zitten die ieder afzonderlijk aan of uit gezet kunnen worden. Ieder schakelaar is een relais dat er voor zorgt dat er geen verbinding bestaat tussen de spanning die geschakeld wordt en de spanning in de computer. Hierdoor wordt het inwendige van je PC beschermd.
Om verwarring te voorkomen heb ik in de Linux-software de namen van de uitgangen hetzelfde gelaten als de namen die onder DOS worden gebruikt. De uitgangen heten achtereenvolgens 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B en C.
De kaart heeft verder 5 ingangen. Een ingang is een aansluiting die door de
computer kan worden ingelezen. Met ander woorden, het is een vorm van
terugkoppeling naar de computer toe. Wanneer er een sensor op wordt
aangesloten, kan de PC bijvoorbeeld weten of de temperatuur te hoog is of
niet.
Ook de 5 ingangen zijn "galvanisch gescheiden" van de computer. Dat betekent
dat er geen stromen lopen tussen sensor en computer. In de praktijk gebeurt
dit door met zogenaamde optische koppelingen te werken. Zo'n optische
koppeling bestaat uit een lampje en een lichtgevoelige cel. Wanneer het
lampje uit is, dan meet de computer een andere waarde dan wanneer het lampje
aan is. Hierdoor voorkomt een foute aansluiting aan een ingang, schade aan de
computer zelf.
Om verwarring te voorkomen heb ik in de Linux-software de namen van de ingangen hetzelfde gelaten als de namen die onder DOS worden gebruikt. De ingangen heten achtereenvolgens P, Q, R, S en T.
2. Algemene informatie
BASE is het basisadres van de printerpoort. Dit basisadres is, afhankelijk van de configuratie 0x3bc, 0x378 of 0x278. Om de Parino te besturen worden drie poorten gebruikt:
- BASE : Datapoort
- BASE+1 : Statuspoort
- BASE+2 : Controlpoort
BASE (Datapoort) is een Write-Only poort. Een lees-opdracht geeft de laatst geschreven waarde terug. Via deze poort worden de relais 2, 3, 4, 5, 6, 7, 8 en 9 aan en uit gezet.
BASE+1 (Statuspoort) is een Read-Only poort. Op deze poort wordt de status van de ingangen P, Q, R, S en T opgevraagd. Schrijven naar deze poort heeft geen effect.
BASE+2 (Controlpoort) is een Write-Only poort. Een lees-opdracht geeft de laatst geschreven waarde terug. Via deze poort worden de relais 1, A, B en C aan en uit gezet.
Om vanuit een userspace programma direct naar/van poorten te schrijven/lezen, moet je je programma hiervoor de rechten geven. Dat kan je doen met de ioperm() functie. Bij een kernelmodule is dat niet nodig.
Programma's die gebruik maken van de ioperm() functie kunnen in principe alleen door root worden uitgevoerd. Verderop in deze howto zal worden uitgelegd hoe ook andere users gebruik kunnen maken van deze programma's.
3. De uitgangen
Om de schakelaars 2 tot en met 9 aan of uit te zetten moet er een byte naar poort BASE worden geschreven volgens onderstaande tabel.
+------------+--------------+--------------+ | schakelaar | byte (hex) | byte (bin) | +------------+--------------+--------------+ | 2 | 0x01 | 0000 0001 | | 3 | 0x02 | 0000 0010 | | 4 | 0x04 | 0000 0100 | | 5 | 0x08 | 0000 1000 | | 6 | 0x10 | 0001 0000 | | 7 | 0x20 | 0010 0000 | | 8 | 0x40 | 0100 0000 | | 9 | 0x80 | 1000 0000 | +------------+--------------+--------------+
Om meerdere schakelaars aan te zetten worden de bytes van de schakelaars geORed. B.v. om schakelaar 2 en 3 aan te zetten:
bin: hex:
0000 0001 0x01
0000 0010 0x02
--------- OR ---- OR
0000 0011 0x03
moet dus 0x03 naar poort BASE worden geschreven.
De logica achter de schakelaars 1, A, B en C is iets ingewikkelder, maar wordt in de volgende tabel verklaard. Ook alle mogelijke combinaties getoond.
+------------+--------------+--------------+-------------------+ | schakelaar | waarde (hex) | waarde (bin) | bit 0, 1 en 3 inv | +------------+--------------+--------------+-------------------+ | - | 0x0b | 0000 1011 | 0000 0000 | | 1 | 0x0a | 0000 1010 | 0000 0001 | | A | 0x09 | 0000 1001 | 0000 0010 | | 1A | 0x08 | 0000 1000 | 0000 0011 | | B | 0x0f | 0000 1111 | 0000 0100 | | 1B | 0x0e | 0000 1110 | 0000 0101 | | AB | 0x0d | 0000 1101 | 0000 0110 | | 1AB | 0x0c | 0000 1100 | 0000 0111 | | C | 0x03 | 0000 0011 | 0000 1000 | | 1C | 0x02 | 0000 0010 | 0000 1001 | | AC | 0x01 | 0000 0001 | 0000 1010 | | 1AC | 0x00 | 0000 0000 | 0000 1011 | | BC | 0x07 | 0000 0111 | 0000 1100 | | 1BC | 0x06 | 0000 0110 | 0000 1101 | | ABC | 0x05 | 0000 0101 | 0000 1110 | | 1ABC | 0x04 | 0000 0100 | 0000 1111 | +------------+--------------+--------------+-------------------+ opm: De bits 4, 5, 6 en 7 staan hier voor de volledigheid, maar spelen geen rol.
In de laatste kolom zijn de bits 0, 1 en 3 geinverteerd. Dit is ooit door IBM bedacht, maar waarom is mij niet helemaal duidelijk. Als je hier meer over wil lezen, kijk dan eens in de IBM Parallel Port FAQ/Tutorial.
Om meerdere schakelaars aan te zetten worden de bytes, nadat de bits 0, 1 en 3 geinvereerd zijn, geORed. B.v. om schakelaar 1 en A aan te zetten:
bin: hex:
0000 1010 --inv-> 0000 0001 0x0a --inv-> 0x01
0000 1001 --inv-> 0000 0010 0x09 --inv-> 0x02
--------- OR ---- OR
0000 1000 <-inv-- 0000 0011 0x08 <-inv-- 0x03
moet dus 0x03 naar poort BASE+2 worden geschreven.
4. De ingangen
Om de ingangen P, Q, R, S en T op te vragen moet er een byte van poort BASE+1 worden gelezen. De ingelezen byte komt overeen met de ingangen zoals vermeld in onderstaande tabel.
+------------+------------+-------------+--------+ | byte (hex) | byte (bin) | bit 0-6 inv | ingang | +------------+------------+-------------+--------+ | 0x3f | 0011 1111 | 0100 0000 | P | | 0xff | 1111 1111 | 1000 0000 | Q | | 0x5f | 0101 1111 | 0010 0000 | R | | 0x6f | 0110 1111 | 0001 0000 | S | | 0x7f | 0111 0111 | 0000 1000 | T | +------------+------------+-------------+--------+
Hier moeten behalve bit 7, alle bits worden geinverteerd. Dit is ooit door IBM bedacht, maar waarom is mij niet helemaal duidelijk. Als je hier meer over wil lezen, kijk dan eens in de IBM Parallel Port FAQ/Tutorial.
5. Toegang
Om vanuit userspace een poort te bereiken, moet je je programma hier toegang toe geven. Dat kan met de functie ioperm(). De syntax van deze functie is: ioperm(<from>, <num>, <turn_on>). Ioperm zet de poort toegang bits van <num> poorten vanaf adres <from> op <turn_on>. Met ioperm() kan je alleen de eerste 0x3ff I/O poorten bereiken, maar dat maakt in dit geval niets uit omdat de hoogst mogelijke poort (0x378) daar nog onder valt. De ioperm() aanroep vereist van het programma dat het root-privilages heeft; je moet om het programma runnen dus als root zijn ingelogd of je moet met setuid aan de gang gaan. Meer informatie over ioperm() is te vinden in 'man ioperm'. In het hoofdstuk 'Webinterface' is meer te lezen over toegang voor non-root.
6. inb() en outb()
Om naar/van poorten te schrijven/lezen moet je gebruik maken van de functies inb() en outb(). Met inb(<port>) lees je een byte in van poort <port>. Met de functie outb(<value>, <port>) schrijf je een waarde <value> naar poort <port>*. *: Deze volgorde is net anderom dan onder DOS gebruikelijk is.
7. Software
In de loop der jaren heb ik meerdere stukjes software in elkaar gerommeld, variërend van buggy userspacetools tot iets dat serieus op een kernelmodule lijkt. Om hier serieus mee aan de gang te gaan adviseer ik om de recentste code te gebruiken, maar ter 'leering en vermaeck' zijn ook m'n oudere creaties hier te vinden.
De eerste versie is 'parinotools-1.0' gedoopt en bestaat uit drie eenvoudige commandline tooltjes om relais aan en uit te zetten en om de status uit te lezen. In de daaropvolgende 'parinotools-2.01' zijn deze tooltjes samengevoegd in één executable en is het geheel wat gestroomlijnder gemaakt. In de recentste versie is het compleet anders aangepakt. De 'parinodrv-2.6' bestaat uit een kernelmodule (Linux 2.6.x). Via /dev/parino zijn de relais te besturen in uit /proc/parino kan de status worden uitgelezen.
Onder aan deze pagina zijn de downloadlinkjes te vinden.
parinotools-1.0
set
Met het programma set is het mogelijk om vanaf de commandline een schakelaar
op de PARINO te SETten. De naam van de schakelaar wordt als parameter
meegegeven. B.v. met de opdracht 'set 8' wordt schakelaar 8 geSET. Andere
schakelaars worden hierdoor niet beinvloed omdat het programma eerst op
poort BASE en BASE+2 opvraagt welke schakelaars er zijn geSET. De waarde die
bij schakelaar 8 hoort wordt hiermee geORed en het resultaat wordt naar
BASE of BASE+2 geschreven. Op het moment dat ik deze howto schrijf is versie
1.0 de laatste versie van set. Deze versie heb ik een paar weken in de
praktijk gebruikt en ik heb geen fouten kunnen ontdekken.
unset
Het programma unset is de tegenhanger van het programma set, en zorgt ervoor
dat vanaf de commandline een schakelaar geUNSET kan worden. De syntax van
unset is gelijk aan die van set en het beinvloed de ander schakelaars niet
omdat de waarde van de gewenste schakelaar wordt geNOT en geAND met de huidige
waarde op BASE of BASE+2. Omdat de omtwikkeling van dit programma synchoon
loopt met set, is ook hiervan de laatste versie 1.0. Ook in deze unset v0.9
heb na een paar weken gebruiken geen foutjes kunnen ontdekken.
status
Om te controleren welke schakelaars er geSET zijn en op welke ingangen een
spanning staat is het programma status geschreven. Het programma status wordt
zonder parameters gestart waarna het op het scherm alle geSETte schakelaars
weergeeft en de ingangen waarop een spanning staat. De laatste versie van
status is versie 1.0 en ook dit programma lijkt nu goed te werken.
parinotools-2.1
In versie 2.1 zijn deze tools samengevoegd in 1 programma. Versie 2.0 bevatte wat bugjes, welke in versie 2.1 zijn gefixed. De syntax is als volgt:
# parino
Het programma zonder parameters geeft de status van de Parino. Alle geSETte relais en ingangen waar spanning op staan worden als 1 string weergegeven.
# parino <parameter>
Als er een parameter wordt opgegeven moet deze beginnen met een '+' of een '-'. Alle relais-namen achter de '+' worden geSET. De '-' zorgt ervoor dat alle opgegeven relais geUNSET worden. Enkele voorbeelden:
# parino +18A
Zorgt ervoor dat de relais 1, 8 en A worden geSET. De syntax wijkt enigzins af van de syntax van de DOS software waarbij in 1 keer meerdere relais geSET en geUNSET kunnen worden. In deze Linux-versie is dat niet mogelijk.
In versie 2.01 wordt gebruik gemaakt van een configuratie bestand dat na installatie is te vinden in /etc/parino.conf. In dit bestand worden de volgende gegevens vastgelegd:
- Basisadres van de printerpoort
- Namen van de relais
- Namen van de ingangen
parinodrv-2.6
Eenmalig de device node maken met "make node". Hoe en of dat met devfsd en udev werkt weet ik niet. Module compileren met "make". Module laden met "insmod ./parino.ko".
Relais 3, 4 en 8 AAN en 1, A en B UIT zetten:
# echo "+348-1AB" > /dev/parino
Status uitlezen:
cat /proc/parino
Basisadres van de printerpoort
Afhankelijk van de configuratie is dat 0x3bc, 0x378 of 0x278. Default staat deze op 0x3bc, omdat dat in mijn configuratie het adres van de printerpoort is. Maar in de meeste gevallen zal dat 0x378 zijn.
Namen van de relais en de ingangen
Default zijn deze namen gelijk aan de namen die onder DOS worden gebruikt. Voorlopig kunnen deze namen bestaan uit slechts 1 letter of cijfer. In toekomstige versies moet het mogelijk zijn om ook langere namen te kunnen gebruiken.
8. Toepassingen
Met behulp van de cron-deamon is het mogelijk om op gezette tijden bepaalde handelingen te verrichten. Als je b.v. elke ochtend om half acht verse koffie wilt, is dat met cron eenvoudige te automatiseren. Meer informatie hierover is te vinden in 'man cron', 'man 1 crontab' en 'man 5 crontab'.
Zelf ben ik eens creatief geweest met LEGO en heb ik een soort van lopende band gemaakt. Op die band lagen porties vissenvoer en een paar keer per dag kregen mijn twee goudvissen automatische te eten. Na ee tijdje waren die beesten zijn al zover dat als ze de band horen lopen, gelijk naar boven kwamen zwemmen. Intussen zijn ze allebei dood (ouderdom, niet door gebrek aan voer :) ).
9. Links
IBM Parallel Port FAQ/Tutorial
http://s.teoma.com/search?submit=Search&q=IBM+Parallel+Port+FAQ%2FTutorial
10. Download
parinotools-1.0.tar.gz: Deze versie is helaas ergens verloren gegaan. :-(
parinotools-2.1.tar.gz: Userspacetooltje om de parino te bedienen.
parinodrv-2.6.2.tar.gz: Parino kernelmodule die werkte tot linux-2.6.5.
parinodrv-2.6.8.tar.gz: Parino kernelmodule die werkt op linux-2.6.8 en latere kernels. Vermoedelijk ook op oudere 2.6 kernels.