home *** CD-ROM | disk | FTP | other *** search
/ Caldera Network Desktop 1.0 / caldera-network-desktop-1.0.bin / doc / HOWTO / mini / IO-Port-Programming < prev    next >
Text File  |  1996-01-01  |  14KB  |  294 lines

  1.  
  2.         Linux I/O port programming mini-HOWTO
  3.  
  4.         Author: rjs@spider.compart.fi (Riku Saikkonen)
  5.         Last modified: Dec 26 1995
  6.  
  7. This document is Copyright 1995 Riku Saikkonen. See the normal Linux HOWTO
  8. COPYRIGHT for details.
  9.  
  10.  
  11. This HOWTO document tells about programming hardware I/O ports and waiting
  12. for small (microseconds to milliseconds) periods of time in user-mode Linux
  13. C programs running on an Intel x86 processor. This document is a descendant
  14. of the very small IO-Port mini-HOWTO by the same author.
  15.  
  16. If you have corrections or something to add, feel free to e-mail me
  17. (rjs@spider.compart.fi)...
  18.  
  19. Changes from the previous version (Nov 16 1995):
  20. Lots, I haven't kept count. Added parallel port specification.
  21.  
  22.  
  23.         I/O ports in C programs, the normal way
  24.  
  25. Routines for accessing I/O ports are in /usr/include/asm/io.h (or
  26. linux/include/asm-i386/io.h in the kernel source distribution). The routines
  27. there are inline macros, so it is enough to #include <asm/io.h>; you do not
  28. need any additional libraries.
  29.  
  30. Because of a limitation in gcc (present at least in 2.7.0 and below), you
  31. _have to_ compile any source code using these routines with optimisation
  32. turned on (i.e. gcc -O). Because of another limitation in gcc, you cannot
  33. compile with both optimisation and debugging (-g). This means that if you
  34. want to use gdb on programs using I/O ports, it might be a good idea to put
  35. the I/O port-using routines in a separate source file, and, when you debug,
  36. compile that source file with optimisation and the rest with debugging.
  37.  
  38. Before you access any ports, you must give your program permission to do
  39. that. This is done by calling the ioperm(2) function (declared in unistd.h,
  40. and defined in the kernel) somewhere near the start of your program (before
  41. any I/O port accesses). The syntax is ioperm(from,num,turn_on), where from
  42. is the first port number to give access to, and num the number of
  43. consecutive ports to give access to. For example, ioperm(0x300,5,1); would
  44. give access to ports 0x300 through 0x304 (a total of 5 ports). The last
  45. argument is a Boolean value specifying whether to give access to the program
  46. to the ports (true (1)) or to remove access (false (0)). You may call
  47. ioperm() multiple times to enable multiple non-consecutive ports. See the
  48. ioperm(2) manual page for details on the syntax.
  49.  
  50. The ioperm() call requires your program to have root privileges; thus you
  51. need to either run it as user root, or make it setuid root. You should be
  52. able to (I haven't tested this; please e-mail me if you have) drop the root
  53. privileges after you have called ioperm() to enable any ports you want to
  54. use. You are not required to explicitly drop your port access privileges
  55. with ioperm(...,0); at the end of your program, it is done automatically.
  56.  
  57. Ioperm() priviledges are transferred across fork()s and exec()s, and across
  58. a setuid to a non-root user.
  59.  
  60. Ioperm() can only give access to ports 0x000 through 0x3ff; for higher
  61. ports, you need to use iopl(2) (which gives you access to all ports at
  62. once); I have not done this, so see the manual page for details. I suspect
  63. the level argument 3 will be needed to enable the port access. Please e-mail
  64. me if you have details on this.
  65.  
  66. Then, to actually accessing the ports... To input a byte from a port, call
  67. inb(port);, it returns the byte it got. To output a byte, call outb(value,
  68. port); (notice the order of the parameters). To input a word from ports x
  69. and x+1 (one byte from each to form the word, just like the assembler
  70. instruction INW), call inw(x);. To output a word to the two ports,
  71. outw(value,x);.
  72.  
  73. The inb_p(), outb_p(), inw_p(), and outw_p() macros work otherwise
  74. identically to the ones above, but they do a short (about one microsecond)
  75. delay after the port access; you can make the delay four microseconds by
  76. #defining REALLY_SLOW_IO before including asm/io.h. These macros normally
  77. (unless you #define SLOW_IO_BY_JUMPING, which probably isn't accurate) use a
  78. port output to port 0x80 for their delay, so you need to give access to
  79. port 0x80 with ioperm() first (outputs to port 0x80 should not affect any
  80. part of the system). For more versatile methods of delaying, read on.
  81.  
  82. Man pages for these macros are forthcoming in a future release of Linux
  83. man-pages.
  84.  
  85.  
  86. Troubleshooting:
  87.  
  88. Q1. I get segmentation faults when accessing ports!
  89.  
  90. A1. Either your program does not have root privileges, or the ioperm() call
  91.     failed for some other reason. Check the return value of ioperm().
  92.  
  93. Q2. I can't find the in*(), out*() functions defined anywhere, gcc complains
  94.     about unknown references!
  95.  
  96. A2. You did not compile with optimisation turned on (-O), and thus gcc could
  97.     not resolve the macros in asm/io.h. Or you did not #include <asm/io.h>
  98.     at all.
  99.  
  100.  
  101.         An alternate method
  102.  
  103. Another way is to open /dev/port (a character device, major number 1, minor
  104. 4) for reading and/or writing (using the normal file access functions,
  105. open() etc. - the stdio f*() functions have internal buffering, so avoid
  106. them). Then seek to the appropriate byte in the file (file position 0 = port
  107. 0, file position 1 = port 1, and so on), and read or write a byte or word
  108. from or to it. I have not actually tested this, and I am not quite sure if
  109. it works that way or not; e-mail me if you have details.
  110.  
  111. Of course, for this your program needs read/write access to /dev/port. This
  112. method is probably slower than the normal method above.
  113.  
  114.  
  115.         Interrupts (IRQs) and DMA access
  116.  
  117. As far as I know, it is impossible to use IRQs or DMA directly from a
  118. user-mode program. You need to make a kernel driver; see the Linux Kernel
  119. Hacker's Guide (khg-x.yy) for details and the kernel source for examples.
  120.  
  121.  
  122.         High-resolution timing: Delays
  123.  
  124. First of all, I should say that you cannot guarantee user-mode programs to
  125. have exact control of timing because of the multi-tasking, pre-emptive
  126. nature of Linux. Your process might be scheduled out at any time for
  127. anything from about 20 milliseconds to a few seconds (on a system with very
  128. high load). However, for most applications using I/O ports, this does not
  129. really matter. To minimise this, you may want to nice your process to a
  130. high-priority value.
  131.  
  132. There have been plans of a special real-time Linux kernel to support the
  133. above discussed in comp.os.linux.development.system, but I do not know their
  134. status; ask on that newsgroup. If you know more about this, e-mail me...
  135.  
  136. Now, let me start with the easier ones. For delays of multiple seconds, your
  137. best bet is probably to use sleep(3). For delays of tens of milliseconds
  138. (about 20 ms seems to be the minimum delay), usleep(3) should work. These
  139. functions give the CPU to other processes, so CPU time isn't wasted. See the
  140. manual pages for details.
  141.  
  142. For delays of under about 20 milliseconds (probably depending on the speed
  143. of your processor and machine, and the system load), giving up the CPU
  144. doesn't work because the Linux scheduler usually takes at least about 20
  145. milliseconds before it returns control to your process. Due to this, in
  146. small delays, usleep(3) usually delays somewhat more than the amount that
  147. you specify in the parameters, and at least 20 ms.
  148.  
  149. For short delays (tens of us to a few ms or so), the easiest method is to
  150. use udelay(), defined in /usr/include/asm/delay.h (linux/include/asm-i386/
  151. delay.h). Udelay() takes the number of microseconds to delay (an unsigned
  152. long) as its sole parameter, and returns nothing. It takes a few
  153. microseconds more time than the parameter specifies because of the overhead
  154. in the calculation of how long to wait (see delay.h for details).
  155.  
  156. To use udelay() outside of the kernel, you need to have the unsigned long
  157. variable loops_per_sec defined with the correct value. As far as I know, the
  158. only way to get this value from the kernel is to read /proc/cpuinfo for the
  159. BogoMips value and multiply that by 500000 to get (an imprecise)
  160. loops_per_sec.
  161.  
  162. For even shorter delays, there are a few methods. Outputting any byte to
  163. port 0x80 (see above for how to do it) should wait for almost exactly 1
  164. microsecond independent of your processor type and speed. You can do this
  165. multiple times to wait a few microseconds. The port output should have no
  166. harmful side effects on any standard machine (and some kernel drivers use
  167. it). This is how {in|out}[bw]_p() normally do the delay (see asm/io.h).
  168.  
  169. If you know the processor type and clock speed of the machine the program
  170. will be running on, you can hard-code shorter delays by running certain
  171. assembler instructions (but remember, your process might be scheduled out at
  172. any time, so the delays might well be longer every now and then). For the
  173. table below, the internal processor speed determines the number of clock
  174. cycles taken; e.g. for a 50 MHz processor (486DX-50 or 486DX2-50), one clock
  175. cycle takes 1/50000000 seconds.
  176.  
  177. Instruction   i386 clock cycles   i486 clock cycles
  178. nop                   3                   1
  179. xchg %ax,%ax          3                   3
  180. or %ax,%ax            2                   1
  181. mov %ax,%ax           2                   1
  182. add %ax,0             2                   1
  183. [source: Borland Turbo Assembler 3.0 Quick Reference]
  184. (sorry, I don't know about Pentiums; probably the same as the i486)
  185. (I cannot find an instruction which would use one clock cycle on a i386)
  186.  
  187. The instructions nop and xchg in the table should have no side effects. The
  188. rest may modify the flags register, but this shouldn't matter since gcc
  189. should detect it.
  190.  
  191. To use these, call asm("instruction"); in your program. Have the
  192. instructions in the syntax in the table above; to have multiple instructions
  193. in one asm(), asm("instruction ; instruction ; instruction");. The asm() is
  194. translated into inline assembler code by gcc, so there is no function call
  195. overhead.
  196.  
  197. Shorter delays than one clock cycle are impossible in the Intel x86
  198. architecture.
  199.  
  200.  
  201.         High-resolution timing: Measuring time
  202.  
  203. For times accurate to one second, it is probably easiest to use time(2). For
  204. more accurate times, gettimeofday(2) is accurate to about a microsecond (but
  205. see above about scheduling).
  206.  
  207. If you want your process to get a signal after some amount of time, use
  208. setitimer(2). See the manual pages of the functions for details.
  209.  
  210.  
  211.         Some useful ports
  212.  
  213. Here is some programming information for common ports that can be used for
  214. general-purpose TTL logic I/O.
  215.  
  216. The parallel port (BASE = 0x3bc for /dev/lp0, 0x378 for /dev/lp1, and 0x278
  217. for /dev/lp2): [source: IBM PS/2 model 50/60 Technical Reference, and some
  218. experimentation]
  219.  
  220. In addition to the standard output-only mode, there is an `extended'
  221. bidirectional mode in most parallel ports. This mode has a direction bit
  222. that can be set to either read or write mode. However, I don't know how the
  223. extended mode can be turned on (it's off by default)...
  224.  
  225. Port BASE+0 (Data port) controls the data signals of the port (D0 to D7 for
  226. bits 0 to 7, respectively; states: 0 = low (0 V), 1 = high (5 V)). A write
  227. to this port latches the data on the pins. A read returns the data last
  228. written in standard or extended write mode, or the data in the pins from
  229. another device in extended read mode.
  230.  
  231. Port BASE+1 (Status port) is read-only, and returns the state of the
  232. following input signals:
  233. Bits 0 and 1 are reserved.
  234. Bit 2 IRQ status (not a pin, I don't know how this works)
  235. Bit 3 -ERROR (0=high)
  236. Bit 4 SLCT (1=high)
  237. Bit 5 PE (1=high)
  238. Bit 6 -ACK (0=high)
  239. Bit 7 -BUSY (0=high)
  240. (I'm not sure about the high and low states.)
  241.  
  242. Port BASE+2 (Control port) is write-only (a read returns the data last
  243. written), and controls the following status signals:
  244. Bit 0 -STROBE (0=high)
  245. Bit 1 AUTO_FD_XT (1=high)
  246. Bit 2 -INIT (0=high)
  247. Bit 3 SLCT_IN (1=high)
  248. Bit 4 enables the parallel port IRQ (which occurs on the low-to-high
  249. transition of -ACK) when set to 1.
  250. Bit 5 controls the extended mode direction (0 = write, 1 = read), and is
  251. completely write-only (a read returns nothing useful for this bit).
  252. Bits 6 and 7 are reserved.
  253. (Again, I'm not sure about the high and low states.)
  254.  
  255. Pinout (a 25-pin female D-shell connector on the port) (i=input, o=output):
  256. 1io -STROBE, 2io D0, 3io D1, 4io D2, 5io D3, 6io D4, 7io D5, 8io D6, 9io D7,
  257. 10i -ACK, 11i -BUSY, 12i PE, 13i SLCT, 14o AUTO_FD_XT, 15i -ERROR,
  258. 16o -INIT, 17o SLCT_IN, 18-25 Ground
  259.  
  260. The IBM specifications say that pins 1, 14, 16, and 17 (the control outputs)
  261. have open collector drivers pulled to 5 V through 4.7 kiloohm resistors
  262. (sink 20 mA, source 0.55 mA, high-level output 5.0 V minus pullup). The rest
  263. of the pins sink 24 mA, source 15 mA, and their high-level output is min.
  264. 2.4 V. The low state for both is max. 0.5 V. Clone parallel ports probably
  265. deviate from this standard.
  266.  
  267. Finally, a warning: Be careful with grounding. I've broken several parallel
  268. ports by connecting them while the machine is turned on. It might be a good
  269. thing to use a parallel port not integrated on the motherboard for things
  270. like this.
  271.  
  272. The game port (ports 0x200-0x207): I do not have specifications on this, but
  273. I think there should be a few TTL inputs and some sort of power for output,
  274. at least. If someone has more information, tell me...
  275.  
  276. If you want analog I/O, you can wire up ADC and/or DAC chips to these ports
  277. (hint: for power, use a spare disk drive power connector wired to outside
  278. the computer case, unless you have a very low-power device and can use the
  279. port itself for power), or buy an AD/DA card (most are controlled by I/O
  280. ports). Or, if you're satisfied with 1 or 2 channels, inaccuracy, and
  281. (probably) bad zeroing, a cheap sound card supported by the Linux sound
  282. driver should do (and it's pretty fast).
  283.  
  284.  
  285.         A to-do list for this document
  286.  
  287.  - checking the stuff I wasn't sure about
  288.  - simple (software) examples on using the functions described
  289.  
  290. Thanks for the many helpful corrections and additions I've got.
  291.  
  292. End of the Linux I/O port programming mini-HOWTO.
  293.  
  294.