一个字符驱动

实现一个基本框架

#define notice(fmt,args...)		 printk(KERN_NOTICE "scull-->" fmt,##args)
#define error(fmt,args...)		 printk(KERN_ERR    "scull-->" fmt,##args)

static __init int scull_init(void)
{
	notice("scull init\n");
	return 0;
}
static __exit void scull_exit(void)
{
	notice("scull exit\n");
}

module_init(scull_init);
module_exit(scull_exit);

MODULE_AUTHOR("xxxxxx");
MODULE_DESCRIPTION("Share Buffer");
MODULE_ALIAS("scull");
MODULE_VERSION("V1.0");

分配设备号注册字符设备

int register_chrdev_region(dev_t,unsigned int,const char*);表示静态的申请和注册设备号

int alloc_chrdev_region(dev_t,unsigned int,const char*);表示动态的申请和注册设备号

int register_chrdev(unsigned int,const char*,struct file_operations*);表示int为0时动态注册,非零静态注册

dev_t dev_num=MKDEV(major_no,0);将设备号转换为dev_t类型变量,第一个参数是主设备号,第二个是次设备号

此时,使用lsmod,可以发现你的设备就在其中


为设备分配内存

1.静态内存初始化

struct cdev my_cdev;
cdev_init(&my_cdev, &fops);//设备操作结构体
my_cdev.owner = THIS_MODULE;

2.动态内存初始化

struct cdev *my_cdev = cdev_alloc();
my_cdev->ops = &fops;
my_cdev->owner = THIS_MODULE;


添加设备到系统

int cdev_add(struct cdev *p, dev_t num, unsigned count);num 是这个设备响应的第一个设备号, count 是关联到设
备的设备号的数目. 常常是 1


从系统去除一个字符设备

void cdev_del(struct cdev *dev); 


释放设备号

void unregister_chrdev_region(dev_t first, unsigned int count); 


实例

#define notice(fmt,args...)		 printk(KERN_NOTICE "scull-->" fmt,##args)
#define error(fmt,args...)		 printk(KERN_ERR    "scull-->" fmt,##args)

#define DEV_NAME				 "scull"

struct scull_dev
{
	struct cdev cdev;
};

static struct file_operations fops = 
{
	.owner = THIS_MODULE,
};
static int major = 0;
static int setup_scull(struct scull_dev *p_dev)
{
	int ret;
	cdev_init(&(p_dev->cdev), &fops);
	p_dev->cdev.owner = THIS_MODULE;
	
	ret = cdev_add(&p_dev->cdev, MKDEV(major,0), 1);
	if (ret)
	{
		error("cdev_add err\n");
		return -1;
	}
	return 0;
}
static __init int scull_init(void)
{
	int ret = 0;
	
	dev_t dev_num = MKDEV(major,0);//将设备号转成dev_t类型
	
	if (major)
	{
		ret = register_chrdev_region(dev_num, 1, DEV_NAME);//知道设备号,使用静态分配
	}
	else
	{
		ret = alloc_chrdev_region(&dev_num, 0, 1, DEV_NAME);//不知道知道设备号,使用动态分配
		major = MAJOR(dev_num);//通过dev_t类型获取主设备号
	}
	
	struct scull_dev *pscull_dev = kmalloc(sizeof(struct scull_dev),GFP_KERNEL);
	if (NULL == pscull_dev)
	{
		error("kmalloc err\n");
		goto err_kmalloc;
	}
	
	ret = setup_scull(pscull_dev);
	if (ret < 0)
	{
		return -1;
	}
	notice("scull init\n");
	return 0;
	
err_kmalloc:
	unregister_chrdev_region(MKDEV(major,0), 1);
	return -1;
}
static __exit void scull_exit(void)
{
	unregister_chrdev_region(MKDEV(major,0), 1);
	notice("scull exit\n");
}

module_init(scull_init);
module_exit(scull_exit);

MODULE_AUTHOR("xxxxxx");
MODULE_DESCRIPTION("Share Buffer");
MODULE_ALIAS("scull");
MODULE_VERSION("V1.0");







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值