Accessing I/O Ports

By Danny Kalev, ITworld |  How-to

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
#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.

Join us:
Facebook

Twitter

Pinterest

Tumblr

LinkedIn

Google+

Answers - Powered by ITworld

ITworld Answers helps you solve problems and share expertise. Ask a question or take a crack at answering the new questions below.

Join us:
Facebook

Twitter

Pinterest

Tumblr

LinkedIn

Google+

Ask a Question