IO管理一基础
来源:互联网 发布:知乎 乾隆 书法 编辑:程序博客网 时间:2024/06/06 10:44
从CPU连出来一把线:数据总线、地址总线、控制总线,这把线上挂着N个接口,有相同的,有不同的,名字叫做存储器接口、中断控制接口、DMA接口、并行接口、串行接口、AD接口……一个设备要想接入,就用自己的接口和总线上的某个匹配接口对接……于是总线上出现了各种设备:内存、硬盘,鼠标、键盘,显示器……
外设都是通过读写设备上的寄存器来进行的,外设寄存器也称为“I/O端口”,而IO端口有两种编址方式:独立编址和统一编制。
统一编址:外设接口中的IO寄存器(即IO端口)与主存单元一样看待,每个端口占用一个存储单元的地址,将主存的一部分划出来用作IO地址空间。
统一编址也称为“I/O内存”方式,外设寄存器位于“内存空间”(很多外设有自己的内存、缓冲区,外设的寄存器和内存统称“I/O空间”)。
独立编址(单独编址):IO地址与存储地址分开独立编址,I/O端口地址不占用存储空间的地址范围,这样,在系统中就存在了另一种与存储地址无关的IO地址,CPU也必须具有专用与输入输出操作的IO指令(IN、OUT等)和控制逻辑。
IO端口:当一个寄存器或者内存位于IO空间时;
IO内存:当一个内存或者寄存器位于内存空间时;
在linux使用platform_driver_register()注册 platform_driver 时, 需要在 platform_driver 的probe() 里面知道设备的中断号, 内存地址等资源。
这些资源的描述信息存放在 resource数据结构中, 相同的资源存放在一个树形树形数据结构中, 通过父节点, 兄弟节点, 子节点相连。 比如中断资源, IO端口资源, IO内存资源, DMA资源有不同资源树。
Linux使用 struct resource来描述一个resouce
struct resource{
resource_size_t start; //资源范围的开始
resource_size_t end; //资源范围的结束
constchar *name; //资源拥有者名
unsignedlong flags; //资源属性标识
struct resource *parent, *sibling, *child; //资源树的父节点, 兄弟节点, 字节点指针
};
resource_size_t 由系统决定为uint32_t 或uint64_t 。
在platform机制里,使用platform_get_resource()来获取指定的资源类型。
//比如获取想获取中断号,
irq = platform_get_irq(pdev, 0);
intplatform_get_irq(struct platform_device*dev, unsigned intnum)
{
struct resource *r =platform_get_resource(dev,IORESOURCE_IRQ, num);
return r ? r->start: -ENXIO;
}
EXPORT_SYMBOL_GPL(platform_get_irq);
platform_get_irq() //会返回一个start, 即可用的中断号。
//之后便可使用request_irq()来注册中断服务函数。
//再比如想要获取IO内存资源:
struct resource *res_mem = platform_get_resource(pdev, IORESOURCE_MEM,0);
即可得到一个IO内存资源节点指针, 包括了地址的开始,结束地址等, 该IO内存的长度可用resource_size() 来获取, 但这段资源只是一个描述, 想真正使用这段IO内存, 还要经过先申请, 再映射的过程。
例如可使用devm_request_mem_region()申请出使用这段IO内存, 再使用ioremap() 将其映射出来, 供用户空间使用。
devm_request_mem_region(&pdev->dev, res_mem->start, resource_size(res_mem), res_mem->name))
addr_start = ioremap(res_mem->start, resource_size(res_mem));
ioremap() 的返回值即为该资源的虚拟地址。
IO内存的资源是在设备树源(DeviceTree Source)文件(以.dts结尾)里给出的,.dts文件就是用来描述目标板硬件信息的,在uboot启动后, 使用uboot提供的特定API将其获取出来, 如fdt_getprop(), fdt_path_offset(),这些API包含在uboot 的头文件
gpio:gpio-controller@1070000000800 {
#gpio-cells=<2>;
compatible ="cavium,octeon-3860-gpio";
reg =<0x107000x000008000x00x100>;
gpio-controller;
根据其描述, 可知道gpio控制器的IO内存起始地址为:0x107900000800, 长度为0x100.
即从 0x107900000800 到0x1079000008ff.
在目标板里使用 cat /proc/iomem可以看到:
1070000000800-10700000008ff: /soc@0/gpio-controller@1070000000800
关于i2c 的描述:
twsi0: i2c@1180000001000{
#address-cells=<1>;
#size-cells=<0>;
compatible ="cavium,octeon-3860-twsi";
reg =<0x118000x000010000x00x200>;
interrupts =<045>;
clock-rate =<100000>;
IO内存起始地址为: 0x118000001000, 长度为0x200.
从 0x118000001000 到0x1180000011ff.
在目标板里使用 cat /proc/iomem可以看到:
1180000001000-11800000011ff: /soc@0/i2c@1180000001000
- IO管理一基础
- java基础---IO(一)
- Java IO 基础总结(一)
- Java基础--IO流(一)
- 【JavaSE基础】------IO流【一】
- JAVA基础------IO操作(一)
- java基础学习要点一:IO流
- Java io基础(一)FILE类
- Java io基础(一)RandomAccessFile类
- 黑马程序员--Java基础--09IO(一)
- io基础学习-拷贝文件(一)
- 文件IO的基础操作(一)
- 黑马程序员-------java基础 IO流<一>
- java基础巩固之IO(一)
- JAVA IO (一) 基础深入理解
- Java基础—IO流(一)
- 黑马程序员---------------JAVA基础-----------------IO流一
- 黑马程序员-----Java基础-----IO流(一)
- python实现selenium断言和验证
- 2015年总结
- 设计模式1—创建型模式
- 跳转系统联系人页面
- img图片下面出现莫名的下边距
- IO管理一基础
- AndroidStudio插件GsonFormat快速实现JavaBean
- JQuery 核心函数 基础研究与提高
- 编写测试类与方法
- 字典转模型注意事项
- 系统设计基础
- 记录一个可以搜索JAVA源代码的网站
- 《深入浅出Node.js》学习笔记——(一)Node简介
- Android Studio运行直接打签名包(release)