【发布时间】:2012-06-13 23:44:50
【问题描述】:
以下代码有问题。我需要它来访问端口 0x300 到 0x307,所以我这样做:
#ifdef LINUX
if(ioperm(PORT1,9,1)==-1) printf("Error in ioperm()");
#endif
其中 PORT1=0x300。
然后我这样做:
int j5inp(unsigned int addr){
#ifdef DOS
return inp(addr);
#endif
#ifdef LINUX
return inb(addr);
#endif
}
void j5outp(unsigned int addr, unsigned int val){
#ifdef DOS
outp(addr,val);
#endif
#ifdef LINUX
outb(val,addr);
#endif
}
/************/
hrd_check()
{
j5outp(PCHECK,0xAA);
if (j5inp(PCHECK)!=0xAA) return(0);
j5outp(PCHECK,0x55);
if (j5inp(PCHECK)!=0x55) return(0);
return(1);
}
其中 PCHECK=0x307。
我对此进行了测试,发现发送后我可以从端口检索值 0xAA,但第二个 (0x55) 失败,因为 inb() 仍然返回 0xAA。
我做错了吗?这可能是硬件问题吗?我应该尝试为每次调用 inb() 调用 ioperm() 函数还是应该尝试使用 iopl() ?
顺便说一下,我使用的主板是研华 PCM-3342
【问题讨论】:
-
inp(2)手册页提到有_p变体会暂停直到 IO 完成——您是否需要使用这些变体? (您不需要在每次使用时都调用ioperm()或iopl()——它们在进程的thread_struct中设置一个标志。) -
你的意思是inb调用的时候不会暂停?这是如何运作的?我尝试的目的是将这个程序从 DOS 迁移到 linux。我需要访问这些端口的方式来获得与 DOS 上的函数 inp() 和 outp() 相同类型的性能。我将研究 *_p 函数,谢谢。
-
我将关于
_p变体的问题作为评论而不是回答,因为我只是在黑暗中拍摄——但如果写入 IO 端口需要一些时间,我不会感到惊讶时间,而outb_p()的执行时间将比outb()长,但在等待输出首先真正工作后,设备可能能够使用下一个inb()报告更新的值。很大的猜测,但希望很容易测试...... -
顺便说一句,除了延迟可能性之外,没有规定说硬件输出端口必须支持回读。有些会,有些不会。如果没有读取支持,有时由于总线电容等原因您会得到有趣的值。此外,您的端口可能需要设置模式配置,或者驱动程序或潜在冲突的其他外围设备需要配置。