linux设备驱动之——总线模块驱动编写步骤
目录:
总线设备驱动模型
设备 总线 驱动 分离思想
文件系统sysfs
总线bus下面很多总线,包括要学习的平台设备:platform
设备一个链表(挂接设备)
驱动一个链表 (挂接驱动)
总线包含两个链的信息 (相当于中介,完成两者匹配)
实验1:完成mybus的构建
实验要求:在bus下构建mybus总线,mybus下构建设备和驱动
实验步骤
注意:保证名称一致
实验1代码:
/*Mbus.c*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/device.h>
#include <linux/interrupt.h>
//编码步骤
//1 定义总线
//2 总线的注册和注销
//匹配函数编写
int mybus_match(struct device * dev, struct device_driver * drv)
{
//成功返回1 失败返回0
if(!strncmp(drv->name, dev->kobj.name, strlen(drv->name)))
{
printk("match ok ! \n");
return 1;
}
else
{
printk("match error\n");
return 0;
}
return 0;
}
struct bus_type mybus = {
.name = "mybus",
.match = mybus_match , //匹配函数
};
EXPORT_SYMBOL(mybus); //其他文件要用到,将mybus导出去;
static int __init mybus_init(void)
{
int ret ;
printk("--------------%s----------\n",__FUNCTION__);
ret = bus_register(&mybus);
if(ret != 0)
{
printk("bus_register error!\n");
return ret;
}
return 0;
}
static void __exit mybus_exit(void)
{
printk("--------------%s----------\n",__FUNCTION__);
bus_unregister(&mybus);
}
module_init(mybus_init);
module_exit(mybus_exit);
MODULE_LICENSE("GPL");
/*mydrv.c*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/device.h>
#include <linux/interrupt.h>
extern struct bus_type mybus; //mybus.c里的变量
int mydrv_probe(struct device * dev)
{
printk("--------------%s----------\n",__FUNCTION__);
return 0;
}
int mydrv_remove(struct device * dev)
{
printk("--------------%s----------\n",__FUNCTION__);
return 0;
}
//构建一个driver对象
struct device_driver mydrv = {
.name = "mydev_drv", //名称和device里面的抱持一致
.bus = &mybus ,
.probe = mydrv_probe , //匹配成功调用
.remove = mydrv_remove ,
};
static int __init mydrv_init(void)
{
int ret;
printk("--------------%s----------\n",__FUNCTION__);
ret = driver_register(&mydrv);
if(ret < 0)
{
printk("driver register error!\n");
return ret;
}
return 0;
}
static void __exit mydrv_exit(void)
{
printk("--------------%s----------\n",__FUNCTION__);
driver_unregister(&mydrv);
}
module_init(mydrv_init);
module_exit(mydrv_exit);
MODULE_LICENSE("GPL");
/*mydev.c*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/device.h>
#include <linux/interrupt.h>
extern struct bus_type mybus; //mybus.c里的变量
//构建一个device对象
struct device mydev = {
.bus_id = "mydev_drv" , //名称和driver里面的保持一致
.bus = &mybus ,
};
static int __init mydev_init(void)
{
int ret;
printk("--------------%s----------\n",__FUNCTION__);
ret = device_register(&mydev);
if(ret < 0)
{
printk("device register error!\n");
return ret;
}
return 0;
}
static void __exit mydev_exit(void)
{
printk("--------------%s----------\n",__FUNCTION__);
device_unregister(&mydev);
}
module_init(mydev_init);
module_exit(mydev_exit);
MODULE_LICENSE("GPL");
实验运行结果:
驱动实验总结:
其实编写总线驱动简单分以下几步:
1、构建bus总线 mybus.c
2、构建driver对象 mydrv.c
3、构建device对象 mydev.c
4、完成匹配: mybus_match