linux基础i o调用,Linux下读写I/O port

#include #define IO_PORTS1 1 /* ioport <= 0x3ff */

#define IO_PORTS2 2 /* ioport >0x3ff && ioport < 0xffff */

#define IO_PERMOFF 0

#define IO_PERMON 1

#define IO_PERMON2 3

#define RW_DELAY 10000 /*delay 100000 microseconds for reading and writing I/O ports. */

#ifndef BOOL

typedef unsigned char BOOL;

#endif

#ifndef BYTE

typedef unsigned char BYTE;

#endif

#ifndef DWORD

typedef unsigned long DWORD;

#endif

#ifndef INT

typedef unsigned int INT;

#endif

#ifndef ULONG

typedef unsigned long ULONG;

#endif

#ifndef WORD

typedef unsigned short WORD;

#endif

/*

** Function : Write the value of the specified I/O port by giving the length and the

** starting address.

** Parameter: PortAddr: the port address

** PortVal : the value to set

** size : size = 1 for reading 1 byte, 2 for word, 4 for double words

** Return : 1 returned if success, or 0 returned

*/

BOOL SetPortVal(WORD PortAddr, DWORD PortVal, BYTE size)

{

BOOL Ret = 0;

INT tmpRet = 0;

ULONG numperm = 1;

INT privilege = 0;

assert(PortAddr>0);

if(PortAddr <=0x3ff)

{

tmpRet = ioperm((ULONG)PortAddr, numperm, IO_PERMON);

privilege = IO_PORTS1;

}

else if( PortAddr > 0x3ff

{

tmpRet = iopl(IO_PERMON2);

privilege = IO_PORTS2;

}

else

return Ret;

if(tmpRet<0)

{

fprintf(stderr, "can't set the io port permission for setting !\n";

return Ret;

}

else

{

switch(size)

{

case 1: /*write one byte to the port */

outb(PortVal, PortAddr);

break;

case 2: /*write one word to the port */

outw(PortVal, PortAddr);

break;

case 4: /*write double words to the port */

outl(PortVal, PortAddr);

break;

default:

Ret = 0;

break;

}

usleep(RW_DELAY);

Ret = 1;

}

if( privilege == IO_PORTS1

ioperm((ULONG)PortAddr, numperm, IO_PERMOFF);

else if(privilege == IO_PORTS2

iopl(IO_PERMOFF);

return Ret;

}

/*

** Function : Read the value of the specified I/O port by giving the lenght and the

** starting address.

** Parameter: PortAddr : the port address

** PortVal : value from port

** size : size = 1 for reading 1 byte, 2 for word, 4 for double words

** Return : 1 returned if success, or 0 returned.

*/

BOOL GetPortVal(WORD PortAddr, DWORD * PortVal, BYTE size)

{

BOOL Ret = 0;

int tmpRet = 0;

unsigned long numperm = 1;

int privilege = 0;

assert(PortAddr>0);

assert(PortVal!=NULL);

if(PortAddr <=0x3ff)

{

tmpRet = ioperm((unsigned long)PortAddr, numperm, IO_PERMON);

privilege = IO_PORTS1;

}

else if( PortAddr > 0x3ff

{

tmpRet = iopl(IO_PERMON2);

privilege = IO_PORTS2;

}

else

return Ret;

if(tmpRet<0)

{

fprintf(stderr, "can't set the io port permission for reading !\n";

return Ret;

}

else

{

switch(size)

{

case 1: /*read one byte from the port */

*PortVal = inb(PortAddr);

break;

case 2: /*read one word from the port */

*PortVal = inw(PortAddr);

break;

case 4: /*read double words from the port */

*PortVal = inl(PortAddr);

break;

default:

Ret = 0;

break;

}

usleep(RW_DELAY);

Ret = 1;

}

if( privilege == IO_PORTS1

ioperm( (unsigned long)PortAddr, numperm, IO_PERMOFF ;

else if( privilege == IO_PORTS2

iopl(IO_PERMOFF);

return Ret;

}

int main (int argc, char * argv[])

{

WORD add_port = 0xcf8;

WORD data_port = 0xcfc;

DWORD addr = 0x80000000;

DWORD port_value;

BYTE size = 4;

int input;

printf("Please select the option number as follow:\n";

printf("1--bus 0:dev:0 fun:0 as address 0x80000000\n";

printf("2--bus 0:dev:1 fun:0 as address 0x80000800\n";

printf("3--input your own defined address value:\n";

scanf("%d",&input);

switch(input)

{

case 1:

addr=0x80000000;

break;

case 2:

addr=0x80000800;

break;

case 3:

printf("please input the 32 bits address in Hex format(such as 80007800): ";

scanf ("%x", &addr);

break;

default:

printf("input invalid option num, exit program.\n";

return -1;

}

printf ("The addr is :%X\n", addr);

printf ("The add_port is : %X\n", add_port);

printf ("The data_port is : %X\n", data_port);

if (SetPortVal(add_port, addr, size))

{

if (GetPortVal(data_port, &port_value, size))

{

printf("port value is :%08X\n", port_value);

return 0;

}

}

return -1;

}

2.2 编译:

gcc -o pci pci.c

gcc 带参数 -o 指定输出的文件名,如不带参数则默认以a.out做为文件名;

如要加入调试信息,则带参数-g,然后用gdb命令进行调试:

gcc -o pci -g pci.c

gdb pci

有关gdb的用法参见相关资料;

2.3 运行:

输入: ./pci (注意: / 前有.表示当前目录下)

可以将结果和系统的pci信息对照,以检查结果是否正确:

more /proc/pci

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值