全部博文(123)
分类: LINUX
2010-03-30 11:22:30
MAJOR(dev_t dev);//从dev中获取主设备号
MINOR(dev_t dev);//从dev中获取次设备号
MKDEV(int major, int minor);//构造主设备号为major,次设备号为minor的dev_t
register_chrdev_region.定义在
int register_chrdev_region(dev_t first,unsigned int count,char *name);
其中,first是要分配的设备编号范围的起始值。first的次设备号经常设置为0.count是连续设备编号的个数.name是和该编号范围关联的设备名称,将出现在/proc/devices和sysfs中。这个函数要求提前明确知道所需要的设备编号。
int alloc_chrdev_region(dev_t*dev,unsigned int firstminor,
unsigned int count,char *name);
其中,dev仅仅用于输出的函数,firstminor是要使用的被请求的第一个次设备号,它通常是0.其他同上。
释放设备号:
void unregister_chrdev_region(dev_t first,unsigned int count);
file_operations是连接设备编号和驱动程序的。
file表示一个打开的文件,系统中每个打开的文件在内核空间中都有一个对应的file结构,和具体进程相关。
inode包含大量有关文件的信息,有2个字段对编写驱动很有用:
dev_t i_rdev;//表示设备文件的inode结构,该字段包含了真正的设备编号。
struct cdev *i_cdev;//表示字符设备的内核数据结构,当inode指向一个字符设备文件时,该字段包含了指向struct cdev结构的指针。
C Primer Plus第五版中相关章节:
已知一个结构,定义如下
struct book
{
char title[MAXTITL];
char author[MAXAUTL];
float value;
};
C99支持结构的指定初始化项目,其语法与数组的指定初始化项目近似。只是,结构的指定初始化项目使用点运算符和成员名(而不是方括号和索引值)来标识具体的元素。例如,只初始化book结构的成员value,可以这样做:
struct book surprise = { .value = 10.99 };
可以按照任意的顺序使用指定初始化项目:
struct book gift = { .value = 25.99,
.author = "James Broadfool",
.title = "Rue for the Toad"
};
正像数组一样,跟在一个指定初始化项目之后的常规初始化项目为跟在指定成员后的成员提供了初始值。另外,对特定成员的最后一次赋值是它实际获得的值。例如,考虑下列声明:
struct book gift = { .value = 18.90,
.author = "Philionna pestle",
0.25
};
这将把值0.25赋给成员value,因为它在结构声明中紧跟在author成员之后。新的值0.25代替了早先的赋值18.90。
struct cdev *my_cdev=cdev_alloc();
my_cdev->ops=&my_fops;
初始化已经分配到的数据结构:
void cdev_init(struct cdev *cdev,struct file_operations *fops);
在cdev结构设置好之后,最后的步骤是通过下面的调用告诉内核该结构的信息:
int cdev_add(struct *dev, dev_t num, unsigned int count);//这个函数容易失败。
从系统中移除一个字符设备,做如下调用:
void cdev_del(struct cdev *dev);
struct cdev {
struct kobject kobj;
struct module *owner;
const struct file_operations *ops;
struct list_head list;
dev_t dev;
unsigned int count;
};
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
memset(cdev, 0, sizeof *cdev);
INIT_LIST_HEAD(&cdev->list);
kobject_init(&cdev->kobj, &ktype_cdev_default);
cdev->ops = fops;
}
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{
p->dev = dev;
p->count = count;
return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);
}
以上内容均来自《linux设备驱动程序3》