bus.c
如下:
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
MODULE_AUTHOR ( "David" );
MODULE_LICENSE ( "Dual BSD/GPL" );
static char *Version = "$Revision: 1.9 $";
static int my_match ( struct device *dev, struct device_driver *driver ) {
// return !strncmp ( dev->bus_id, driver->name, strlen ( driver->name ) );
return !strncmp ( dev_name ( dev ), driver->name, strlen ( driver->name ) );
}
static void my_bus_release ( struct device *dev ) {
printk ( KERN_DEBUG "my bus release\n" );
}
struct device my_bus = {
// .bus_id = "my_bus0",
.init_name = "my_bus0",
.release = my_bus_release
};
struct bus_type my_bus_type = {
.name = "my_bus",
.match = my_match,
};
EXPORT_SYMBOL ( my_bus );
EXPORT_SYMBOL ( my_bus_type );
/* Export a simple attribute */
static ssize_t show_bus_version ( struct bus_type *bus, char *buf ) {
return snprintf ( buf, PAGE_SIZE, "%s\n", Version );
}
static BUS_ATTR ( version, S_IRUGO, show_bus_version, NULL );
static int __init my_bus_init ( void ) {
int ret;
ret = bus_register ( &my_bus_type ); /* 注册总线 */
if ( ret ) {
return ret;
}
if ( bus_create_file ( &my_bus_type, &bus_attr_version ) ) { /* 创建属性文件 */
printk ( KERN_NOTICE "Fail to create version attribute!\n" );
}
ret = device_register ( &my_bus ); /* 注册总线设备 */
if ( ret ) {
printk ( KERN_NOTICE "Fail to register device:my_bus!\n" );
}
return ret;
}
static void my_bus_exit ( void ) {
device_unregister ( &my_bus );
bus_unregister ( &my_bus_type );
}
module_init ( my_bus_init );
module_exit ( my_bus_exit );
device.c
如下:
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
extern struct device my_bus;
extern struct bus_type my_bus_type;
static void my_dev_release ( struct device *dev ) {
}
struct device my_dev = {
.bus = &my_bus_type,
.parent = &my_bus,
.release = my_dev_release,
};
/* Export a simple attribute */
static ssize_t mydev_show ( struct device *dev, char *buf ) {
return sprintf ( buf, "%s\n", "This is my device!" );
}
static DEVICE_ATTR ( dev, S_IRUGO, mydev_show, NULL );
static int __init my_device_init ( void ) {
int ret = 0;
// strncpy ( my_dev.bus_id, "my_dev", BUS_ID_SIZE ); /* 初始化设备 */
dev_set_name ( &my_dev, "my_dev" );
device_register ( &my_dev ); /* 注册设备 */
device_create_file ( &my_dev, &dev_attr_dev ); /* 创建属性文件 */
return ret;
}
static void my_device_exit ( void ) {
device_unregister ( &my_dev );
}
module_init ( my_device_init );
module_exit ( my_device_exit );
MODULE_LICENSE ( "Dual BSD/GPL" );
首先生成bus.ko
模块,然后生成device.ko
,再安装到开发板中。然后使用命令ls -al /sys/bus/my_bus/devices/my_dev
(注意不是/my_dev/
),看是否出现/sys/bus/my_bus/devices/my_dev -> ../../../devices/my_bus0/my_dev
。安装完bus.ko
模块后,观察/sys/bus
目录下是否有my_bus
文件夹。
driver.c
如下:
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
extern struct bus_type my_bus_type;
static int my_probe ( struct device *dev ) {
printk ( "Driver found device which my driver can handle!\n" );
return 0;
}
static int my_remove ( struct device *dev ) {
printk ( "Driver found device unpluged!\n" );
return 0;
}
struct device_driver my_driver = {
.name = "my_dev",
.bus = &my_bus_type,
.probe = my_probe,
.remove = my_remove,
};
/* Export a simple attribute */
static ssize_t mydriver_show ( struct device_driver *driver, char *buf ) {
return sprintf ( buf, "%s\n", "This is my driver!" );
}
static DRIVER_ATTR ( drv, S_IRUGO, mydriver_show, NULL );
static int __init my_driver_init ( void ) {
int ret = 0;
driver_register ( &my_driver ); /* 注册驱动 */
driver_create_file ( &my_driver, &driver_attr_drv ); /* 创建属性文件 */
return ret;
}
static void my_driver_exit ( void ) {
driver_unregister ( &my_driver );
}
module_init ( my_driver_init );
module_exit ( my_driver_exit );
MODULE_LICENSE ( "Dual BSD/GPL" );
生成模块bus.ko
、device.ko
和driver.ko
,然后先加载bus.ko
,再加载device.ko
与driver.ko
,看终端是否出现字符串Driver found device which my driver can handle!
。