请给出一个使用register_chrdev注册字符设备的例子
时间: 2024-02-12 10:08:02 浏览: 30
好的,下面是一个使用`register_chrdev`函数注册字符设备的例子:
```c
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
// 定义设备号
static dev_t devno;
// 定义字符设备结构体
static struct cdev cdev;
// 打开设备
static int example_open(struct inode *inode, struct file *filp)
{
printk(KERN_INFO "example device opened\n");
return 0;
}
// 释放设备
static int example_release(struct inode *inode, struct file *filp)
{
printk(KERN_INFO "example device released\n");
return 0;
}
// 读取设备
static ssize_t example_read(struct file *filp, char __user *buf, size_t len, loff_t *off)
{
char *kbuf = "Hello, world!\n";
int ret;
if (*off >= strlen(kbuf)) {
return 0;
}
ret = copy_to_user(buf, kbuf + *off, strlen(kbuf) - *off);
if (ret != 0) {
printk(KERN_ERR "copy_to_user failed\n");
return -EFAULT;
}
*off += len;
return len;
}
// 写入设备
static ssize_t example_write(struct file *filp, const char __user *buf, size_t len, loff_t *off)
{
char kbuf[1024];
int ret;
if (len >= sizeof(kbuf)) {
printk(KERN_ERR "buffer too small\n");
return -EINVAL;
}
ret = copy_from_user(kbuf, buf, len);
if (ret != 0) {
printk(KERN_ERR "copy_from_user failed\n");
return -EFAULT;
}
kbuf[len] = '\0';
printk(KERN_INFO "received data: %s\n", kbuf);
return len;
}
// 注册设备操作函数
static const struct file_operations example_fops = {
.owner = THIS_MODULE,
.open = example_open,
.release = example_release,
.read = example_read,
.write = example_write,
};
// 模块加载函数
static int __init example_init(void)
{
int ret;
// 分配设备号
ret = alloc_chrdev_region(&devno, 0, 1, "example");
if (ret < 0) {
printk(KERN_ERR "alloc_chrdev_region failed\n");
return ret;
}
// 初始化字符设备
cdev_init(&cdev, &example_fops);
cdev.owner = THIS_MODULE;
// 注册字符设备
ret = cdev_add(&cdev, devno, 1);
if (ret < 0) {
printk(KERN_ERR "cdev_add failed\n");
unregister_chrdev_region(devno, 1);
return ret;
}
printk(KERN_INFO "example module loaded\n");
return 0;
}
// 模块卸载函数
static void __exit example_exit(void)
{
// 注销字符设备
cdev_del(&cdev);
// 释放设备号
unregister_chrdev_region(devno, 1);
printk(KERN_INFO "example module unloaded\n");
}
module_init(example_init);
module_exit(example_exit);
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Example character device driver");
MODULE_LICENSE("GPL");
```
这个例子实现了一个简单的字符设备,支持读和写操作。在模块加载时,它会使用`alloc_chrdev_region`函数分配一个设备号,并将设备操作函数和设备号注册到内核中。在模块卸载时,它会将设备从内核中注销,并释放设备号。
相关推荐
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)