创建字符设备的三种方法 (转载)
来源:互联网 发布:中国银行网上银行软件 编辑:程序博客网 时间:2024/05/29 11:20
(2008-12-13 12:55)
分类: Linux DeviceDrivers
将创建字符设备的三种方法记录一下,以便以后参考.
1.使用早期的register_chardev()方法
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<asm/uaccess.h>
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<asm/uaccess.h>
intinit_module(void);
void cleanup_module(void);
static int device_open(struct inode*, struct file*);
static int device_release(struct inode*, struct file*);
static ssize_t device_read(struct file*, char *, size_t,loff_t*);
static ssize_t device_write(struct file*, const char*, size_t,loff_t*);
void cleanup_module(void);
static int device_open(struct inode*, struct file*);
static int device_release(struct inode*, struct file*);
static ssize_t device_read(struct file*, char *, size_t,loff_t*);
static ssize_t device_write(struct file*, const char*, size_t,loff_t*);
#define SUCCESS 0
#define DEVICE_NAME "chardev"
#define BUF_LEN 80
#define DEVICE_NAME "chardev"
#define BUF_LEN 80
static int major;
static int Device_open = 0;
static char msg[BUF_LEN];
static char *msg_ptr;
static int Device_open = 0;
static char msg[BUF_LEN];
static char *msg_ptr;
static structfile_operations fops =
{
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release,
};
{
};
intinit_module(void)
{
major = register_chrdev(0, DEVICE_NAME,&fops);
if (major < 0)
{
printk(KERN_ALERT "Registering char device failed with %d\n",major);
return major;
}
printk(KERN_INFO "I was assigned major number %d.\n", major);
return SUCCESS;
}
{
}
voidcleanup_module(void)
{
int ret = unregister_chrdev(major, DEVICE_NAME);
if (ret < 0)
{
printk(KERN_ALERT "Error in unregister chrdev %d\n", major);
}
}
{
}
static intdevice_open(struct inode* inode, struct file* file)
{
static int counter = 0;
if (Device_open)
{
return -EBUSY;
}
Device_open++;
sprintf(msg, "I already told you %d times helloworld\nDevice_open=%d\n" , counter++, Device_open);
msg_ptr = msg;
try_module_get(THIS_MODULE);
return SUCCESS;
}
{
}
static intdevice_release(struct inode* inode, struct file* file)
{
Device_open--;
module_put(THIS_MODULE);
return 0;
}
{
}
static ssize_tdevice_read(struct file* filp, char *buffer, size_t length, loff_t*offset)
{
int bytes_read = 0;
if (*msg_ptr == '\0')
return 0;
printk(KERN_ALERT "length=%d\n", length);
while (length && *msg_ptr)
{
put_user(*(msg_ptr++), buffer++);
length--;
bytes_read++;
}
return bytes_read;
}
{
}
static ssize_tdevice_write(struct file* filp, const char *buff, size_t len,loff_t *off)
{
printk(KERN_ALERT "Sorry, this operation isn't supported\n");
return -EINVAL;
}
{
}
2.使用cdev的方法
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/types.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<asm/uaccess.h>
intinit_module(void);
void cleanup_module(void);
static int device_open(struct inode*, struct file*);
static int device_release(struct inode*, struct file*);
static ssize_t device_read(struct file*, char *, size_t,loff_t*);
static ssize_t device_write(struct file*, const char*, size_t,loff_t*);
void cleanup_module(void);
static int device_open(struct inode*, struct file*);
static int device_release(struct inode*, struct file*);
static ssize_t device_read(struct file*, char *, size_t,loff_t*);
static ssize_t device_write(struct file*, const char*, size_t,loff_t*);
#define SUCCESS 0
#define DEVICE_NAME "chardev"
#define BUF_LEN 80
#define DEVICE_NAME "chardev"
#define BUF_LEN 80
static int major;
static int Device_open = 0;
static char msg[BUF_LEN];
static char *msg_ptr;
static struct cdev *my_cdev;
static structfile_operations fops =
{
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release,
};
{
};
intinit_module(void)
{
int err;
dev_t devid ;
alloc_chrdev_region(&devid, 0, 1, "chardev");
major = MAJOR(devid);
my_cdev = cdev_alloc();
cdev_init(my_cdev, &fops);
err = cdev_add(my_cdev, devid, 1);
if (err)
{
printk(KERN_INFO "I was assigned major number %d.\n", major);
return -1;
}
printk("major number is %d\n", MAJOR(devid));
return SUCCESS;
}
{
}
voidcleanup_module(void)
{
cdev_del(my_cdev);
printk("cleanup done\n");
}
{
}
static intdevice_open(struct inode* inode, struct file* file)
{
static int counter = 0;
if (Device_open)
{
return -EBUSY;
}
Device_open++;
sprintf(msg, "I already told you %d times helloworld\nDevice_open=%d\n", counter++, Device_open);
msg_ptr = msg;
try_module_get(THIS_MODULE);
return SUCCESS;
}
{
}
static intdevice_release(struct inode* inode, struct file* file)
{
Device_open--;
module_put(THIS_MODULE);
return 0;
}
{
}
static ssize_tdevice_read(struct file* filp, char *buffer, size_t length, loff_t*offset)
{
int bytes_read = 0;
if (*msg_ptr == '\0')
return 0;
printk(KERN_ALERT "length=%d\n", length);
while (length && *msg_ptr)
{
put_user(*(msg_ptr++), buffer++);
length--;
bytes_read++;
}
return bytes_read;
}
{
}
static ssize_tdevice_write(struct file* filp, const char *buff, size_t len,loff_t *off)
{
printk(KERN_ALERT "Sorry, this operation isn't supported\n");
return -EINVAL;
}
{
}
3.使用udev在/dev/下动态生成设备文件的方式
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/types.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<linux/pci.h>
#include<linux/moduleparam.h>
#include<linux/init.h>
#include<linux/string.h>
#include<asm/uaccess.h>
#include<asm/unistd.h>
#include<asm/uaccess.h>
#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/types.h>
#include<linux/fs.h>
#include<linux/cdev.h>
#include<linux/pci.h>
#include<linux/moduleparam.h>
#include<linux/init.h>
#include<linux/string.h>
#include<asm/uaccess.h>
#include<asm/unistd.h>
#include<asm/uaccess.h>
MODULE_LICENSE("GPL");
intinit_module(void);
void cleanup_module(void);
static int device_open(struct inode*, struct file*);
static int device_release(struct inode*, struct file*);
static ssize_t device_read(struct file*, char *, size_t,loff_t*);
static ssize_t device_write(struct file*, const char*, size_t,loff_t*);
void cleanup_module(void);
static int device_open(struct inode*, struct file*);
static int device_release(struct inode*, struct file*);
static ssize_t device_read(struct file*, char *, size_t,loff_t*);
static ssize_t device_write(struct file*, const char*, size_t,loff_t*);
#define SUCCESS 0
#define DEVICE_NAME "chardev"
#define BUF_LEN 80
#define DEVICE_NAME "chardev"
#define BUF_LEN 80
static int major;
static int Device_open = 0;
static char msg[BUF_LEN];
static char *msg_ptr;
static struct cdev *my_cdev;
static struct class *my_class;
dev_t devid ;
static structfile_operations fops =
{
.read = device_read,
.write = device_write,
.open = device_open,
.release = device_release,
};
{
};
intinit_module(void)
{
int err;
alloc_chrdev_region(&devid, 0, 1, "chardev");
major = MAJOR(devid);
my_cdev = cdev_alloc();
cdev_init(my_cdev, &fops);
my_cdev->owner = THIS_MODULE;
err = cdev_add(my_cdev, devid, 1);
if (err)
{
printk(KERN_INFO "I was assigned major number %d.\n", major);
return -1;
}
my_class = class_create(THIS_MODULE, "chardev_class1");
if (IS_ERR(my_class))
{
printk(KERN_INFO "create class error\n");
return -1;
}
class_device_create(my_class, NULL, devid, NULL, "chardev" "%d",MINOR(devid));
printk("major number is %d\n", MAJOR(devid));
return SUCCESS;
}
{
}
voidcleanup_module(void)
{
cdev_del(my_cdev);
class_device_destroy(my_class, devid);
class_destroy(my_class);
printk("cleanup done\n");
}
{
}
static intdevice_open(struct inode* inode, struct file* file)
{
static int counter = 0;
if (Device_open)
{
return -EBUSY;
}
Device_open++;
sprintf(msg, "I already told you %d times helloworld\nDevice_open=%d\n", counter++, Device_open);
msg_ptr = msg;
try_module_get(THIS_MODULE);
return SUCCESS;
}
{
}
static intdevice_release(struct inode* inode, struct file* file)
{
Device_open--;
module_put(THIS_MODULE);
return 0;
}
{
}
static ssize_tdevice_read(struct file* filp, char *buffer, size_t length, loff_t*offset)
{
int bytes_read = 0;
if (*msg_ptr == '\0')
return 0;
printk(KERN_ALERT "length=%d\n", length);
while (length && *msg_ptr)
{
put_user(*(msg_ptr++), buffer++);
length--;
bytes_read++;
}
return bytes_read;
}
{
}
static ssize_tdevice_write(struct file* filp, const char *buff, size_t len,loff_t *off)
{
printk(KERN_ALERT "Sorry, this operation isn't supported\n");
return -EINVAL;
}
注:
在linux- 2.6.22以后的内核中,class_device_create()和class_device_destroy()内核函数变更为device_create()和device_destroy()(此段内容为本站添加)。
{
}
注:
0 0
- 创建字符设备的三种方法 (转载)
- 创建字符设备的三种方法 (转载)
- 创建字符设备的三种方法
- 创建字符设备的三种方法
- 创建字符设备的三种方法
- linux下字符设备驱动的三种创建方式
- C++/MFC创建多线程的三种方法(转载)
- JavaScript 三种创建对象的方法
- 字符设备驱动学习(二) 设备接点的创建
- 字符设备文件的创建
- 使用ioctl方法创建字符设备驱动
- 字符设备驱动(三)
- linux字符设备(三)
- 字符设备驱动(三)
- 转载(一)代码注入的三种方法
- Android完全退出应用程序的三种方法(转载)
- structs2 接受参数的三种方法(转载)
- 转载-Javascript定义类(class)的三种方法
- C代码优化方案 (转载上)
- C代码优化方案 (转载上)
- C代码优化方案 (转载下)
- C代码优化方案 (转载下)
- 创建字符设备的三种方法 (转载)
- 创建字符设备的三种方法 (转载)
- 内核通知链学习笔记(转载)
- 内核通知链学习笔记(转载)
- IOS之同步请求、异步请求、GET请求、POST请求
- 嵌入式linux启动信息完全注释(上…
- 嵌入式linux启动信息完全注释(上…
- 嵌入式linux启动信息完全注释(下…
- 嵌入式linux启动信息完全注释(下…
- Linux下ARM汇编教程