Linux设备驱动开发-3与硬件通信.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Linux设备驱动程序学习(9) 与硬件通信 ? I/O 端口和 I/O 内存 每种外设都是通过读写寄存器来进行控制。 在硬件层,内存区和 I/O 区域没有概念上的区别: 它们都是通过向在地址总线和控制总线发出电平信号来进行访问,再通过数据总线读写数据。 使用 I/O 端口 I/O 端口是驱动用来和许多设备之间的通讯方式。 I/O 端口分配 在尚未取得端口的独占访问前,不应对端口进行操作。内核提供了一个注册用的接口,允许驱动程序声明它需要的端口: #include linux/ioport.h struct resource *request_region(unsigned long first, unsigned long n, const char *name);/*告诉内核:要使用从 first 开始的 n 个端口,name 参数为设备名。若分配成功返回非 NULL,否则将无法使用需要的端口。*/ /*所有的的端口分配显示在 /proc/ioports 中。若不能分配到需要的端口,则可以到这里看看谁先用了。*/ /*当用完 I/O 端口集(可能在模块卸载时), 应当将它们返回给系统*/ void release_region(unsigned long start, unsigned long n); int check_region(unsigned long first, unsigned long n); /*检查一个给定的 I/O 端口集是否可用,若不可用, 返回值是一个负错误码。不推荐使用*/ 操作 I/O 端口 在驱动程序注册I/O 端口后,就可以读/写这些端口。大部分硬件会把8、16和32位端口区分开,不能像访问系统内存那样混淆使用。驱动必须调用不同的函数来存取不同大小的端口。 Linux 内核头文件(体系依赖的头文件 asm/io.h ) 定义了下列内联函数(有的体系是宏,有的不存在)来访问 I/O 端口: unsigned inb(unsigned port); void outb(unsigned char byte, unsigned port); /*读/写字节端口( 8 位宽 )。port 参数某些平台定义为 unsigned long ,有些为 unsigned short 。 inb 的返回类型也体系而不同。*/ unsigned inw(unsigned port); void outw(unsigned short word, unsigned port); /*访问 16位 端口( 一个字宽 )*/ unsigned inl(unsigned port); void outl(unsigned longword, unsigned port); /*访问 32位 端口。 longword 声明有的平台为 unsigned long ,有的为 unsigned int。*/ 在用户空间访问 I/O 端口 以上函数主要提供给设备驱动使用,但它们也可在用户空间使用,至少在 PC上可以。 GNU C 库在 sys/io.h 中定义了它们。 串操作 除了一次传输一个数据的I/O操作,一些处理器实现了一次传输一个数据序列的特殊指令,序列中的数据单位可以是字节、字或双字,这是所谓的串操作指令。它们完成任务比一个 C 语言循环更快。下列宏定义实现了串I/O,它们有的通过单个机器指令实现;但如果目标处理器没有进行串 I/O 的指令,则通过执行一个紧凑的循环实现。 有的体系的原型如下: void insb(unsigned port, void *addr, unsigned long count); void outsb(unsigned port, void *addr, unsigned long count); void insw(unsigned port, void *addr, unsigned long count); void outsw(unsigned port, void *addr, unsigned long count); void insl(unsigned port, void *addr, unsigned long count); void outsl(unsigned port, void *addr, unsigned long count); 使用时注意: 它们直接将字节流从端口中读取或写入。当端口和主机系统有不同的字节序时,会导致不可预期的结果。 使用 inw 读取端口应在必要时自行转换字节序,以匹配主机字节序。 暂停式?I/O 为了匹配低速外设的速度,有时若 I/O 指令后面还紧跟着另一个类似的I/O指令,就必须在

文档评论(0)

zhuliyan1314 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档