【问题标题】:Communicating with ports using ioperm() in embedded device在嵌入式设备中使用 ioperm() 与端口通信
【发布时间】: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() 报告更新的值。很大的猜测,但希望很容易测试......
  • 顺便说一句,除了延迟可能性之外,没有规定说硬件输出端口必须支持回读。有些会,有些不会。如果没有读取支持,有时由于总线电容等原因您会得到有趣的值。此外,您的端口可能需要设置模式配置,或者驱动程序或潜在冲突的其他外围设备需要配置。

标签: c linux io embedded port


【解决方案1】:

嗯,我想这是那些简单地消失的问题之一。我相信我纠正了一个我确信与这个问题无关的小错误。但是当我这样做时,问题就消失了。

我会更好地描述我是如何解决它的,但我真的不知道我是如何做到的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    相关资源
    最近更新 更多