用c语言写一个字符设备
时间: 2023-11-23 10:06:53 浏览: 178
好的,以下是一个简单的字符设备驱动程序的C语言代码:
```c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#define DEVICE_NAME "my_chardev"
#define BUF_LEN 1024
static char msg[BUF_LEN];
static int msg_len = 0;
static dev_t dev;
static struct cdev c_dev;
static struct class *cl;
static int my_open(struct inode *i, struct file *f)
{
printk(KERN_INFO "my_chardev: open()\n");
return 0;
}
static int my_close(struct inode *i, struct file *f)
{
printk(KERN_INFO "my_chardev: close()\n");
return 0;
}
static ssize_t my_read(struct file *f, char __user *buf, size_t len, loff_t *off)
{
int bytes_read = 0;
if (*off >= msg_len)
return 0;
if (*off + len > msg_len)
len = msg_len - *off;
bytes_read = copy_to_user(buf, msg + *off, len);
*off += len - bytes_read;
return len - bytes_read;
}
static ssize_t my_write(struct file *f, const char __user *buf, size_t len, loff_t *off)
{
int bytes_written = 0;
if (*off + len > BUF_LEN)
return -ENOSPC;
bytes_written = copy_from_user(msg + *off, buf, len);
*off += len - bytes_written;
msg_len = *off;
return len - bytes_written;
}
static struct file_operations my_fops = {
.owner = THIS_MODULE,
.open = my_open,
.release = my_close,
.read = my_read,
.write = my_write
};
static int __init my_chardev_init(void)
{
int ret = 0;
printk(KERN_INFO "my_chardev: init()\n");
if ((ret = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME)) < 0) {
return ret;
}
cdev_init(&c_dev, &my_fops);
if ((ret = cdev_add(&c_dev, dev, 1)) < 0) {
unregister_chrdev_region(dev, 1);
return ret;
}
if (IS_ERR(cl = class_create(THIS_MODULE, DEVICE_NAME))) {
cdev_del(&c_dev);
unregister_chrdev_region(dev, 1);
return PTR_ERR(cl);
}
if (IS_ERR(device_create(cl, NULL, dev, NULL, DEVICE_NAME))) {
class_destroy(cl);
cdev_del(&c_dev);
unregister_chrdev_region(dev, 1);
return PTR_ERR(cl);
}
return 0;
}
static void __exit my_chardev_exit(void)
{
printk(KERN_INFO "my_chardev: exit()\n");
device_destroy(cl, dev);
class_destroy(cl);
cdev_del(&c_dev);
unregister_chrdev_region(dev, 1);
}
module_init(my_chardev_init);
module_exit(my_chardev_exit);
MODULE_LICENSE("GPL");
```
这个驱动程序创建了一个名为“my_chardev”的字符设备,它可以在用户空间中读取和写入数据。当用户打开设备文件时,驱动程序会在内核日志中输出“my_chardev: open()”信息;当用户关闭设备文件时,驱动程序会在内核日志中输出“my_chardev: close()”信息。
当用户读取设备文件时,驱动程序会将缓冲区中的数据复制到用户空间中,并返回实际读取的字节数。当用户写入设备文件时,驱动程序会将数据从用户空间复制到缓冲区中,并返回实际写入的字节数。
该驱动程序还使用了cdev结构体和class结构体来管理设备文件和设备节点。在模块初始化期间,它会申请一个设备号并将设备文件和设备节点添加到内核中。在模块退出期间,它会将设备文件和设备节点从内核中删除,并释放设备号。
阅读全文