c_dev结构体
struct my_device_data {
char buffer[BUFFER_SIZE];
int size;
struct cdev cdev;
};
read函数
static ssize_t my_device_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
{
struct my_device_data *dev_data = file->private_data;
ssize_t bytes_read = 0;
if (*offset < dev_data->size) {
bytes_read = min(count, (size_t)(dev_data->size - *offset));
if (copy_to_user(buf, dev_data->buffer + *offset, bytes_read)) {
return -EFAULT;
}
*offset += bytes_read;
printk(KERN_INFO "Read %zd bytes from device\n", bytes_read);
}
return bytes_read;
}
write函数
static ssize_t my_device_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
{
struct my_device_data *dev_data = file->private_data;
ssize_t bytes_written = 0;
if (*offset < BUFFER_SIZE) {
bytes_written = min(count, (size_t)(BUFFER_SIZE - *offset));
if (copy_from_user(dev_data->buffer + *offset, buf, bytes_written)) {
return -EFAULT;
}
*offset += bytes_written;
dev_data->size = *offset;
printk(KERN_INFO "Write %zd bytes to device\n", bytes_written);
}
return bytes_written;
}
open函数
static int my_device_open(struct inode *inode, struct file *file)
{
struct my_device_data *dev_data;
dev_data = container_of(inode->i_cdev, struct my_device_data, cdev);
printk(KERN_INFO "Device %s opened\n", DEVICE_NAME);
file->private_data = dev_data;
return 0;
}
release函数
static int my_device_release(struct inode *inode, struct file *file)
{
printk(KERN_INFO "Device %s released\n", DEVICE_NAME);
return 0;
}
init函数
static int __init my_device_init(void)
{
int result;
my_device = kmalloc(sizeof(struct my_device_data), GFP_KERNEL);
if (!my_device) {
return -ENOMEM;
}
memset(my_device, 0, sizeof(struct my_device_data));
my_device->size = 0;
device_numbers = MKDEV(0, 0);
result = alloc_chrdev_region(&device_numbers, 0, 1, DEVICE_NAME);
if (result < 0) {
kfree(my_device);
return result;
}
cdev_init(&my_device->cdev, &my_device_fops);
my_device->cdev.owner = THIS_MODULE;
result = cdev_add(&my_device->cdev, device_numbers, 1);
if (result < 0) {
unregister_chrdev_region(device_numbers, 1);
kfree(my_device);
return result;
}
my_device_class = class_create(THIS_MODULE, DEVICE_NAME);
if (IS_ERR(my_device_class)) {
cdev_del(&my_device->cdev);
unregister_chrdev_region(device_numbers, 1);
kfree(my_device);
return PTR_ERR(my_device_class);
}
device_create(my_device_class, NULL, device_numbers, NULL, DEVICE_NAME);
return 0;
}
exit函数
static void __exit my_device_exit(void)
{
cdev_del(&my_device->cdev);
unregister_chrdev_region(device_numbers, 1);
device_destroy(my_device_class, device_numbers);
class_destroy(my_device_class);
kfree(my_device);
}