设备树资源获取:从设备树节点中解析并获取虚拟的内存地址和中断号

引言

在Linux内核驱动开发中,设备树(Device Tree)是一种描述硬件配置的数据结构,它允许内核在不修改代码的情况下支持多种硬件平台。本章将重点介绍如何从设备树节点中解析并获取虚拟的内存地址和中断号,这是驱动开发中的关键步骤。

设备树基础

设备树是一种树形数据结构,用于描述系统中的硬件设备。每个设备在设备树中都有一个节点,节点中包含设备的属性和资源信息。常见的资源包括内存地址和中断号。

设备树结构示例 根节点 CPU节点 设备节点 中断控制器

解析设备树资源

在Linux内核驱动中,我们通常使用以下API来从设备树节点中获取资源:

获取内存地址

内存地址在设备树中通常通过reg属性定义。使用of_iomap()函数可以将物理地址映射到内核的虚拟地址空间,从而允许驱动访问设备寄存器。

#include <linux/of.h>
#include <linux/io.h>

void __iomem *base_addr;

static int my_probe(struct platform_device *pdev)
{
    struct device_node *np = pdev->dev.of_node;
    if (!np) {
        dev_err(&pdev->dev, "No device tree node found.\n");
        return -ENODEV;
    }

    base_addr = of_iomap(np, 0);
    if (!base_addr) {
        dev_err(&pdev->dev, "Failed to map memory.\n");
        return -ENOMEM;
    }

    // 现在可以使用 base_addr 访问设备寄存器
    return 0;
}

获取中断号

中断号在设备树中通过interrupts属性定义。使用irq_of_parse_and_map()函数可以解析并获取中断号。

#include <linux/interrupt.h>

int irq_number;

static irqreturn_t my_interrupt_handler(int irq, void *dev_id)
{
    // 处理中断
    return IRQ_HANDLED;
}

static int my_probe(struct platform_device *pdev)
{
    struct device_node *np = pdev->dev.of_node;
    if (!np) {
        dev_err(&pdev->dev, "No device tree node found.\n");
        return -ENODEV;
    }

    irq_number = irq_of_parse_and_map(np, 0);
    if (!irq_number) {
        dev_err(&pdev->dev, "Failed to get IRQ number.\n");
        return -EINVAL;
    }

    // 注册中断处理程序
    if (request_irq(irq_number, my_interrupt_handler, 0, "my_device", NULL)) {
        dev_err(&pdev->dev, "Failed to request IRQ.\n");
        return -EIO;
    }

    return 0;
}

设备树节点示例

以下是一个简单的设备树节点示例,描述了一个虚拟设备的内存地址和中断信息:

my_device: my_device@1000000 {
    compatible = "vendor,my-device";
    reg = <0x1000000 0x1000>;
    interrupts = <0 25 4>;
};
属性 描述
compatible 用于匹配驱动的字符串
reg 设备的物理地址和大小
interrupts 中断号、触发类型等

软件架构图

设备树资源获取软件架构 设备树节点 驱动探测函数 资源解析API 虚拟地址映射 中断处理程序 设备寄存器访问
注意:在实际开发中,务必错误检查和处理资源获取失败的情况,以确保驱动的稳定性。

总结

通过本章的学习,我们了解了如何从设备树节点中解析并获取虚拟的内存地址和中断号。这些是Linux内核驱动开发中的基本技能,掌握它们对于编写高效、可移植的驱动至关重要。