Linux驱动技术之一:访问I/O内存

    ARM      是对内存空间和IO空间统一编址的,所以,通过读写SFR来控制硬件也就变成了通过读写相应的SFR地址来控制硬件。这部分地址也被称为I/O内存。x86中对I/O地址和内存地址是分开编址的,这样的IO地址被称为I/O端口。本文只讨论IO内存的访问

IO内存访问流程

我们知道,为了管理最重要的系统资源并让物理地址对进程透明,     Linux   使用了内存映射机制,就是一个进程如果想访问一个物理内存地址(eg.SFR地址),那么首先就是将其映射成虚拟地址。

 Linux驱动技术之一:访问I/O内存_设计制作_存储技术

IO内存申请/归还

Linux提供一组函数用于申请和释放IO内存的范围,这两个A     PI   在访问IO内存的时候并不是必须的,但是建议使用,他们可以检查申请的资源是否可用,增加IO访问的安全性,如果可用则申请成功,并标志为已用,其他驱动想在这个进程归还资源前申请就会失败。

request_mem_region()宏函数向内存申请n个内存地址,这些地址从fi     rs   t开始,len长,name表示设备的名称,成功返回非NULL失败返回NULL。

/** * request_mem_region - crea     te   a new busy resource region * @start: resource start address * @n: resource region size * @name: reserving caller's ID string */struct resource * request_mem_region(resource_size_t start, resource_size_t n,const char *name)

release_mem_region()宏函数顾名思义就是将request_mem_region()申请的IO内存资源归还给内核以便其他进程也可以访问该IO内存。

/** * release_mem_region - release a previously reserved resource region * @start: resource start address * @n: resource region size */void release_mem_region(resource_size_t start, resource_size_t n,const char *name)

IO内存映射/去映射

申请了IO资源,接下来就是进行物理地址到虚拟地址的映射。内核提供的API如下

sta     ti   c inline void __iomem *ioremap(unsigned long port, unsigned long size)

sta  TI c inline void iounmap(vola  TI le void __iomem *addr)

IO内存访问API

ARM的SFR是32bit的,我们在经过了ioremap之后其实就可以直接通过强制类型转换来读取获取的虚拟地址,但是这种方法不够安全,一不小心就会读错位,为此,内核同样提供的标准的API来读写IO内存,不但代码的安全性更高,可读性也得到了改善。

读IO

unsigned int ioread8(void *addr)unsigned int ioread16(void *addr)unsigned int ioread32(void *addr)

写IO

void iowrite8(u8 val,void *addr)void iowrite16(u8 val,void *addr)void iowrite32(u8 val,void *addr)

读一串IO内存

void ioread8_rep(void *addr,void *buf,unsigned long len)void ioread16_rep(void *addr,void *buf,unsigned long len)void ioread32_rep(void *addr,void *buf,unsigned long len)

写一串IO内存

void iowrite8_rep(void *addr,const void *buf,unsigned long len)void iowrite16_rep(void *addr,const void *buf,unsigned long len)void iowrite32_rep(void *addr,const void *buf,unsigned long len)

复制IO内存

void m     emc   py_f     rom   io(void *dest,void *source,unsigned long len)void memcpy_toio(void *dest,void *source,unsigned long len)

设置IO内存

void memset_io(void *addr,u8 value,unsigned int len)

4
30
0
72

相关资讯

  1. 1、灵魂战马踏血而来《口袋兽人》新资料片即将上线2016
  2. 2、《洛奇英雄传:永恒》内容抢鲜看性感一脉传承1481
  3. 3、《疯狂挂机》新版本上线挂机更方便~2222
  4. 4、《刀塔来了》蓝猫领衔驾到三灵开泰豪礼送不停3613
  5. 5、《SD敢达强袭战线》新服开启带来全新征程4224
  6. 6、《推理学院》新资料片”狼人杀“即将发布2146
  7. 7、黄秋生陷婚内出轨丑闻,心情低落自嘲:要小心超级好的女人3721
  8. 8、《极无双》热血新篇章全新军团战开启4191
  9. 9、《紫青双剑》战力暴涨物品锻造技巧5004
  10. 10、《十万个冷笑话》手游再添全新狠角色4833
全部评论(0)
我也有话说
0
收藏
点赞
顶部