分类: 嵌入式
2009-11-14 17:16:34
struct cdev *my_cdev = cdev_alloc();// 下例中cdev结构被嵌入到scull_dev中,因此此步省略
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
dev->cdev.owner = THIS_MODULE;
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
字符设备的移除:
void cdev_del(struct cdev *p)
example:
struct scull_dev {
struct scull_qset *data; /* Pointer to first quantum set */
int quantum; /* the current quantum size */
int qset; /* the current array size */
unsigned long size; /* amount of data stored here */
unsigned int access_key; /* used by sculluid and scullpriv */
struct semaphore sem; /* mutual exclusion semaphore */
struct cdev cdev; /* Char device structure */
}; // 此cdev结构被嵌入到scull_dev中,因此须调用cdev_init来执行该结构的初始化。
int scull_init_module(void) //模块初始化函数
{
.........
scull_devices = kmalloc(scull_nr_devs * sizeof(struct scull_dev), GFP_KERNEL);//kmalloc 头文件linux/slab.h 成功返回内存指针 失败:NULL
if (!scull_devices) {
result = -ENOMEM;
goto fail; /* Make this more graceful */
}
memset(scull_devices, 0, scull_nr_devs * sizeof(struct scull_dev));
for (i = 0; i < scull_nr_devs; i++) {
scull_devices[i].quantum = scull_quantum;
scull_devices[i].qset = scull_qset;
init_MUTEX(&scull_devices[i].sem);
scull_setup_cdev(&scull_devices[i], i);//字符设备的注册
}
........
}
static void scull_setup_cdev(struct scull_dev *dev, int index)
{
int err, devno = MKDEV(scull_major, scull_minor + index);
cdev_init(&dev->cdev, &scull_fops);//初始化结构
dev->cdev.owner = THIS_MODULE; //初始化结构的所有者字段
dev->cdev.ops = &scull_fops;
err = cdev_add (&dev->cdev, devno, 1);//告知内核该结构信息
/* Fail gracefully if need be */
if (err)
printk(KERN_NOTICE "Error %d adding scull%d", err, index);
}
void scull_cleanup_module(void) //模块清除函数
{
int i;
dev_t devno = MKDEV(scull_major, scull_minor);
/* Get rid of our char dev entries */
if (scull_devices) {
for (i = 0; i < scull_nr_devs; i++) {
scull_trim(scull_devices + i);
cdev_del(&scull_devices[i].cdev);//先移除字符设备
}
kfree(scull_devices);//在释放内存
}
#ifdef SCULL_DEBUG /* use proc only if debugging */
scull_remove_proc();
#endif
/* cleanup_module is never called if registering failed */
unregister_chrdev_region(devno, scull_nr_devs);
/* and call the cleanup functions for friend devices */
scull_p_cleanup();
scull_access_cleanup();
}