驱动的编写

A、PLATFORM驱动,虚拟总线的驱动。

1、写好设备树节点,中断,GPIO,别名等。

2、在驱动中新建 platform_driver结构体test_device_driver和of_device_id。注意:of_device_id必须多出一行空行。在platform_driver中写入probe和remove函数,以及和of_device_id绑定。

3、在INIT中调用register驱动的接口:platform_driver_register(&test_device_driver);,在该注册函数中,最总调用的会是结构体中的probe函数。

4、实现probe和remove函数。probe函数:probe(struct platform_device* pdev),

(1)、    match = of_match_device(siglentkb_dt_ids, &pdev->dev);匹配设备树中的别名节点。

(2)、   自定义一个结构体用以记录该驱动的全局变量。例如为test_dev。初始化test_dev = kmalloc(sizeof(struct siglentkb_dev_data), GFP_KERNEL);

(3)、调用of_iomap、platform_get_irq、devm_request_irq等函数从设备树中获取设备信息,并且注册中断处理函数。

(4)、建立create()函数用于创建设备号和class,device_class。a、file_operations siglentkb_fops 建立read,write..函数。b、调用register_chrdev函数动态获取设备号。c、调用class_create创建class记录在全部结构体test_dev中。d、调用device_create(test_dev->class, NULL, MKDEV(major, 0), NULL, "test");创建devcie下的设备。

(5)、实现中断处理函数。

 

B、I2C驱动。

1、写好设备树节点,注意硬件连线。将对于外设的描述记录在该节点上, 此处以GT911触摸屏为例。记录节点名:compatible = "goodix,gt9xx";设备地址:reg = <0x14>;复位及初始化管脚 <&gpio0 54 0x00>;

2、和上述PLATFORM类似,但是结构体不一样。此处需要建立i2c_driver结构体goodix_ts_driver和of_device_id。在i2c_driver中写入probe和remove函数,以及和of_device_id绑定。

3、在INIT函数中调用i2c_add_driver注册设备驱动。i2c_add_driver(&goodix_ts_driver);

4...步骤和platform注册类似。

 

注意:1、一般都会在probe中建立一个 wait_queue_head_t用以阻塞。一般调用函数  init_waitqueue_head(&inq);或者使用宏来初始化。使用wait_event_interruptible阻塞或者wake_up(&inq)函数调用。

2、一般都会建立一个自定义的驱动中的全局变量。用于数据共享使用。

3、不用总线驱动的注册函数不一样:I2C:i2c_add_driver。PLATFORM:platform_driver_register。不用函数中使用的结构体也不一致。platform_driver或者i2c_driver。但是内容结构是基本一致。

4、probe函数差别。

        I2C:static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id),可以直接用client来操作read,write...函数

        PLATFORM:static int test_probe(struct platform_device* pdev).
 

你可能感兴趣的:(linux)