[置顶] Linux 设备编程
设备挂载到bus总线上
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
void usb_dev_release(struct device *dev);
struct bus_type my_usb_bus = {
.name = "my_usb", //总线的名字,注册成功后会在/sys/bus/目录下看到
};
struct device my_usb_device = {
.bus_id = "usb_device", // 设备的名字
.bus = &my_usb_bus, //这个设备会在my_usb_bus总线上挂载
.release = usb_dev_release,
};
#define COUNT_SIZE 100
char data[COUNT_SIZE] = "Hello MikeChen";
char data_device[COUNT_SIZE] = "Hello MikeChen this is my device";
void usb_dev_release(struct device *dev)
{
printk("<kernel>release\n");
}
/*
内核到用户空间的数据
*/
static ssize_t show_device_data(struct device* bus, struct device_attribute *attr, char *buf)
{
return snprintf(buf, COUNT_SIZE, "show Bus Data: %s\n", data_device);
}
/*
用户空间到内核的数据
*/
static ssize_t store_device_data(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
return snprintf(data_device, COUNT_SIZE, "Store Bus Data: %s\n", buf);
}
/*
内核到用户空间的数据
*/
static ssize_t show_bus_data(struct bus_type * bus, char *buf)
{
return snprintf(buf, COUNT_SIZE, "show Bus Data: %s\n", data);
}
/*
用户空间到内核的数据
*/
static ssize_t store_bus_data(struct bus_type * bus, const char *buf, size_t count)
{
return snprintf(data, COUNT_SIZE, "Store Bus Data: %s\n", buf);
}
/*
注意该宏最终返回bus_attr_version
#define BUS_ATTR(_name, _mode, _show, _store) \
struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store)
*/
static BUS_ATTR(version, S_IRUGO | S_IWUGO, show_bus_data, store_bus_data);
static DEVICE_ATTR(verison_device, S_IRUGO | S_IWUGO, show_device_data, store_device_data);
static int __init my_usb_bus_init(void)
{
int ret;
ret = bus_register(&my_usb_bus);
if (ret)
{
printk("Bus register failed!, ret: %d\n", ret);
return ret;
}
printk("Usb init commplete\n");
ret = bus_create_file(&my_usb_bus, &bus_attr_version);
if (ret)
{
printk("Bus Create file failed");
bus_unregister(&my_usb_bus);
return 0;
}
printk("Bus ATTR Create Commplete\n");
ret = device_register(&my_usb_device);
if (ret)
{
printk("Device Register failed\n");
bus_remove_file(&my_usb_bus, &bus_attr_version)
bus_unregister(&my_usb_bus);
return 0;
}
printk("Device Register commplete\n");
ret = device_create_file(&my_usb_device, &dev_attr_verison_device);
if (ret)
{
printk("Device Create failed\n");
device_unregister(&my_usb_device);
bus_remove_file(&my_usb_bus, &bus_attr_version)
bus_unregister(&my_usb_bus);
return 0;
}
printk("Device Create commplete\n");
return 0;
}
static void __exit my_usb_bus_exit(void)
{
device_create_file(&my_usb_bus, &dev_attr_verison_device);
device_unregister(&my_usb_device);
bus_remove_file(&my_usb_bus, &bus_attr_version)
bus_unregister(&my_usb_bus);
printk("Usb Bus exit\n");
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("MIKE CHEN");
module_init(my_usb_bus_init);
module_exit(my_usb_bus_exit);