之前通过register_chrdev(0, “hello”, &hello_fops)注册字符驱动程序,一个主设备号下的所有设备(major,0)—(major,255)都对应hello_fops。
另一种字符设备驱动程序
实现函数:
//自动分配主设备号,只有(major,0)和(major,1)对应hello_fops
alloc_chrdev_region(&devid, 0, 2, “hello”);
major=MAJOR(devid);
dev_init(&hello_cdev,&hello_fops);
cdev_add(hello_cdev,devid,HELLO_CNT);
device_create(cls, NULL, MKDEV(major, 0), NULL, “hello0”); / /dev/hello0
device_create(cls, NULL, MKDEV(major, 1), NULL, “hello1”); /*/dev/hello1
程序源码
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <linux/poll.h>
#include <linux/cdev.h>
static struct class *cls;
static struct cdev hello_cdev;
static struct cdev hello2_cdev;
static int major;
#define HELLO_CNT 2//两个次设备号
/*构造hello_open*/
static ssize_t hello_open (struct inode * inode, struct file * file)
{
printk("hello_open");
return 0;
}
static struct file_operations hello_fops={
.owner = THIS_MODULE,
.open = hello_open,
};
/*构造hello2_open*/
static int hello2_open(struct inode *inode, struct file *file)
{
printk("hello2_open\n");
return 0;
}
static struct file_operations hello2_fops = {
.owner = THIS_MODULE,
.open = hello2_open,
};
static int hello_init(void)
{
dev_t devid;
/*(major,0)-(major,255)都对应hello_fops
major=register_chrdev(0, "hello", &hello_fops);
*/
if(major){//手动分配主设备号
devid=MKDEV(major,0);
/*从0开始2个;(major,0)-(major,1)对应hello_fops*/
register_chrdev_region(devid, HELLO_CNT, "hello");
}
else{//自动分配主设备号
/*(major,0)-(major,1)对应hello_fops*/
alloc_chrdev_region(&devid, 0, HELLO_CNT, "hello");
major=MAJOR(devid);
}
cdev_init(&hello_cdev,&hello_fops);
cdev_add(hello_cdev,devid,HELLO_CNT);
/*(major,2)对应hello2_fops*/
devid = MKDEV(major, 2);
register_chrdev_region(devid, 1, "hello2");
cdev_init(&hello2_cdev, &hello2_fops);
cdev_add(&hello2_cdev, devid, 1);
cls = class_create(THIS_MODULE, "hello");
device_create(cls, NULL, MKDEV(major, 0), NULL, "hello0"); /* /dev/hello0 */
device_create(cls, NULL, MKDEV(major, 1), NULL, "hello1"); /* /dev/hello1 */
device_create(cls, NULL, MKDEV(major, 2), NULL, "hello2"); /* /dev/hello2 */
device_create(cls, NULL, MKDEV(major, 3), NULL, "hello3"); /* /dev/hello3 打不开*/
return 0;
}
static void hello_exit(void)
{
device_destroy(cls, MKDEV(major, 0));
device_destroy(cls, MKDEV(major, 1));
device_destroy(cls, MKDEV(major, 2));
device_destroy(cls, MKDEV(major, 3));
class_destroy(cls);
cdev_del(&hello_cdev);
unregister_chrdev_region(MKDEV(major, 0), HELLO_CNT);
cdev_del(&hello2_cdev);
unregister_chrdev_region(MKDEV(major, 2), 1);
}
module_init(hello_init);//入口函数
module_exit(hello_exit);//出口函数
MODULE_LICENSE("GPL");