11608|26

58

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

请教关于io端口读写问题(iopl,outb,inb) [复制链接]

我在104工控板上调试一个开关量输入继电器,用sys/io.h的outb(write_addr)发命令可以正常控制,
但是在读inb(read_addr)时总是返回0xff。
我的操作系统是FC8。
请大侠指教一下!!!

最新回复

不懂,来学习的。  详情 回复 发表于 2010-4-21 10:10
点赞 关注

回复
举报

60

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
大侠都跑哪里去了哦???
自己顶~~
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
你是通过应用层访问,还是在核心通过驱动访问?
 
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

4
 
引用 2 楼 morris88 的回复:
你是通过应用层访问,还是在核心通过驱动访问?

是在应用层,我是用qt4中调试的
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

5
 
你看看 /usr/include/sys/io.h 文件内容,inb 定义在其中,
或者贴上来,不同版本可能有差别...
 
 
 

回复

97

帖子

0

TA的资源

一粒金砂(初级)

6
 
另外你读的地址对不对?
在应用层使用要先 ioperm 吧...
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

7
 
首先谢谢morris88赐教:
我用的是iopl()代替 ioperm :

  void pm582::readData()
{
     int base=0x300;                /*基地址0x300*/       
     iopl(3);               /*打开linux读写端口的服务*/       
     int v = inb(base+1);     //8路开入信号状态
     lbl->setText(QString::number(v));  //   这里出错  总是显示 255  
}

void pm582::writeData()
{
        int base=0x300;                /*基地址0x0*/
        iopl(3);                /*打开linux读写端口的服务*/
        outb(0x01,base);        /*闭合第一个端口*/    正常               
}
 
 
 

回复

58

帖子

0

TA的资源

一粒金砂(初级)

8
 
/usr/include/sys/io.h 文件中inb 的定义:
static __inline unsigned char
inb (unsigned short int port)
{
  unsigned char _v;

  __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
  return _v;
}
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

9
 
程序应该是对的,可以用 iopl 来提升权限
写端口 = 0x300, 读端口 = 0x301
你可以看看 iopl 的返回值是不是对的
另外你的 0x301 是不是本身就应该是 0xff(-1) ...
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

10
 
引用 4 楼 morris88 的回复:
你看看 /usr/include/sys/io.h 文件内容,inb 定义在其中,
或者贴上来,不同版本可能有差别...

/usr/include/sys/io.h 文件中inb 的定义:
static __inline unsigned char
inb (unsigned short int port)
{
  unsigned char _v;

  __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
  return _v;
}
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

11
 
貌似 iopl 必须是 root 用户吧 ...
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

12
 
引用 8 楼 morris88 的回复:
程序应该是对的,可以用 iopl 来提升权限
写端口 = 0x300, 读端口 = 0x301
你可以看看 iopl 的返回值是不是对的
另外你的 0x301 是不是本身就应该是 0xff(-1) ...

iopl 的返回值是0,是对的啊
我的io卡是8个断的,如果是0xff 应该都是高电平
现在我是把其中的一个端口加了指定的电压(5v),不应该还是0xff啊
还有就是我随便指定一个基地址(someaddr)来读 inb(someaddr) 返回的都是0xff;
费解啊,我刚接触这方面的不是太懂,希望解惑啊! 谢谢!
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

13
 
引用 10 楼 morris88 的回复:
貌似 iopl 必须是 root 用户吧 ...

root用户?怎么指定?为什么我outb的时候可以呢?
 
 
 

回复

89

帖子

0

TA的资源

一粒金砂(初级)

14
 
就是你以 root 登录系统,然后运行你的程序

你怎么确定的 outb 输出是正确的呢?它不会提供返回值的 ...
如果 outb 是正确的,那么 inb 也是正确的,那么貌似就只有两个
可能:
1、inb 地址不正确
2、硬件有问题
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

15
 
引用 13 楼 morris88 的回复:
就是你以 root 登录系统,然后运行你的程序

你怎么确定的 outb 输出是正确的呢?它不会提供返回值的 ...
如果 outb 是正确的,那么 inb 也是正确的,那么貌似就只有两个
可能:
1、inb 地址不正确
2、硬件有问题

对的,是root用户登录的。
对于outb输出的判断是我在io卡是已经连接好了外围设备(栏杆机),可以指定需要的端口进行正常控制。
1、inb 地址不正确 :我是按照供应商提供基地址进行设置的啊,并且在Windows下是可以的。
2、硬件有问题 : 同上windows下测试过的。
真是费解啊~~~ 快疯了。。。  不过还是谢谢你哈

 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

16
 
另外这个 iopl / ioperm 之类的操作必须是 x86 系列的 cpu 才行 ...

  1. iopl.c

  2. 该程序可以操作所有65536个端口。

  3. 该程序首先设置0x3FF端口的读写权限,然后读出原先的值,然后将原值的LSB翻转并写回端口,并在此读取端口值。

  4. 代码如下:

  5. /*Godbach. Dec 18, 2008

  6. Description:This function is used to test iopl()*/

  7. #include

  8. #include

  9. #include



  10. #define PORT_ADDR 0x3FF



  11. int main(void)

  12. {

  13.       int ret;

  14.       char port_val;



  15.       /*set r/w permission of all 65536 ports*/

  16.       ret = iopl(3);

  17.       if(ret < 0){

  18.            perror("iopl set error");

  19.            return 0;

  20.       }

  21.       port_val = inb(PORT_ADDR);

  22.       printf("Original value of port 0x%x is : %.2x\n", PORT_ADDR, port_val);

  23.       

  24.       /*reverse the least significant bit */

  25.       outb(port_val^0x01, PORT_ADDR);

  26.       port_val = inb(PORT_ADDR);

  27.       printf("Current value of port 0x%x is : %.2x\n", PORT_ADDR, port_val);   

  28.       

  29.       /*set r/w permission of  all 65536 ports*/

  30.       ret = iopl(0);

  31.       if(ret < 0){

  32.            perror("iopl set error");

  33.            return 0;

  34.       }

  35.       return 0;

  36. }

  37. 程序执行结果:

  38. [root@linux misc-progs]# ./a.out

  39. Original value of port 0x3ff is : 01

  40. Current value of port 0x3ff is : 00

  41. [root@linux misc-progs]# ./a.out

  42. Original value of port 0x3ff is : 00

  43. Current value of port 0x3ff is : 01

  44. 该程序执行几次,将进行几次的LSB翻转。

  45. 注:这里再次使用0x3FF端口,主要个人对端口的理解还不很深入,其他高于0x3FF的端口进行测试的时候,没有得到既定的结果。这里权且还使用这个端口,借此对iopl的用法熟悉一下即可。至于在真正使用中,如果系统的某个端口是可以进行配置的,那么执行这个程序应该是可以得到既定结果的。
复制代码
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

17
 
  高深啊 qt高手可能linux端口和windows端口不一样啊
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

18
 
引用 15 楼 morris88 的回复:
另外这个 iopl / ioperm 之类的操作必须是 x86 系列的 cpu 才行 ...


C/C++ codeiopl.c

该程序可以操作所有65536个端口。

该程序首先设置0x3FF端口的读写权限,然后读出原先的值,然后将原值的LSB翻转并写回端口,并在此读取端口值。

代码如下:

/*Godbach. Dec 18, 2008

Description:This function is used to test iopl()*/

#include

#include

#include





谢啦,有点启发哈,我再琢磨琢磨。
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

19
 
请大家继续关注哈~~
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

20
 
io 地址冲突 ...
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表