获取资源信息

内核模块驱动加载之后,就开始把硬件资源管理起来,如读写寄存器、接收中断。

来看看设备树里的一条:

    xillybus_0: xillybus@50000000 {
compatible = "xlnx,xillybus-1.00.a";
reg = < 0x50000000 0x1000 >;
interrupts = < 0 59 1 >;
interrupt-parent = <&gic>; xlnx,max-burst-len = <0x10>;
xlnx,native-data-width = <0x20>;
xlnx,slv-awidth = <0x20>;
xlnx,slv-dwidth = <0x20>;
xlnx,use-wstrb = <0x1>;
} ;

驱动一般在探测函数里就取得了硬件内存段的所有权(探测函数就是probe指针指向的函数)。

来看看一个典型探测函数的框架:

static int __devinit xilly_drv_probe(struct platform_device *op)
{
const struct of_device_id *match; match = of_match_device(xillybus_of_match, &op->dev); if (!match)
return -EINVAL;

第一个操作就是检查probe是否作用在相关硬件上。

访问寄存器

下一步,分配一段内存并映射到虚拟内存中。

  int rc = 0;
struct resource res;
void *registers; rc = of_address_to_resource(&op->dev.of_node, 0, &res);
if (rc) {
/* Fail */
} if (!request_mem_region(res.start, resource_size(&res), "xillybus")) {
/* Fail */
} registers = of_iomap(op->dev.of_node, 0); if (!registers) {
/* Fail */
}

of_address_to_resource() 在设备树中找到第一个"reg",并将解析到的信息填充在"res"结构体里。这个例子里"reg = < 0x50000000 0x1000 >”, 指的是分配一块起始物理地址是0x50000000,长度为0x1000字节的空间。of_address_to_resource()会设置res.start = 0x50000000, res.end = 0x50000fff。

调用request_mem_region()是为了注册特殊的内存段。目的是避免两个驱动访问同一段寄存器空间而造成的冲突。resource_size()是个内联函数,返回segment的大小(此处是0x1000)。

of_iomap()函数是of_address_to_resource()和ioremap()的组合,本质上等效于ioremap(re.start, resource_size(&res)).确保物理段已经映射到虚拟内存中,函数返回内存段的虚拟地址空间起始地址。

显然,当模块卸载或某个错误发生时,这些操作都需要有恢复动作。

访问硬件寄存器请使用iowrite32(),ioread32()以及其他的函数和宏,而不要直接使用上面的"register"指针。

中断处理

这部分的驱动很简单,类似如下:

  irq = irq_of_parse_and_map(op->dev.of_node, 0);

  rc = request_irq(irq, xillybus_isr, 0, "xillybus", op->dev);

irq_of_parse_and_map()在设备树里查找中断的描述项,然后返回中断号,request_irq()将使用这个中断号来注册。第二个参数是0,表示使用设备树中的第一个中断。

设备树里面描述是:

      interrupts = < 0 59 1 >;
interrupt-parent = <&gic>;

那么使用了这三个数据中的哪一个呢?

第一个0是一个标志,用于指示中断是否是SPI(共享中断,shared peripheral interrupt)。非0值表示它是SPI。事实上在Zynq硬件上,这些中断都是共享的,这里是为了方便才写0, 软件上认为它不共享。

第二个数据表示中断号。

第三个数字是中断类型,可以有如下值:

  • 0 - 内核不改变它,开机或uboot设置它是什么样就什么样。
  • 1 - 上升沿触发
  • 4 - 电平触发,高电平表示来中断。

不允许有其他值,下降沿触发和低电平中断目前不支持,因为硬件不支持那些模式。如果需要这样的触发方式,就得在硬件上加一个非门。

值得注意的是第三个数字在设备树里通常都是0, 所以Linux内核不去改变中断模式。这通常意味着高电平触发。这也让驱动依赖于bootloader里的设置。

interrupt-parent 这一句,必须指向中断控制器&gic。如果反编译一个DTB文件,这里的&gic会被一个数字代替,通常是0x1。

翻译:A Tutorial on the Device Tree (Zynq) -- Part IV的更多相关文章

  1. 翻译:A Tutorial on the Device Tree (Zynq) -- Part V

    A Tutorial on the Device Tree (Zynq) -- Part V Application-specific data 之前提过,设备树中是一些特殊信息,这样一个驱动可以管理 ...

  2. 翻译:A Tutorial on the Device Tree (Zynq) -- Part III

    A Tutorial on the Device Tree (Zynq) -- Part III 定义外设 可能你读本文是为了给你的设备写一个Linux驱动,在这方面要推荐著名的<Linux D ...

  3. 翻译:A Tutorial on the Device Tree (Zynq) -- Part II

    A Tutorial on the Device Tree (Zynq) -- Part II 设备树结构 Zynq的设备树如下: /dts-v1/; / { #address-cells = < ...

  4. 翻译:A Tutorial on the Device Tree (Zynq) -- Part I

    A Tutorial on the Device Tree (Zynq) -- Part I 此教程的目的 本教程是针对Xilinx' Zynq-7000 EPP设备(一个集成了FPGA的ARM Co ...

  5. Device Tree Usage 【转】

    转自:http://blog.chinaunix.net/uid-20522771-id-3457184.html 原文链接:http://devicetree.org/Device_Tree_Usa ...

  6. Device Tree(二):基本概念

    转自:http://www.wowotech.net/linux_kenrel/dt_basic_concept.html 一.前言 一些背景知识(例如:为何要引入Device Tree,这个机制是用 ...

  7. Device Tree Usage( DTS文件语法)

    http://elinux.org/Device_Tree_Usage Device Tree Usage     Top Device Tree page This page walks throu ...

  8. 【转】Device Tree(二):基本概念

    原文网址:http://www.wowotech.net/linux_kenrel/dt_basic_concept.html 一.前言 一些背景知识(例如:为何要引入Device Tree,这个机制 ...

  9. Device Tree Usage(理解DTS文件语法)

    Basic Data Format The device tree is a simple tree structure of nodes and properties. Properties are ...

随机推荐

  1. 爬虫开发python工具包介绍 (4)

    本文来自网易云社区 作者:王涛 此处我们给出几个常用的代码例子,包括get,post(json,表单),带证书访问:Get 请求 @gen.coroutine def fetch_url():     ...

  2. 自己项目使用了ARC,项目中使用第三方库继续引用ARC

    Objective-C引入ARC(Automatic Reference Counting)后,我们经常会面对这样一种困境:自己的项目使用了ARC,却发现要使用的第三方类库是non-ARC的:又或者自 ...

  3. 修复Centos7双系统引导

    1.进入CentOS系统 2.命令行输入 vi /boot/grub2/grub.cfg 3.在文件空白处添加下列代码 menuentry 'Windows 7'{ insmod part_msdos ...

  4. zabbix的配置之新版微信报警(二)

    zabbix配置2018版本微信报警 centos6.5中微信报警需要Python2.7版本之上,由于服务器是centos6.5.所以需要升级版本2.6到2.7. 具体升级步骤:Python升级版本2 ...

  5. 刷题总结——学姐的逛街计划(vijos1891费用流)

    题目: doc 最近太忙了, 每天都有课. 这不怕, doc 可以请假不去上课.偏偏学校又有规定, 任意连续 n 天中, 不得请假超过 k 天. doc 很忧伤, 因为他还要陪学姐去逛街呢. 后来, ...

  6. 【kmp+最小循环节】poj 2406 Power Strings

    http://poj.org/problem?id=2406 [题意] 给定字符串s,s=a^n,a是s的子串,求n最大是多少 [思路] kmp中的next数组求最小循环节的应用 例如 ababab ...

  7. Cstring中GetBuffer()方法的主要作用

    摘自:http://bbs.csdn.net/topics/310247836 GetBuffer()主要作用是将字符串的缓冲区长度锁定   CString::GetBuffer有两个重载版本: (1 ...

  8. 洛谷 [T21776] 子序列

    题目描述 你有一个长度为 \(n\) 的数列 \(\{a_n\}\) ,这个数列由 \(0,1\) 组成,进行 \(m\) 个的操作: \(1\ l\ r\) :把数列区间$ [l,r]$ 内的所有数 ...

  9. NOJ 1111 保险箱的密码 【大红】 [区间dp]

    传送门 保险箱的密码 [大红] 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 118            测 ...

  10. 结构字段验证--validator.v9

    官网:https://godoc.org/gopkg.in/go-playground/validator.v9#hdr-Baked_In_Validators_and_Tags package va ...