linux的设备模型

linux的设备模型

1 总线bus

1.1 代码

xbus.c

#include 
#include 
#include 




int xbus_match(struct device *dev,struct device_driver *drv)
{
    printk("%s-%s\n",__FILE__,__func__);
    if(!(strncmp(dev_name(dev),drv->name,strlen(drv->name))))
    {
        printk("dev & drv match\n");
        return 1;
    }

    return 0;

}




static struct bus_type xbus={
    .name="xbus",
    .match = xbus_match,

};

EXPORT_SYMBOL(xbus);



static char* bus_name = "xbus";

ssize_t xbus_test_show(struct bus_type *bus,char *buf)
{
    return sprintf(buf,"%s\n",bus_name);
}

BUS_ATTR(xbus_test,S_IRUSR,xbus_test_show,NULL);



static  __init int xbus_init(void)
{
    printk("xbus init sucess!\n");

    bus_register(&xbus);
    bus_create_file(&xbus,&bus_attr_xbus_test);
    
 
    return 0;
}




static __exit void xbus_exit(void)
{
    printk("xbus exit sucess!\n");

    bus_remove_file(&xbus,&bus_attr_xbus_test);
    bus_unregister(&xbus);

}


module_init(xbus_init);
module_exit(xbus_exit);
MODULE_LICENSE("GPL");

1.2 加载模块

加载内核模块,成功。

sudo insmod /mnt/xbus.ko

image-20221202095946228

此时会在/sys/bus/下面创建一个xbus的目录项。

linux的设备模型_第1张图片

1.3 总线的属性文件

xbus里的devices和drivers目录项现在是空的,xbus_test文件别创建的属性文件,当使用cat命令时,就会在内部执行回调函数。

sudo cat xbus_test

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MfMcvPDJ-1669966720949)(linux的设备模型.assets/image-20221202100506048-16699665808181.png)]

可以看下属性文件的信息,就是我们之前设置的。

image-20221202100614188

2 设备dev

2.1 代码

xdev.c

#include 
#include 
#include 




extern struct bus_type xbus;

void xdev_release(struct device *dev)
{
   printk("%s-%s\n",__FILE__,__func__);
}



struct device xdev={
    .init_name="xdev",
    .bus = &xbus,
    .release = xdev_release,

};


unsigned long id = 0; 

ssize_t xdev_id_show(struct device *dev,struct device_attribute *attr,char *buf)
{
    return sprintf(buf,"%d\n",id);
}

ssize_t xdev_id_store(struct device *dev,struct device_attribute *attr,const char *buf,size_t count)
{
   //将buf里的字符串转为10进制,存在id中
   kstrtoul(buf,10,&id);
   return count;
}


//定义名为xdev_id的文件,当使用cat命令时,调用,echo命令时调用
DEVICE_ATTR(xdev_id,S_IRUSR|S_IWUSR,xdev_id_show,xdev_id_store);




static  __init int xdev_init(void)
{
    printk("xdev init sucess!\n");

    device_register(&xdev);
    device_create_file(&xdev,&dev_attr_xdev_id);
    
 
    return 0;
}




static void __exit xdev_exit(void)
{
    printk("xdev exit sucess!\n");

    device_remove_file(&xdev,&dev_attr_xdev_id);
    device_unregister(&xdev);

}



module_init(xdev_init);
module_exit(xdev_exit);
MODULE_LICENSE("GPL");

2.2 加载模块

sudo insmod /mnt/xdev.ko

image-20221202104730647

加载设备模块成功后,会在/sys/bus/xbus/device/目录下创建一个链接文件

linux的设备模型_第2张图片

指向的是/sys/device/xdev目录项

linux的设备模型_第3张图片

2.3 设备的属性文件

进入/sys/devices/xdev目录,xdev_id就是创建的属性文件

image-20221202105421341

通过echo以及cat命令,可以进行修改和查询,如下所示:

image-20221202105738489

3 驱动drv

3.1 代码

drv.c

#include 
#include 

#include 

extern struct bus_type xbus;


//当驱动和设备匹配成功,执行此函数
int xdrv_probe(struct device *xdev)
{
   printk("%s-%s\n",__FILE__,__func__);
   return 0;
}

//当注销驱动时,会执行此函数
int xdrv_remove(struct device *xdev)
{
   printk("%s-%s\n",__FILE__,__func__);

   return 0;
}

struct device_driver xdrv={
    //要匹配的设备名字
    .name="xdev",
    //要挂载的总线
    .bus = &xbus,
    .probe = xdrv_probe,
    .remove = xdrv_remove

};


char *name = "xdrv"; 

ssize_t drvname_show(struct device_driver *drv,char *buf)
{
    return sprintf(buf,"%s\n",name);
}

//定义名为drvname的文件要和上面的drvname_show函数之前的一致
DRIVER_ATTR_RO(drvname);




static  __init int xdrv_init(void)
{
    printk("xdrv init sucess!\n");

    driver_register(&xdrv);
    driver_create_file(&xdrv,&driver_attr_drvname);
    
 
    return 0;
}




static void __exit xdrv_exit(void)
{
    printk("xdrv exit sucess!\n");

    driver_remove_file(&xdrv,&driver_attr_drvname);
    driver_unregister(&xdrv);

}



module_init(xdrv_init);
module_exit(xdrv_exit);
MODULE_LICENSE("GPL");

3.2 加载模块

sudo insmod /mnt/xdrv.ko

image-20221202132555865

加载设备模块成功后,会在/sys/bus/xbus/driver/目录下创建一个xdrv目录

linux的设备模型_第4张图片

3.3 驱动的属性文件

进入/sys/bus/xbus/drivers/xdev目录,drvname就是创建的属性文件。

通过使用cat命令会打打印出之前设置的信息。

image-20221202133318508

4 Makefile文件

KERNEL_DIR=../ebf_linux_kernel/build_image/build

ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
export  ARCH  CROSS_COMPILE

obj-m := xbus.o xdev.o xdrv.o 


all:
	$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules

.PHONY:clean

clean:
	$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean

5 模块卸载

当将xbus.ko模块首先加载,xdev.ko和xdrv.ko加载顺序不要求。查看当前模块如下图:

linux的设备模型_第5张图片

卸载模块,先卸载xdev.ko或xdrv.ko,xbus.ko的卸载要在设备和驱动模块卸载后再卸载。

linux的设备模型_第6张图片

你可能感兴趣的:(驱动开发,linux,c语言)