驱动注册流程(简单)

注册一个驱动的步骤:
1、定义一个platform_driver结构
2、初始化这个结构,指定其probe、remove等函数,并初始化其中的driver变量
3、实现其probe、remove等函数

📋
1. platform_driver结构,定义于include/linux/platform_device.h文件中。
 
2. struct platform_driver {
    int (*probe)(struct platform_device *);
    int (*remove)(struct platform_device *);
    void (*shutdown)(struct platform_device *);
    int (*suspend)(struct platform_device *, pm_message_t state);
    int (*suspend_late)(struct platform_device *, pm_message_t state);
    int (*resume_early)(struct platform_device *);
    int (*resume)(struct platform_device *);
    struct device_driver driver;
};
 
3. 结构体device_driver位于include/linux/device.h文件中。
 
4. struct device_driver {
    const char        * name;
    struct bus_type        * bus;
    struct kobject        kobj;
    struct klist        klist_devices;
    struct klist_node    knode_bus;
    struct module        * owner;
    const char         * mod_name;  /* used for built-in modules */
    struct module_kobject    * mkobj;
    int    (*probe)    (struct device * dev);
    int    (*remove)    (struct device * dev);
    void    (*shutdown)    (struct device * dev);
    int    (*suspend)    (struct device * dev, pm_message_t state);
    int    (*resume)    (struct device * dev);
};
 
5.  需要注意这两个变量:name和owner。那么的作用主要是为了和相关的platform_device关联起来,owner的作用是说明模块的所有者,驱动程序中一般初始化为THIS_MODULE。
 
6. platform_driver的初始化实例:
static struct platform_driver s3c2410iis_driver = { 
  .probe = s3c2410iis_probe, 
  .remove = s3c2410iis_remove,
  .driver = {
    .name = "s3c2410-iis",
    .owner = THIS_MODULE,
  },
}; 
 
7. struct platform_device { //pdev是平台总线设备,对于整个驱动是可见的
    const char    * name;
    int        id;
    struct device    dev;
    u32        num_resources;
    struct resource    * resource;
};
 
8. 具体的实例: 
struct platform_device s3c_device_iis = {
    .name         = "s3c2410-iis",
    .id         = -1,
    .num_resources     = ARRAY_SIZE(s3c_iis_resource),
    .resource     = s3c_iis_resource,
    .dev = {
        .dma_mask = &s3c_device_iis_dmamask,
        .coherent_dma_mask = 0xffffffffUL
    }
};
 
9. 它的name变量和刚才上面的platform_driver的name变量是一致的,内核正是通过这个一致性来为驱动程序找到资源,即platform_device中的resource。
 
10. resource位于include/linux/ioport.h文件中
 
11. struct resource {
    resource_size_t start;
    resource_size_t end;
    const char *name;
    unsigned long flags;
    struct resource *parent, *sibling, *child;
};
    下面是一个具体的实例:
static struct resource s3c_iis_resource[] = {
    [0] = {
        .start = S3C24XX_PA_IIS,
        .end = S3C24XX_PA_IIS + S3C24XX_SZ_IIS -1,
        .flags = IORESOURCE_MEM,
    }
};
 
11. 这个结构的作用就是告诉驱动程序设备的起始地址和终止地址和设备的端口类型。这里的地址指的是物理地址。
 
12. struct device {
    struct klist        klist_children;
    struct klist_node    knode_parent;        /* node in sibling list */
    struct klist_node    knode_driver;
    struct klist_node    knode_bus;
    struct device        *parent;
    struct kobject kobj;
    char    bus_id[BUS_ID_SIZE];    /* position on parent bus */
    ......
    struct list_head    node;
    struct class        *class;
    dev_t            devt;        /* dev_t, creates the sysfs "dev" */
    struct attribute_group    **groups;    /* optional groups */
    void    (*release)(struct device * dev);
};
 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
CCI (Camera Control Interface) 是用于处理相机设备的接口,下面是一个简单的 CCI 设备驱动注册和使用的流程: 1. 注册CCI设备驱动 在Linux系统中,CCI设备驱动通常是通过Platform Device进行注册的。在设备树中定义好CCI设备节点的属性和寄存器信息后,设备驱动通过调用函数platform_driver_register()来进行注册。 2. 初始化CCI设备 在CCI设备驱动注册成功后,需要进行初始化。初始化包括读取设备树配置信息、初始化寄存器等操作。 3. 使用CCI设备 初始化完成后,CCI设备可以进行功能操作。比如,设置相机的曝光时间、增益等参数。 4. 取消CCI设备注册 如果不再需要使用CCI设备,可以通过调用函数platform_driver_unregister()来取消CCI设备驱动注册。 下面是一段示例代码,演示了CCI设备驱动注册和使用的流程: ```c #include <linux/platform_device.h> // 定义CCI设备节点的属性和寄存器信息 static const struct of_device_id cci_of_match[] = { { .compatible = "cci", .data = &cci_device_info, }, { } }; // 定义CCI设备驱动结构体 static struct platform_driver cci_driver = { .probe = cci_probe, .remove = cci_remove, .driver = { .name = "cci", .of_match_table = cci_of_match, .owner = THIS_MODULE, }, }; // CCI设备驱动注册函数 static int __init cci_init(void) { int ret; // 注册CCI设备驱动 ret = platform_driver_register(&cci_driver); if (ret < 0) { printk(KERN_ERR "CCI: Failed to register platform driver\n"); return ret; } printk(KERN_INFO "CCI: Platform driver registered\n"); return 0; } // CCI设备驱动注销函数 static void __exit cci_exit(void) { // 取消CCI设备驱动注册 platform_driver_unregister(&cci_driver); printk(KERN_INFO "CCI: Platform driver unregistered\n"); } module_init(cci_init); module_exit(cci_exit); ``` 在CCI设备驱动注册成功后,可以在probe函数中进行设备的初始化、配置和使用操作: ```c static int cci_probe(struct platform_device *pdev) { int ret; // 读取设备树配置信息 struct device_node *node = pdev->dev.of_node; if (!node) { printk(KERN_ERR "CCI: Failed to get device node\n"); return -ENODEV; } // 初始化CCI设备 ret = cci_init(pdev); if (ret < 0) { printk(KERN_ERR "CCI: Failed to initialize device\n"); return ret; } // 使用CCI设备 cci_set_exposure_time(1000); cci_set_gain(20); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式空白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值