在Linux设备驱动程序中读写设备寄存器?

问题描述 投票:0回答:1

首先:这是我第一次尝试为 Linux 内核做驱动程序,所以如果我完全错了,请告诉我。

在我当前的项目中,我们在板上添加了一个新设备(FPGA),我现在的任务是为该设备编写驱动程序。(我接受这个任务主要是因为我想学习,作为一个很大的挑战我)。

在 youtube 上花了几个小时后,我至少成功地完成了一个模块的框架,可以将其插入内核:

/* Match table for OF platform binding */
const struct of_device_id module_of_match[] = {
        { .compatible = "foo,testtest", },
        { /* end of list */},
};
MODULE_DEVICE_TABLE(of, module_of_match);

static int module_open(struct inode *inode, struct file *file_p) {
    pr_notice("module_open is called\n");
    return 0;
}

static int module_release(struct inode *inode, struct file *file_p) {
    pr_notice("module_release is called\n");
    return 0;
}

static ssize_t module_write(struct file *file_p, const char __user *user_buffer, size_t count, loff_t *f_pos) {
    pr_notice("module_write is called\n");
    return 0;
}

static ssize_t module_read(struct file *file_p, char __user *user_buffer, size_t count, loff_t *f_pos) {
    pr_notice("module_read is called\n");
    return 0;
}

static int module_probe(struct platform_device *pdev) {
    int ret;
    void __iomem *base_addr;
    struct device *dev = &pdev->dev;
    struct resource *res;

    pr_notice("module_probe called...name: %s\n", pdev->name);
    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    base_addr = devm_ioremap_resource(dev, res);
    if(IS_ERR(base_addr)){
        pr_err("module_probe: Error when calling devm_ioremap_resource\n");
        return -1;
    }
    ret = misc_register(&module_dev);
    if (ret) {
        pr_err("module_probe: Failed to register module_dev\n");
        return ret;
    }
    pr_notice("module_probe registered %s\n", &module_dev.name);

    return 0;
}

static int module_remove(struct platform_device *pdev)
{
    pr_info("module_remove called...\n");
    misc_deregister(&module_dev);
    return 0;
}


/* Driver operations */
struct platform_driver module_driver = {
        .probe = module_probe,
        .remove = module_remove,
        .driver = {
            .name = DRIVER_NAME,
            .owner = THIS_MODULE,
            .of_match_table = module_of_match
        },
};

/**
 * @brief Structure holding configure file operations
 */
static struct file_operations module_fops = {
        .owner = THIS_MODULE,                        ///< Owner of module
        .open = module_open,                        ///< Open function
        .release = module_release,                  ///< Release function
        .read = module_read,                        ///< Read function
        .write = module_write,                      ///< Write function
};

module_platform_driver(module_driver);

static struct miscdevice module_dev = {
    .minor = MISC_DYNAMIC_MINOR, // Allocate a dynamic minor number
    .name = DRIVER_NAME,
    .fops = &module_fops,
};

设备树节点:

uart_dev: dev8@a0190000 {
            compatible = "foo,testtest";
            reg = <0x0 0xa0190000 0x0 0x10000>;
        };

但现在我有点迷失在这里。 我想做的是能够使用设备中的寄存器0xa0190000,通过读写函数来读写一些值。 我发现一些 API 能够获取设备的资源,devm_ioremap_resource,但是之后我就迷失了。 我如何能够根据资源指针写入/读取寄存器?

或者这是错误的做法?

linux-device-driver
1个回答
0
投票

正如 0andriy 评论的那样,使用 readl 和 writel 读写寄存器效果很好:

u32 reg;
reg = readl(base_addr);
pr_notice("Reg read: %d\n", reg);
writel(0xff,base_addr);
reg = readl(base_addr);
pr_notice("Reg read: %d\n", reg);
© www.soinside.com 2019 - 2024. All rights reserved.