spi驱动框架

本文详细剖析了Linux中SPI驱动的框架,介绍了主机、设备分离的设计思想,以及SPI驱动如何基于字符设备驱动实现。讲解了从设备号注册、主机驱动与设备驱动的交互,到SPI总线注册、设备匹配及probe函数的过程,揭示了SPI驱动从注册到实际设备文件创建的完整流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在linux中,spi框架是通过主机、设备分离的思想设计的,主机、设备分离的思想就是主机驱动跟设备驱动分开实现,但是它们之间又相互联系,毕竟上层应用是通过主机控制器间接来控制具体设备,这就涉及到了两个关系,上层应用访问跟主机控制器、主机控制器跟具体设备之间的关系,清楚linux如何处理它们之间的关系,是了解这个框架的关键。在内核中对上层访问spi设备抽象出了通用的部分,这部分在spidev.c文件中实现,这个文件里面有个初始化函数:

static int __init spidev_init(void)
{
    int status;
    BUILD_BUG_ON(N_SPI_MINORS > 256);
    status = register_chrdev(SPIDEV_MAJOR, "spi", &spidev_fops);//注册一个字符设备,并把SPIDEV_MAJOR主设备号跟spidev_fops进行绑定
    if (status < 0)
        return status;
    spidev_class = class_create(THIS_MODULE, "spidev");//创建一个类
    if (IS_ERR(spidev_class)) {
        unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
        return PTR_ERR(spidev_class);
    }
    status = spi_register_driver(&spidev_spi_driver);//注册一个spi_driver
    if (status < 0) {
        class_destroy(spidev_class);
        unregister_chrdev(SPIDEV_MAJOR, spidev_spi_driver.driver.name);
    }
    return status;
}

spi驱动是基于字符设备驱动实现的,在学习字符设备驱动的时候知道,编写一个完整的字符设备的四部曲:
1、注册一个设备号(可用接口alloc_chrdev_region,register_chrdev_region)
2、主设备号跟文件操作函数集的绑定(cdev_add) 注:以上两步可用register_chrdev代替(次设备号固定)
3、创建一个struct class结构(class_create)
4、创建设备驱动文件(device_create)
由上代码可知这里完成了编写一个字符设备驱动的前三步,还需要创建一个设备文件供上层访问,这里只是进行初始化,显然也是没有必要去生成设备文件,因此这里可以引出一个疑问?(设备文件会在哪里生成)。最后是调用spi_register_driver注册一个spi_driver,这里需要先说明一下,spi是通过总线的方式注册进系统的(在spi.c文件中实现),这里先来看下spi_register_driver的实现:

int spi_register_driver(struct spi_driver *sdrv)
{
    sdrv->driver.bus = &spi_bus_type;
    if (sdrv->probe)
        sdrv->driver.probe = spi_drv_probe;
    if (sdrv->remove)
        sdrv->driver.remove = spi_drv_remove;
    if (sdrv->shutdown)
        sdrv->driver.shutdown = spi_drv_shutdown;
    return driver_register(&sdrv->driver);
}

这里初始化driver结构的总线类型,然后是调用driver_register注册一个driver,到这里可以回到总线驱动模型的知识,driver_register是所有总线注册一个driver进总线中的统一接口,在学习总线模型的时候知道,在调用driver_register注册一个driver会去遍历总线下的device,并调用总线提供的总线提供的match函数进行匹配,对应的spi总线,它的match函数为:

static int spi_match_device(struct device *dev, struct device_driver *drv)
{
    const struct spi_device *spi = to_spi_device(dev);
    const struct spi_driver *sdrv = to_spi_driver(drv);

    /* Attempt an OF style match */
    if (of_driver_match_device(dev, drv))//driver的of_match_table跟device的of_node成员进行比较,
        return 1;

  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值