arm-linux

http://armboard.taobao.com/

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

继续往下学习第九章的内容。从这一章开始才接触到了一些实际的硬件设备,硬件是我的强项啊,呵呵。加油!

 

一、I/O端口和I/O内存

   在学习这部分之前,需要先明确一个概念:side effect。明确这个概念有助于理解内存操作和IO寄存器操作的不同。LDD3中将这个词翻译成了“边际效应”,对此我持保留意见,至少我当时学习的时候就被这个词搞得一头雾水(我本身是搞硬件的,自认为对寄存器还是很了解的,这里完全被这个词搞晕,我勒个去以为是什么高级的东东)。LDD2中将此翻译成“副作用”,这至少比“边际效应”更容易理解一些,但是“副作用”本身多指一件事物不好的方面的影响,不太符合国人的习惯。所以这里我想把它叫做“侧面影响”或者“连带效应”(一家之言,也未必准确),相对于对寄存器值本身的变化的“正面影响”或“表面效应”。 这里我姑且叫他“连带效应”吧。不同于普通内存没有连带效应,对寄存器的操作所产生的连带效应可能是多方面的。一个例子是:对于S3C2440的时钟控制寄存器CLKCON的操作,不仅仅是变化了寄存器本身的值(表面效应),更重要的是每一位都控制了相应外设的时钟使能(连带效应)。另外一个例子:同样对于S3C2440,CLKSLOW寄存器中MPLL_OFF位置1(表面效应)可以Turn off PLL(连带效应),但同时必须要SLOW_BIT位置1才可以实现(表面效应),此时对SLOW_BIT位的操作限制了对MPLL_OFF位操作的结果(连带效应)。这是在同一寄存器不同位的情况,同样的,在不同寄存器之间也会有这样的影响,对一个寄存器的操作能否去的预期的效果取决于另一个寄存器的状态。可以看出,连带效应才是我们进行寄存器操作的目的。这样我们就容易理解为什么对寄存器的操作顺序如此重要。

   编译器工作时往往会对程序进行优化,这种优化可能会改变内存或者寄存器的访问顺序,如果发生这样的情况,IO操作就会出现问题。所以Linux提供了4个宏来确保操作的执行顺序。我们可以在需要严格执行顺序的地方插入这些宏。具体如下:

关于这些宏的具体应用参考本博客转载的一篇文章“内核同步机制-优化屏障和内存屏障”。

 

二、使用I/O端口

   驱动程序中使用一些函数来进行I/O端口的分配和操作。具体如下(linux 2.6.32):

   分配相关的函数:

 

下面详细看一下__request_region的实现,定义在kernel/resource.c中。

 

 

 下面看一下__release_region的实现:

 

   操作I/O端口的函数:

posted on 2011-01-18 14:46  arm-linux  阅读(398)  评论(0编辑  收藏  举报