原创 I/O 端口和 I/O 内存 3

2014-9-4 09:44 861 11 12 分类: MCU/ 嵌入式

2.2、操作I/O端口

 

在驱动成功请求到I/O 端口后,就可以读写这些端口了。部分硬件会将81632位端口区分开,无法像访问内存那样混淆使用。驱动程序必须调用不同的函数来访问不同大小的端口。

如同前面所讲的,仅支持单地址空间的计算机体系通过将I/O端口地址重新映射到内存地址来伪装端口I/O 。为了提高移植性,内核对驱动隐藏了这些细节。Linux 内核头文件(系依赖的头文件<asm/io.h>) 定义了下列内联函数来存取I/O端口:

 

/* inb/outb:读/写字节端口(8位宽)。有些体系将port参数定义为unsigned long;而有些平台则将它定义为unsigned short。inb的返回类型也是依赖体系的 */
unsigned inb(unsigned port);
void outb(unsigned char byte, unsigned port);

/* inw/outw:读/写字端口(16位宽) */
unsigned inw(unsigned port);
void outw(unsigned short word, unsigned port);

/* inl/outl:读/写32位端口。longword也是依赖体系的,有的体系为unsigned long;而有的为unsigned int */
unsigned inl(unsigned port);
void outl(unsigned longword, unsigned port);

从现在开始,当我们使用unsigned 没有进一步指定类型时,表示是一个依赖体系的定义

注意,没有64位的I/O端口操作函数。即便在64位体系中,端口地址空间使用一个32(最大)的数据通路。

2.3、从用户空间访问I/O端口

2.2节介绍的函数主要是提供给驱动使用,但它们也可在用户空间使用,至少在PC机上可以GNU C 库在 <sys/io.h> 中定义它们。如果在用户空间使用这些函数,必须满足下列条件:

1)、程序必须使用-O选项编译来强制扩展内联函数

2)、必须使用iopermiopl系统调用(#include <sys/perm.h>) 来获得进行操作I/O端口的权限ioperm 为获取单个端口的操作许可iopl 为获取整个I/O空间许可。这2个函数都是x86特有的

3)、程序必须以root来调用ioperm或者iopl,或者其父进程(祖先)必须以root获得的端口操作权限

如果平台不支持iopermiopl系统调用,通过使用/dev/prot设备文件,用户空间仍然可以存取I/O 端口。但是要注意的是,这个文件的定义也是依赖平台的

2.4、字串操作

除了一次传递一个数据的I/O操作,某些处理器实现了一次传递一序列数据(单位可以是字节、字和双字)的特殊指令。这些所谓的字串指令,它们完成任务比一个C语言循环更快。下列宏定义实现字串操作,在某些体系上,它们通过使用单个机器指令实现;但如果目标处理器没有进行字串I/O指令,则通过执行一个紧凑的循环实现

字串函数的原型是:

 

/* insb:从I/O端口port读取count个数据(单位字节)到以内存地址addr为开始的内存空间 */
void insb(unsigned port, void *addr, unsigned long count);

/* outsb:将内存地址addr开始的count个数据(单位字节)写到I/O端口port */
void outsb(unsigned port, void *addr, unsigned long count);

/* insw:从I/O端口port读取count个数据(单位字)到以内存地址addr为开始的内存空间 */
void insw(unsigned port, void *addr, unsigned long count);

/* outsw:将内存地址addr开始的count个数据(单位字)写到I/O端口port */
void outsw(unsigned port, void *addr, unsigned long count);

/* insl:从I/O端口port读取count个数据(单位双字)到以内存地址addr为开始的内存空间 */
void insl(unsigned port, void *addr, unsigned long count);
/* outsl:将内存地址addr开始的count个数据(单位双字)写到I/O端口port */
void outsl(unsigned port, void *addr, unsigned long count);

 

 

文章评论1条评论)

登录后参与讨论

用户377235 2015-12-25 19:23

sssssssssssssss
相关推荐阅读
用户1642694 2014-09-16 11:27
arm常用指令
  常用ARM指令及汇编包括   1、ARM处理器寻址方式 2、指令集介绍 3、伪指令 4、ARM汇编程序设计 5、C与汇编混合编程   ARM处理器寻址方式 ...
用户1642694 2014-09-16 11:26
Android中Intent的
  本文介绍Android中Intent的各种常见作用。       1 Intent.ACTION_MAIN   String: android.intent.act...
用户1642694 2014-09-16 11:25
验证 大端小端
  #include <stdio.h>   int main(void) {     union{         short s;         ch...
用户1642694 2014-09-09 20:42
VC#通过TCP/IP实现远程控制
  如何控制对方计算机,有程序人员自己定义.,这里给出核心技术代码并且实现部分控制功能. 这里我们把运行在我们自己电脑上的控制程序叫 Server  被管理电脑运行的程序叫Client ...
用户1642694 2014-09-09 20:40
共模扼流圈在高速数据链路的使用
   简介 共模扼流圈广泛应用于高速串行数据传输。当传输介质是连接两个子系统的差分线电缆时, 其应用则更为普遍。使用共模扼流圈可以减少电缆的电磁辐射噪音,并有助于符合规范要求。由于共...
用户1642694 2014-09-09 20:38
电平和频率计算
  图:输入端口电平要求 图:输出端口电平极限条件 图:输入端口电平要求   图:输出端口电平 图:时序要求:接线图9013的参数 ...
我要评论
1
11
关闭 站长推荐上一条 /2 下一条