Linux学习之I/O内存访问详解

来源:互联网 发布:c语言图书管理系统 编辑:程序博客网 时间:2024/06/05 21:13
ARM是对内存空间和IO空间统一编址的,所以,通过读写SFR来控制硬件也就变成了通过读写相应的SFR地址来控制硬件。这部分地址也被称为I/O内存。x86中对I/O地址和内存地址是分开编址的,这样的IO地址被称为I/O端口。本文只讨论linux系统中IO内存的访问。
  IO内存访问流程
  我们知道,为了管理最重要的系统资源并让物理地址对进程透明,Linux使用了内存映射机制,就是一个进程如果想访问一个物理内存地址(eg.SFR地址),那么首先就是将其映射成虚拟地址。

IO内存申请/归还
  Linux提供一组函数用于申请和释放IO内存的范围,这两个API在访问IO内存的时候并不是必须的,但是建议使用,他们可以检查申请的资源是否可用,增加IO访问的安全性,如果可用则申请成功,并标志为已用,其他驱动想在这个进程归还资源前申请就会失败。
  request_mem_region()宏函数向内存申请n个内存地址,这些地址从first开始,len长,name表示设备的名称,成功返回非NULL失败返回NULL
  /**
  * request_mem_region - create 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如下
  static inline void __iomem *ioremap(unsigned long port, unsigned long size)
  static inline void iounmap(volatile void __iomem *addr)
  IO内存访问API
  ARMSFR32bit的,我们在经过了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,unsignedlong 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 memcpy_fromio(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)

来源:51CTO
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 汽车轮胎锈住了怎么办 新轮胎不好装怎么办 学it找不到工作怎么办 血液里有微生物怎么办 机械硬盘不显示怎么办 六安建筑机械租赁公司怎么办 别墅楼梯太陡怎么办 不锈钢楼梯太陡怎么办 真皮白色鞋脏了怎么办 白色牛皮包脏了怎么办 白色羊皮鞋脏了怎么办 白色真皮染色了怎么办 白色漆皮鞋脏了怎么办 对鉴定结果不服怎么办 洗衣机入水口堵塞怎么办 华科办临时饭卡怎么办 血浆乳酸测定高怎么办 olay大红瓶过敏怎么办 饥一顿饱一顿怎么办 朝鲜人向去韩国怎么办? 我是超级大方脸怎么办 被精神病砍断四根筋怎么办 40小时不睡觉怎么办 边防转业军人安置不好怎么办 转业军人孩子读书怎么办玉环 军官证丢了怎么办 飞行学员停飞了怎么办 丹东港债券违约怎么办 对村党支部贿选怎么办 马自达2油耗高怎么办 马自达1.5油耗高怎么办 马自达5停产配件怎么办 期货账户休眠了怎么办 低于二本线怎么办 听力测试不过关怎么办 安装的天正过期怎么办 天正t20v4过期了怎么办 鸡肉菊花一起吃怎么办 孕妇误食马兰头怎么办 孕29周喉咙痛怎么办 哺乳期吃了当归怎么办