Linux驱动学习之点灯(六,利用平台设备总线)

平台设备总线

平台设备总线是内核虚拟的一条总线,早期没有设备树时,通过名字匹配设备信息,如今有设备树通过设备树里的complitable属性匹配,下图是平台设备总线的结构体描述。

much函数是完成信息匹配的,

总线就是使用 match函数来根据注册的设备来查找对应的驱动,或者根据注册的驱动来查找相应的设备,因此每一条总线都必须实现此函数。 match函数有两个参数: dev和 drv,这两个参数分别为 device和 device_driver类型,也就是设备和驱动。
platform总线是bus_type的一个具体实例。

既然match是完成信息匹配的我们来重点关注这个函数

不难发现,先通过of方法匹配设备树里的 节点(通过compatible)不断往里跳

然后再匹配其他,最后通过name匹配。

下面是platform_driver结构体

这个我们是很熟悉的
probe函数,驱动和设备匹配成功以后会执行
driver成员,面向对象,device_driver为基类,platform_driver集成了这个基类并添加了一些特有的成员变量

of_match_table这个结构体我我们需要提供compatible 信息

由这个函数可以看出来(往里跳)

compatible非常重要,对于设备树而言,就是通过设备节点的compatiable属性值和of_match_table中每个项目的compatible成员变量进行比较,如果有相等的就表示设备和此驱动匹配成功

代码实现

定义一个平台驱动,实现probe和remove函数,分别在加载和卸载的时候会自动执行,

然后在driver里定义名子(一定要写,不然加载驱动会加载不上如下图),最后写出匹配表格

然后在 myprobe里实现 设备注册,在myremove里实现设备卸载

代码实列

#include "linux/device/class.h"
#include "linux/gpio.h"
#include "linux/of_gpio.h"
#include "linux/platform_device.h"
#include "linux/printk.h"
#include <linux/module.h>
#include "linux/device/driver.h"
#include "linux/cdev.h"
uint32_t pin1;
uint32_t pin2;
struct class *cls;
struct cdev *cdev;
static dev_t dev_num;
static int open (struct inode *i, struct file *f)
{
    gpio_set_value(pin1,0);
    gpio_set_value(pin2,0);
    return 0;
}
static int close (struct inode *i, struct file *f)
{
    gpio_set_value(pin1,1);
    gpio_set_value(pin2,1);
    return 0;
}
struct file_operations fops={
    .owner=THIS_MODULE,
    .open=open,
    .release=close,
};
int myprobe(struct platform_device *a)
{
  
   pin1=of_get_named_gpio(a->dev.of_node,"led_pin",0);
   pin2=of_get_named_gpio(a->dev.of_node,"led_pin",1);
   gpio_request(pin1,"led");
    gpio_request(pin2,"led");
    gpio_direction_output(pin1, 0);
    gpio_direction_output(pin2, 0);
      alloc_chrdev_region(&dev_num, 0, 1, "led");
    cdev= cdev_alloc();
    cdev->ops=&fops;
    cdev_add(cdev, dev_num,1);
   cls= class_create(THIS_MODULE, "led");
    device_create(cls,NULL,dev_num,NULL,"led");
    return 0;
}
int myremove (struct platform_device *dev){
     device_destroy(cls, dev_num);
    class_destroy(cls);
    unregister_chrdev_region(dev_num,1);
    gpio_free(pin1);
    gpio_free(pin2);
    printk(KERN_INFO "Goodbye, world!\n");
    return 0;
}
static struct of_device_id mymatch={
    .compatible="led",
};
struct platform_driver driver={
    .probe=myprobe,
    .remove=myremove,
    .driver={
        .name="led",
        .of_match_table=&mymatch,
    },

};
static int __init start(void)
{
    platform_driver_register(&driver);
    printk("hahaa\r\n");
    return 0;
}
static void __exit stop(void)
{
    platform_driver_unregister(&driver);
    printk("gun\r\n");
}
module_init(start);
module_exit(stop);
MODULE_LICENSE("GPL");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值