LDD3第九章的学习-与硬件通信

 

作者:Aningsk ,本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化版本许可协议进行许可。 


最近在忙别的东西好久没来写了,第九章和第十章之前就看过,但是一直没有来写啊。今天下定决心写一写,嘿嘿~话说,时隔很久都要忘记看了什么东西了。

 

I/O寄存器

CPU与外接硬件之间的通信,一定是要通过CPU的IO引脚的;而且控制这些引脚是与CPU硬件相关的:这里主要区分了两大架构:x86和ARM。他们提供了两种不太相同的IO控制方法。对于x86来说,叫做“IO端口”;对于ARM来说,叫做“IO内存”。这两者的区别待会儿再说,先记录一下使用IO应该注意的问题,因为不管哪种方式,都是使用了IO寄存器(我理解就是使用IO时,用到的硬件寄存器——和内存差不多)。

使用IO寄存器可能会出现一定的“副作用”(sideeffect,中文书上翻译的是“边际效应”,我认为不够恰当),产生这些副作用的原因是:CPU或编译器不合适到优化而改变了我们预期的IO动作。使用IO寄存器时,和使用内存没什么太大区别,它们会情不自禁的优化一下。正如CPU对内存的访问会使用“缓存”来提高效率,编译器会对代码翻译出的指令进行重新排序,来达到更快的执行。

但是当我们使用IO的时候就有问题了:如果使用了高速缓存,数据很可能没有实际地从IO引脚上输入输出,我们实际的操作在外接的硬件来看什么都没有发生;如果编译器对指令重新排序,我们对硬件的控制时序将会变化,从而导致致命的错误。所以,我们要做的就是解决这两个“自作聪明”而导致的问题。

书中237页讲了如何解决。关于缓存的解决方法说的比较简单:把底层硬件配置成在访问IO区域时禁止硬件缓存即可。话说,描述的好简单啊……由编译器优化和硬件重新排序引起的问题,则是在顺序执行的操作之间添加“内存屏障”,Linux提供了一些宏完成,如rmb,wmb,mb具体实现和平台相关,我们一般不用管。内存屏障可以保证它之前的指令不会被重新排序到它的后面,或者说它之前的指令的执行确保已经生效。

 

IO端口与IO内存

前面已经提到过:管理设备IO有两种方式——x86的IO端口方式和ARM的IO内存方式。

对于x86架构,外设通常具有一个独立的地址空间,叫做IO地址空间;这个空间是不同于内存地址空间的。使用IO设备必须首先向内核申请使用的资源(或叫做端口),即使用request_region。这个函数有三个参数,分别是起始物理地址first,申请长度n(n个端口),设备名称。返回值是struct resource 类型的指针。这个函数成功返回结构体指针,失败返回NULL。我看了一下例子的代码,返回值只用来看看是不是NULL,并没有使用struct resource的结构体。当我们要使用申请的端口时,调用inb, outb, inw就可以了(参见书中240页),它们的参数有一个port,就是要读写的地址——first+m(0<=m<n)。如果我们不再使用,就应该将资源返还给系统release_region。

 

对于ARM架构,外设是没有独立的地址空间的,使用IO设备需要将它们的地址映射到内存,叫做IO内存映射。类似的,在使用IO内存前,要向内核申请:request_mem_region(start, n, name)参数的含义与request_region相同(其实这两个函数是都是基于__request_region的)。不同的是:申请完之后,还不能立即使用它们,必须把这个地址映射为虚拟内存地址空间。这就是用ioremap函数来实现,记得以前的文章提到过。举个例子:

request_mem_region(short_base, SHORT_NR_PORTS, “short”);

short_base = (unsigned long)ioremap(short_base, SHORT_NR_PORTS);

检查返回值的部分就不写了。 然后我们就可以使用ioread8, iowrite8等等函数来操作了(参见书中250页)。也要记得最后将资源返还给系统。

 

像使用IO内存一样使用IO端口

相同的硬件因为不同的CPU架构,使用的IO操作方法不同,这显然不是地道的可移植性所喜欢的。所以为了最小化IO端口和IO内存的表面区别,2.6内核引入了void *ioport_map(port, count);这样就可以像使用IO内存那样使用IO端口啦——就是ioread8之类的那些函数。但是我们在使用ioport_map之前仍然需要使用request_region来申请端口资源。

 

嗯,好了~大概就是这个样子:说了怎么访问IO寄存器。

 

Aningsk

2015-06-14


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值