Accessing I/O Ports

Linux offers two methods of accessing I/O ports. The method I will

present this week is the safer and more portable of the two.

A Word of Caution

In general, user-level programs should not access hardware directly,

for several good reasons. For starters, usually a dedicated library of

API functions or a vendor specific library allows you to access a

device in a safe manner. Secondly, the details of I/O port access are

platform dependent (e.g., the control port's address) and may vary

across hardware architectures. Finally, a program that accesses

hardware directly might crash the system. That said low-level programs

that do need to access hardware directly could accomplish that

relatively easily.

Accessing an I/O Port through a File Descriptor

Suppose we have a device connected to the computer's printer parallel

port, say a remote control that switches the light in the room on and

off. The "dev/port" generic device enables a program to access an I/O

port. We open it in write-only mode using the open() function:

int main()


int fd=open("dev/port", O_WRONLY, 0);


Since the control port of "dev/lp1" is located at address 0x378+2 (890

decimal), we have to advance the logical file pointer to that offset

before we can write a command to it. We use lseek() for this purpose:

const int PORT=0x378+2;

lseek(fd, PORT, SEEK_SET);

Now we can use write() to write a command directly to the control port

of "dev/lp1". For the sake of brevity, I omitted all error checking

code from the program, although, in general, you should check the

status of an open() call. Let's assume that our remote controller knows

only two commands: "turn the lights on" and "turn the lights off",

which are represented as the characters 0x01 and 0x00, respectively.

The following write() call turns the lights on:

const int ON=0x01;

const int OFF=0x00;

unsigned char command=ON;

write(fd, &command, 1);/*write 0x01 to the control port*/

Here's a complete program that turns the lights off:


#include const int CTL_PORT=0x378+2; const int ON=0x01; const int OFF=0x00; int main() { int fd; unsigned char command=OFF; fd=open("dev/port", O_WRONLY, 0); lseek(fd, CTL_PORT, SEEK_SET); write(fd, &command, 1);/*turn the lights off*/ } Next week, I will show how to write to I/O ports directly.
ITWorld DealPost: The best in tech deals and discounts.