
Linux I/O |[gvO~O mini-HOWTO

Riku Saikkonen

Riku.Saikkonen@hut.fi

JF Project - {

JF@linux.or.jp

v3.0, 2000-12-13

̃nEc[ł́ACe x86 vZbTővÓAn[
hEFA I/O |[g̃vO~OƁALinux ̃[U[hŒZԑ
ȂvOAȂǂɂďqׂ܂B



Table of Contents
1. Introduction
2. C vO I/O |[gg
    2.1. ʂ̕@
        2.1.1. p[~bV
        2.1.2. |[g̃ANZX
       
       
    2.2. I/O |[gANZXʂ̕@F/dev/port
   
   
3. 荞 (IRQ)  DMA ANZX
4. x̃^C~O
    4.1. fBC
        4.1.1. X[vFsleep()  usleep()
        4.1.2. nanosleep()
        4.1.3. |[gI/OgfBC
        4.1.4. AZu߂ɂfBC
        4.1.5. Pentiumrdtscɂ
       
       
    4.2. Ԃ̑
   
   
5. ̑̃vO~Oɂ
6. 悭g|[g
    6.1. p|[g
    6.2. Q[(WCXeBbN)|[g
    6.3. VA|[g
   
   
7. Hints
8. guV[g
9. vO̗
10. ӎ
11. {ɂ

1. Introduction

̃nEc[ł́ACe x86 vZbTővÓAn[
hEFA I/O |[g̃vO~OƁALinux ̃[U[hŒZԑ
ȂvOAȂǂɂďqׂ܂B͑Oɂ悤(Ƃ
) IO-Port-mini-HOWTO ܂A͂̑̕҂łB

̃hLg̒쌠 1995-2000 Riku Saikkonsen ɑ܂Bڍׂ
ւĂ͒ʏ Linux  HOWTO COPYRIGHT B

AȂɂԈႢAt邱ƂȂǂ܂為ЎɃ
CĂB(Riku.Saikkonen@hut.fi)

{łɂĂ̂wEAӌȂǂ܂ JF Project܂ł
܂B<JF@linux.or.jp>


2. C vO I/O |[gg

2.1. ʂ̕@

I/O |[gANZX邽߂̃[` /usr/include/asm/io.h (܂
J[l̃\[XpbP[W̒ linux/include/asm-i386/io.h) ɒ`
Ă܂BKvȃ[`́A̒ŃCC}NƂĒ`
܂̂ŁA#include <asm/io.h> Ƃ邾ŏ\ł傤BʂȃCu
Ȃǂ͕svłB

gcc (̒mSẴo[WAegcs ܂) ̐̂߁A
̃[`g\[XRpCɂAœKIɂ(
gcc -O1 ܂͂ȏ)A邢 #include <asm/io.h> ̑O #define
extern static Ƃ錾ȂĂKv܂B (Ƃ #undef
extern Ă̂YȂ悤ɁB)

fobÔ߂ɁA(ȂƂŋ߂ gcc ł) gcc -g -OgƂł
܂AœKꂽR[hł̓fobKςȋƂ܂B
̂悤ȏꍇɂ́AI/O |[gANZX܂񂾃R[hƗt@C
ɂĂāÃt@C̃RpC̎ɂœKIɂƂ
@gƂł܂B


2.1.1. p[~bV

|[gANZXOɁÃ|[gANZX鋖vOɗ^
Ȃ΂Ȃ܂Bɂ́Aioperm() ֐ (unistd.h Ő錾AJ
[l̒Œ`Ă)Ăяo܂B̊֐̓vO̍ŏ
( I/O |[gANZXO)ĂяoKv܂B̊֐̏
 ioperm(from, num, turn_on)łB from̓ANZX|[g̍ŏ
̃AhXA numfrom炢̘AAhX̃ANZXAw
肵܂BႦ΁Aioperm(0x300, 5, 1) ́A0x300  0x304 (v 5 
̃|[g)ɑ΂鋖w肵AŌ̃p[^ł́Ã|[gɑ΂
ANZX^̂֎~̂_l(true : 1 = ANZX
, false : 0 = ANZX֎~)Ŏw肵܂BAĂȂ|[g
̏ꍇɂ́Aioperm() ĂяoāAK؂ȋw肵܂B@
ڍׂɊւĂ ioperm(2) ̃}jAy[WQƂĂB

ioperm() Ăяoɂ́ÃvO root őĂ邱ƂK
vłB܂ÃvO[g[UŎs邩Asetuid root
(: st@C̃I[i[ root ɂĂAchmod 4755 hogehoge 
łB)ĂKv܂BKvȃ|[gɑ΂鋖
ioperm() ŗ^ƂɁAroot 𗎂Ƃł܂BvO̍
ŁAI ioperm(..., 0) Ăяoċ𗎂Kv͂܂B
̓vȌIɎIɍsȂ܂B

root ȊÕ[U setuid() 邱Ƃ ioperm() ̗^|[gANZX
ȂȂ邱Ƃ͂܂񂪁A fork() ƋȂȂ
B (qvZX̓ANZXĂ܂񂪁AevZX͎Ă
܂B)

ioperm() ł́A0x000  0x3ff ܂ł̃|[gɑ΂ANZX^
邱Ƃ͂ł܂B̃|[gɑ΂ẮAiopl() gKv
܂B (iopl() gƈxɂׂẴ|[gɑ΂ANZX
^邱ƂɂȂ܂B) ׂẴ|[gɑ΂ăANZX^ɂ
Axp[^Ƃāu3vg܂B܂Aiopl(3) Ƃ֐Ă
o܂B (Ԉ|[gɃANZXƂƂłȂƂN
m܂񂩂AgƂɂ͒ӂĂB) Aiopl() 
Ăяoɂ root KvłBڍׂɊւĂ iopl(2) ̃}jA
y[WQƂĂB


2.1.2. |[g̃ANZX

|[goCgf[^(8bit)͂ꍇɂ inb(port) Ăяo܂
B̊֐̓oCgf[^Ԃ܂B|[gɃoCgf[^o͂ɂ
Aoutb(value, port) Ăяo܂B (p[^̏Ԃɒӂĉ
B) (:AZuAMS-DOS ̃RpCCuȂǂ̏ꍇƂ͋t
B) |[gAhX x  x+1 烏[hf[^͂ꍇɂ inw(x)
Ăяo܂B(AZuinw Ƃ܂悤ɂꂼ̃|[g
 1 oCgǂłāA[hf[^\킯łB) ӂ
|[gɃ[h( 2 oCg)o͂ɂ outw(value, x) g܂Bǂ
̖(oCgf[^[hf[^)g΂̂ȂƂ
AAinb()  outb() g΂ł傤B̃foCX̓oCgP
ʂ̃|[gANZX悤݌vĂ܂B|[gANZX̖߂͂
ׂĎsɏȂƂ 1 }CNb̂ŒӂĂB

inb_p(), outb_p(), inw_p(), outw_p() Ƃ}ŃAɏqׂ̂Ɠ
܂A|[gɃANZXɏ( 1 }CNb) E
GCg܂B #include <asm/io.h> ̑O #define REALLY_SLOW_IO t
Ƃ̃EGCgԂ 4 }CNbɕς邱Ƃł܂B
}N͒ʏA0x80 Ԓn I/O |[gɏo͂邱ƂŃEGCg
܂B (#define SLOW_IO_BY_JUMPING ƂĂꍇɂ͕ʂ̕@g
܂A͂܂萳mȒxȂƂłȂ͂łB) 
悤ȗRA0x80 Ԓñ|[gɑ΂ ioperm() ɎsĂK
v܂B(0x80 Ԓñ|[gɑ΂o͂̓VXeɑ΂ĂȂe
^邱Ƃ͂Ȃ͂łB) ɂ܂܂ȒxsȂ@ɂ
ẮAȉǂݐi߂ĉB

ŋ߂̃[X Linux }jAy[Wɂ́A ioperm(2)  iopl
(2)Aq̃}NɊւ܂B


2.2. I/O |[gANZXʂ̕@F/dev/port

I/O |[gɃANZX̕@́Aopen() g /dev/port (L
N^foCXAW[ԍ 1A}Ci[ԍ 4)I[vāAread/
write ȂƂ@łB (stdio  f*() ֐(: fwrite() 
 fread() Ƃ...)͓Ńobt@OĂ̂ŁAg܂
B) I[vɁAo͂|[g̃AhX܂ lseek() ܂B
(file position 0 |[g 0x00 ɁAfile position 1 |[g 0x01 ... 
ɑ܂B) ̌ read(), write() găoCg/[
hǂݏ܂B

̕@gɂ́A񂻂̃vO /dev/port ɑ΂ read/
write ĂȂ΂Ȃ܂B̕@͏ɏqׂʏ̕@
炭xł傤ARpC̍œK ioperm() sv
Ƃ_܂B /dev/port ɑ΂ă[gȊÕ[UO[
ṽANZX^ root Kv܂Bł̓VXe
ZLeBƂӖł͂ƂĂǂȂƂłBƂ̂́A/dev/
port găn[hfBXNAlbg[NJ[hȂɒڃANZX
邱ƂŁAVXeɏQ^Aɂ root ^Ă܂
\邩łB

/dev/port ̓ǂݍ݂ɂ select(2)  poll(2) gƂ͂ł
܂BȂȂ̓|[g̒lωƂɁAn[hEFAɂ͂
CPUɓ`@\ȂłB


3. 荞 (IRQ)  DMA ANZX

[U[h̃vO璼ڂɊ荞݂ DMA gƂ͂ł܂
Bɂ́AJ[lhCo쐬Kv܂B̏ڍׂɂ
́uLinux J[lnbJ[YKChvA܂̗ƂẮAJ[l
\[XR[hǂŉB

[U[h̃vO犄荞݂֎~邱Ƃ́A댯𔺂܂
A\łB(J[lhCoł炻sƂ͂łZ
Ԃł̂łB) iopl(3) ĂяoƁAasm("cli"); Ăяo
Ŋ荞݂֎~邱Ƃł܂BĂъ荞݉\ɂɂ asm
("sti") Ăт܂B


4. x̃^C~O

4.1. fBC

܂ŏɒfĂ܂A[UvOɂĐmȃ^C~O
؂邱Ƃ͂ł܂B́ALinux }`^XNEvGveB
uȃVXełBȂ̃vZXA 10 ~b琔b(
ׂ̍VXeȂǂ)ɓnĂȂ炩̗RŃXPW[OΏۂ
O邱Ƃ́Ał蓾܂BAI/O |[ggقƂ
̃AvP[Vł́A͎ۂɂ͖ɂ͂ȂȂł傤B̎
Ԃł邾邽߂ɂ́Anice (}jAy[W nice(2)Q
̂) găvZX̗D揇ʂA܂̓A^CXP
W[̃VXe(LQƂ̂)gƂƂł܂B (
Fnice LɎgƂŁAvZX̎Ԃ̍ČvZpɂɍsA
ɂ肠xADIɃXPW[Ƃʂ܂B)

ʏ̃[U[hvZXň͈͂Ɛׂȃ^C~O
߂̂ȂA[U[hŁuA^CvT|[g邽߂̑΍
܂B Linux 2.x J[l̓\tgA^CT|[gĂ܂B
ڍׂ sched_setscheduler(2) ̃}jAy[WQƂĂBn[
hA^CT|[gʂȃJ[l܂BɂĂ̂
Əڂ http://luz.cs.nmt.edu/ B (󒍁FL
Oɂn[hA^CT|[g݂܂Bڍׂhttp://
www.linux.or.jp/link/kernel.html#RTQƂĂB)


4.1.1. X[vFsleep()  usleep()

āAƊȒPȃ^C~OɂĂb܂傤Bb̃fBC~
ꍇɂ́A炭 sleep() ł傤B\~bȏ̃fBC
(ŏ̃fBC͖ 10 ~b̂悤łB)̏ꍇɂ usleep() E
łB̊֐ĂяoƁACPU ͑̃vZXɊ蓖Ă܂(
܂vZXuv)̂ŁACPU ^CʂɂȂ邱Ƃ͂܂B
ׂɂĂ sleep(3)  usleep(3) ̃}jAy[WB

 50 ~bfBCɊւĂ(炭vZbT}V
xAVXeׂ̕ɂˑ܂)Aɏqׂ悤 CPU Ă
܂ƂAv[`ł͂܂܂BʏALinux ̃XPW[
Ȃ̃vZXɑ΂Đ߂O(x86 A[LeN`ł)Ȃ
 10-30 ~b͂邩łB̂悤Ȃ킯ŁAusleep(3) ɏf
BCw肷ƒʏ͎w肵lƂzfBC
܂B܂ŏ̒l͖ 10 ~bƂƂɂȂ܂B


4.1.2. nanosleep()

2.0.x V[Y Linux J[lɂ nanosleep() ƂVȃVXeR
[t܂B(ڍׂ nanosleep(2) ̃}jAy[WQƂ
ĂB) ̃VXeR[g(}CNbƂ)Z
̃X[v܂̓fBC\ƂȂ܂B

vZX (sched_setscheduler()p)\tgA^CXPW[
OĂꍇA2 ~bȉ̃fBCɑ΂ẮAnanosleep() ̓r
W[[vg܂Bȏ̃fBCɑ΂Ă usleep() ƓlX
[v܂B (󒍁F\tgA^CłȂ΁Ausleep() Ɠx̎
ԕ\ɂȂ悤łB)

̃rW[[v udelay() (̃J[lhCogJ[l̓
t@NV)gĂāA[v̒ BogoMips lgČvZ
܂B (̎̃rW[[v̑Ȃǂ BogoMips lmɔf
̗̂łB) ǂ̂悤ɓ삷邩ɂďڍׂ /usr/include/asm/
delay.h QƂĂB


4.1.3. |[gI/OgfBC

|[g I/O gΐ}CNb̃fBC܂@ō܂B|
[g 0x80 ɉoCgf[^o͂܂͓͂ƁAvZbT̎ނ
xɊ֌WȂAقڐm 1 }CNb҂Ƃł܂B (o͂̕
@ɂẮAO̕ǂŉB) Kvȉ񐔌JԂƂŐ
}CNb҂Ƃł܂BWIȃ}Vł́Ã|[go͂ɂ
ĂȂɂςȕp肵Ȃ͂łB (J[lhCoł
gĂ̂܂B) ̕@ {in|out}[bw]_p() łfB
C邽߂ɒʏɎgĂ@łB (asm/io.h ĉB)

|[gAhX 0-0x3ff ͈̔͂ɂ̃|[gւ I/O ߂͎ۂ̂
قڐm 1 }CNb܂BႦ΃p|[g𒼐
ĂꍇȂAfBC邽߂ɂ͂̃|[gɑ΂ inb() 
ǉ邾ł킯łB


4.1.4. AZu߂ɂfBC

̃vO}ṼvZbT̎ނƃNbNx킩Ă
ꍇɂ́ÃAZu߂n[hR[h邱ƂŁAƒZf
BC邱Ƃł܂B (AvZXXPW[O
OAfBCȂĂ܂Ƃ蓾邱ƂYȂŉ
B) ȉ̕\ł́Aꂼ̖߂ŉNbN(NbN)
Ă܂BɂĂǂꂭ炢̎Ԃ邩m邱Ƃ
ł܂BႦ 50MHz ̃vZbT (486DX-50 ƂA486DX2-50) ̏ꍇ
 1 NbN 1/50000000 b( 200 imb)łB

 
Instruction   i386 clock cycles   i486 clock cycles                    
xchg %bx,%bx          3                   3                            
nop                   3                   1                            
or %ax,%ax            2                   1                            
mov %ax,%ax           2                   1                            
add %ax,0             2                   1                            
 

Pentium ̃NbN i486 ƓɂȂ͂łB Pentium Pro/II
ł͈Ⴂ܂B܂ add %ax, 0 ͔NbN܂B̖߂
X̖߂ƃyAŎs邩łB (out-of-order ŝ߁A
͖ߎsXg[ׂ̖̂߂łKv͂Ȃ̂łB)

̕\ŁAnop  xchg ͉p͂Ȃ͂łB̖̑߂̓tO
WX^ύX\܂BłAgcc ͂oĂ܂
Aɂ͂ȂȂ͂łB xchg %bx, %bx fBCp̖߂Ƃ
͖ȑIƌł傤B

gɂ́AvO̒ asm("") ƂgāA
\̖߂𖄂ߍ݂܂BЂƂ asm() ŕ̖߂𖄂ߍނɂ̓Z~
RŊe߂Ȃ܂BႦ asm("nop ; nop ; nop ; nop")  nop
߂4sāAi486 ܂ Pentium vZbTł 4 NbÑfB
C(i386 ł 12 NbN)ɂȂ܂B

asm() ́Agcc ɂāACCAZuR[hɕϊ̂Ŋ
ĂяõI[o[wbh͂܂B

Intel x86 A[LeN`ł 1 NbNZfBC邱Ƃ͕s
\łB


4.1.5. Pentiumrdtscɂ

Pentium vZbTł́Au[g猻݂܂ł̌o߃NbNTCN
m邱Ƃł܂Bȉ̃R[hł(̃R[h RDTSC Ƃ CPU 
sĂ܂B):

 
   extern __inline__ unsigned long long int rdtsc()                    
   {                                                                   
     unsigned long long int x;                                         
     __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));                 
     return x;                                                         
   }                                                                   
 

̒lfBCƂĕKvȐω̂rW[[vŊĎ
΂悢ł傤B


4.2. Ԃ̑

1 b炢̐x̎ԂȂ΁Atime() ĝԊȒPł傤B
mȎԂKvȏꍇɂ́Agettimeofday() gƑ́A}CNb̐
x܂B (łAO̕ŏqׂAXPW[ÔƂ͖YȂ
łB) Pentium ̏ꍇɂ́ÃR[hg 1 NbNTCN
̐xo܂B

vZXA鎞Ԍo߂ɃVOi󂯎悤ɂꍇɂ
A setitimer()  alarm() g܂B̊֐̏ڍׂɂĂ̓}jA
y[WB


5. ̑̃vO~Oɂ

ȏ̐ł C ɓďqׂ܂AC++  Objective C ł
悤ɂł͂łBAZȕꍇAC ̏ꍇƓl ioperm() 
iopl() ĂяoȂ΂Ȃ܂񂪁Ǎɂ͒ I/O |[gɑ΂
郊[h/Cg(: in, out ) gƂł܂B

̑̌ŁACCAZu C ̃R[h𖄂ߍނƂ
ȂA܂͑OɏqׂVXeR[gȂꍇɂƂȒPȕ
@́AKv I/O |[gANZX̂߂̃\[XR[h C ŋLqăR
pCAvȎ̕ƃNĂ܂Ƃ@ł傤B
邢͑OŐGꂽ /dev/port gƂ悢ł傤B


6. 悭g|[g

ȉ́A悭g TTL (܂ CMOS)̔ėp_ I/O |[gɂẴv
O~OłB

ȉɏqׂ|[g₻̑̕WIȃ|[gŖ{̎g(ႦΕ
̃v^⃂f𐧌䂷Ƃ悤)̂ȂA HOWTO
ŏqׂ悤Ƀ|[g𒼐ڑ삷ÃhCo(̓J[l
ɂĂ܂B)gł傤B̃ZNV PC ̕W
|[gLCDfBXvC(󒍁FƌĂߍ͂ 14 C`Ƃ
fBXvĈƂȂłB)ƂXebsO[^[Ƃ̓d
q@ȂƂlӐ}Ă܂B

XLiƂXɕׂĔĂ悤ȋ@(Xɏo
n߂Ăƌo悤Ȃ)𐧌䂵̂ȂAɂ
Linux hCoTĂ݂܂傤B Hardware-HOWTO (󒍁F{
Hardware-HOWTO({)łB) Ȃǂŏ̎肪ƂĂ͂Ǝv
܂B

Rs[^ɐڑ@(ƂAɂʂ̓dq@)ɂĂ̂
http://www.hut.fi/Misc/Electronics/E߂łB


6.1. p|[g

p|[g̃x[XAhX(ȉł ``BASE'' ƌĂԂƂɂ܂B)
 /dev/lp0 ł 0x3bcA /dev/lp1 ł 0x378A/dev/lp2 ł 0x278 ɂ
܂B (󒍁FLinux J[l2.2.xȍ~ parport hCoT|[g
VXeł lp foCXt@Cƃx[XAhXKΉĂ
킯ł͂܂Bڂ̓J[lt parport.txt QƂĂ
B) ʏ̃v^|[gƂē삳łA
Printing-HOWTO(󒍁F{ Printing-HOWTO({)łB)ǂނ
ł傤B

قƂǂ̃p|[gɂ͈ȉɏqׂWIȏo͐p[hɉ
Augvo[h܂BɊւ邱ƁA܂ŋ߂ ECP/EPP
[h(ɂ͔ėp IEEE1284 Ki)ɂẮA http://www.fapo.com/
http://www.senet.com.au/~cpeacock/parallel.htmlQƂĂB[
U[h̃vOł IRQ  DMA g܂̂ŁAECP/EPP g
߂ɂ͂炭J[lhCoȂ΂ȂȂł傤BN
hCoĂ邾낤Ƃ͎v܂A͏ڂƂ͒m
܂B

BASE+0̃|[g(f[^|[g) ́A|[g̃f[^M𐧌䂵܂B (D0
` D7 ̓rbg 0 ` 7 ɑΉ܂B : 0 = low (0V)A1 = high (5V))
B̃|[gɑ΂郉Cg̓f[^b`ĊÕsɏo͂܂B
W܂͊gCg[h̏ꍇɂ́A[hƁAŌɃCgꂽ
f[^ǂݏo܂Bg[h[h̏ꍇɂ́AOfoCX
f[^ǂݏo܂B

BASE+1̃|[g(Xe[^X|[g) ̓[hI[ŁAȉ̂悤ȓ͐M
̃Xe[^XԂ܂:

 E Bit 0  1 ͗\
   
 E Bit 2 IRQ Xe[^X (Os̒lł͂ȂBǂӂɓ삷
    邩mȂ)
   
 E Bit 3 ERROR (1=high)
   
 E Bit 4 SLCT (1=high)
   
 E Bit 5 PE (1=high)
   
 E Bit 6 ACK (1=high)
   
 E Bit 7 -BUSY (0=high)
   

 

BASE+2̃|[g(|[g)̓CgI[ ([hꍇAŌɃC
gf[^ԂB)ŁAȉ̃Xe[^XM𐧌䂵܂:

 E Bit 0 -STROBE (0=high)
   
 E Bit 1 -AUTO_FD_XT (0=high)
   
 E Bit 2 INIT (1=high)
   
 E Bit 3 -SLCT_IN (0=high)
   
 E Bit 4 '1' ɂƁAp|[g̊荞݂(ACK  low
    -> high ̑JڂŊ荞ݔB)
   
 E Bit 5 g[hł̕(0 = o, 1 = ) 𐧌䂷B̃rb
    g͊SɃCgI[ŁA[hɂ͕s̒lԂB
   
 E Bit 6  7 ͗\
   

 

sڑ (25 s D-sub XRlN^) (i=input, o=output):
1io -STROBE, 2io D0, 3io D1, 4io D2, 5io D3, 6io D4, 7io D5, 8io D6,   
9io D7, 10i ACK, 11i -BUSY, 12i PE, 13i SLCT, 14o -AUTO_FD_XT,         
15i ERROR, 16o INIT, 17o -SLCT_IN, 18-25 Ground                        
 

IBM ̋Kiɂ΁A1, 14, 16, 17 ԃs(o)́A4.7kI[ 5V
ɃvAbvꂽI[vRN^hCo (VN(z) 20mA, \[
X (fo) 0.55mA, AnCx̏o͂̓vAbv 5V) ̑
̃sɂẮAVN(z) 24mA, \[X(fo) 15mA, nC
xo͍͂ŏ 2.4V, [x̏o͍͂ő 0.5VB IBM ȊÕp|
[gł͂炭̕WƂ͏XႤꍇł傤BɊւ
Əڂ http://www.hut.fi/Misc/Electronics/circuits/
lptpower.html B

Ōɒ: Oh(ڒn)ɂ͋C܂傤B̓Rs[^ғ
ɃRlN^ڑŁAp|[g󂵂Ă܂o
܂BlƁA}U[{[hɏĂ̂ł͂Ȃ(gJ[
h)p|[gĝ܂ˁB (WIȈu}
`I/OvJ[hg΂Ȃ̃Rs[^ɓ߂̃p|[g
܂BKv̂Ȃ(p|[gȊÓF)|[g disable Ă
΂łBgJ[h̃p|[gI/OAhX󂢂ĂƂ
ɐݒ肵܂傤B IRQ ͎g\肪Ȃ΋CɂKv͂܂B)
(: e@̃t[Oh́AƂƂ܂傤ˁB)


6.2. Q[(WCXeBbN)|[g

Q[|[g̓|[gAhX 0x200-0x207 łBʂ̃WCXeBbN
䂷ȂAALinux J[lɂĂhCog
łB

sڑ (15 s D-sub XRlN^):

 E 1,8,9,15: +5 V (power)
   
 E 4,5,12: Ground
   
 E 2,7,10,14: fW^ (Ԃ) BA1, BA2, BB1, BB2
   
 E 3,6,11,13: AiO (Ԃ) AX, AY, BX, BY
   

 

+5 V s̓}U[{[h̓dɒڐڑĂ悤ł̂ŁA (}U[
{[h̍AdAQ[|[gɂ܂)ɑ傫ȓd͂
邱Ƃł͂łB

̃|[gɂ͓̃WCXeBbNڑł܂AfW^͂́A
̃{^̓͂łB (WCXeBbN A ƃWCXeBbN B
ꂼɓ{^܂B) ͒ʏ TTL x̓͂
AȉŏqׂXe[^X|[g(ȉɋLq)猻݂̏Ԃǂݏo
ł܂Bۂ̃WCXeBbNł̓{^Ă low (0V)
AłȂ high (1K I[̒Rʂ 5V dɃvAbv)
ǂݏo܂B

AiO͂Ƃ̂́Aۂɂ͒RlvĂ̂łBȉ
ł̎dg݂qׂ܂BQ[|[gɂ4{̓͂ꂼɃVbg
}`oCu[^ڑĂ܂B(S(4{) 558 `bv) 
̓͂ɂāA̓sƃ}`oCu[^̏o͂̊Ԃ 2.2K I[
̒RA}`oCu[^̏o͂ƃOh̊Ԃ 0.01uF ̃^C~
OpRfTڑĂ܂Bۂ̃WCXeBbNɂ́AX  Y
̎ɂꂼ|eV[^A+5V Ƃꂼ̓̓sɐ
Ă܂B (AX, AY WCXeBbN A ɁABX, BY WCXeB
bN B ɑΉ܂B) (: H}͂Ȋ:
+5V                                                                    
 |       ^                                                             
 |      /          2.2KI[                                          
 +---/\/\/\--IN----/\/\/\------+                                       
       /                       |                                       
 |eV[^              |                                       
                  +---------+  |                                       
                  | Multi   |  |                                       
                  | vib.   Q|--+                                       
                  |         |  |                                       
                  |         |  |                                       
                  |         |  |                                       
                  |         | === 0.01uF                               
                  |         |  |                                       
                  +---------+  |                                       
                               |                                       
                              GND                                      
)

}`oCu[^쓮ƁȀo͂ high (5V) ɃhCuA
ɐڑĂ^C~ORfT̓dʂ 3.3V ɂȂ܂ő҂A
̌ɏo͂ low ɂ܂B̌ʁA}`oCu[^̏o͂ high
̎Ԃ̓WCXeBbÑ|eV[^̒RlɔႵ܂B (
܂Aꂼ̎̃WCXeBbN̈ʒu\܂B) Rl͈ȉ
̂Ƃł:

R = (t - 24.2) / 0.011,                                                

ŁAR ̓|eV[^̒Rl(I[)At  high ̎(}CN
b)łB

Ƃ܂A킯ł̂ŁAAiO͂ǂݏo߂ɂ́Aȉŏq
ׂ悤ɂ܂|[gɃCgāA}`oCu[^쓮Kv
܂B̌4̎̏Ԃ|[O(|[gJԂǂݏo)
Aꂼ̃|[g high  low ɂȂ܂ł̎Ԃ𑪒肵܂B̃|
[Oɂ͔ CPU ^C܂A(ʏ̃[U[h)
Linux ̂悤Ȕ񃊃A^CE}`^XNVXeł͂̌ʂ͂܂
mł͂܂B|[g₦ԂȂǂݏoƂ͂łȂłB
(J[lx̃hCogA|[O̊ԁA荞݂֎~
̂łA͍Xɑ CPU ^CH܂B) M low ɂ
܂Œ(\~b)̂ĂȂA|[OO
CPU ^C𑼂̃vZXɖn悤 usleep() ĂԂƂł܂B

āAANZXKv̂|[g͂A0x201 (̃|[gAhX
͂̃|[gƓ悤ɂӂ܂AȂɂȂÂǂ炩)łB
̃|[gɑ΂郉Cg(ރf[^͂ȂłǂłB)ɂă}
`oCu[^쓮܂B[hƓ͐M̏ԂԂ܂:

 E Bit 0: AX (}`oCu[^o͂̏ (1=high))
   
 E Bit 1: AY (}`oCu[^o͂̏ (1=high))
   
 E Bit 2: BX (}`oCu[^o͂̏ (1=high))
   
 E Bit 3: BY (}`oCu[^o͂̏ (1=high))
   
 E Bit 4: BA1 (fW^, 1=high)
   
 E Bit 5: BA2 (fW^, 1=high)
   
 E Bit 6: BB1 (fW^, 1=high)
   
 E Bit 7: BB2 (fW^, 1=high)
   

 


6.3. VA|[g

Rs[^Ɛڑ@킪 RS-232 ݂Ȏdg݂ĂȂ
A̋@Ƃ̐ڑɃVA|[ggƂł傤B Linux ̃VA
hCo͂قƂǂƂ鉞p܂B (VA|[g
ڑ삷ȂĂȂłBȂƂȂ瑽J[lh
CoȂ΂ȂȂnɂȂ܂B) ̃hCoƂĂėp
̂ŕWłȂ bps [ggƂƂƂł͂
B

Unix VXeŃVA|[ggvÔڂɂĂ
termios(3) }jAy[WVAhCõ\[XR[h(linux/
drivers/char/serial.c) A܂http://www.easysw.com/~mike/serial/Ql
ɂĂB


7. Hints

܂ƂȃAiO I/O Kvȏꍇɂ́AADC (AiO -> fW^Ro
[^) DAC (fW^ -> AiORo[^)`bvp|[gɐ
Ƃ@܂B (qg: dɂ͋CĉBQ[
|[g̓dgAfBXNhCup̗]ĂdRlN^
Rs[^P[XoȂǂł傤Bp|[g
dƂȂ΁Ad͂̃foCXgKv܂B) (:
ɂA̓fW^n̓dłAAiOnɎgꍇ
͂Ȃ炩̕@ŃfJbvOYȂB) ܂́AAD/DA J[h
wƂ܂B (̂̃ĝȂ I/O |[gŐ
܂B) A1`2 `lŏ\łA܂萳młȂĂ悭A
(炭) smȒ_␳(zeroing)ł悯΁ALinux ̃TEhh
CoŃT|[gĂTEhJ[h𔃂ĂĎgAƂ@
܂B (ɁA\łˁB)

ȃAiO@ł͕sKȃOhݒɂAiOo͂̌덷
邱ƂɂȂ܂BςȂAƎvA̋@tHgJbv
păRs[^dCI(Rs[^Ƌ@̊Ԃׂ̂Ă̐M
) AC\[gĂ݂Ƃł傤BǂAC\[V
邽߂ɃtHgJbv̓dRs[^Ƃ悤ɂĂ݂܂傤
B (|[g̗\̐M\Ȃ炢̓dƂ܂B)

Linux Ŏgvg݌ṽ\tgEFATłA Pcb Ƃ
Õt[ X11 AvP[V܂BƂ
Ƃ̂łȂAŏ\ɂ܂B Linux fBXgr
[VɎ^Ă܂A ftp://sunsite.unc.edu/pub/Linux/apps/
circuits/ (t@C pcb-* ) ɂ邱Ƃł܂B


8. guV[g

Q1.
    |[gANZX segmentation faults NĂ܂܂B
   
A1.
    vO root ĂȂAȂ炩̗R ioperm()
    ĂяoɎsĂ̂ł傤B ioperm() ̕Ԃl𒲂ׂ
    ݂ĂBƖ{ ioperm() ŋ𓾂|[gɃANZX
    Ă邩ǂׂĂ݂ĂB (Q3QlɂĂB) f
    BCt}N (inb_p(), outb_p() ȂǂȂ)gĂȂA
    ioperm() Ń|[g 0x80 ̃ANZXYꂸɎ擾ĂB
   
Q2.
    in*() Ƃ out*() Ƃ̊֐ǂɂ݂܂Bgcc 
    undefined references ƂĂ܂B
   
A2.
    RpC̎ɍœKI (-O) ɂȂ̂ł? ̌ʁAgcc
     asm/io.h ̒ɂ}N邱ƂłȂ̂łB
    ƂA#include <asm/io.h> YĂ܂?
   
Q3.
    out*() sĂȂɂȂA܂͂Ȃ񂩕ςȂ̂łB
   
A3.
    p[^̏Ԃ`FbNĉBoutb(value, port) Ƃ
    łB MS-DOS łȂ݂ outportb(port,value) Ƃ͋tłB
   
Q4.
    W RS-232 @Apv^[AWCXeBbNƂ
    ̂𐧌䂵̂ł...
   
A4.
    ԂɂhCo( Linux ̃J[lƂ X T[oƂ
    ̂ɂĂ̂ƂłB)głB
    hCo͂ėpāAƋKiŐ@Ȃ񂩂
    ܂Bւ̕ւ̃|C^[ƂāAŏW|[g
    ̏QlɂĂB
   



9. vO̗

́AI/O |[gANZX̒PȃR[fBOł:

 
/*                                                                       
 * example.c: ƂĂȒPȃ|[gI/O̗                                
 *                                                                       
 * ȂɂɂƂ͂Ă܂B|[gɏ݁Aꎞ~āA    
 * |[gǂݏołBugcc -O2 -o example example.cv        
 * RpCāA[g[UɂȂāu./examplevŎsĂB 
 */                                                                      
                                                                         
#include <stdio.h>                                                       
#include <unistd.h>                                                      
#include <asm/io.h>                                                      
                                                                         
#define BASEPORT 0x378 /* lp1 */                                         
                                                                         
int main()                                                               
{                                                                        
  /* |[gւ̃ANZX𓾂 */                                     
  if (ioperm(BASEPORT, 3, 1)) {perror("ioperm"); exit(1);}               
                                                                         
  /* |[g̃f[^ (D0-D7)S low (0) ɂ */                      
  outb(0, BASEPORT);                                                     
                                                                         
  /* ΂炭̊ (100 ms) X[v */                                   
  usleep(100000);                                                        
                                                                         
  /* Xe[^X|[g (BASE+1) ǂݏoāA\ */               
  printf("status: %d\n", inb(BASEPORT + 1));                             
                                                                         
  /* |[ggȂ̂Ōn */                                   
  if (ioperm(BASEPORT, 3, 0)) {perror("ioperm"); exit(1);}               
                                                                         
  exit(0);                                                               
}                                                                        
                                                                         
/* example.c  */                                                   
 


10. ӎ

ƂĂ̕珕 (contribute) 󂯂܂̂ŁAɂ͋L
܂BFAƂĂ肪ƂBׂĂ̕ɃvC邱Ƃ͂
܂łXɂ͂߂ȂAĂxAĂ
Ă肪ƂB


11. {ɂ

          : 쓇 _       <kei@sm.sony.co.jp>
̋ᖡ/Z : R NO <hiro@koneeko.linux.or.jp>
(1996/12/26)

XVFKcЂ <coda@post.kek.jp> (2001/03/24)
