【原创】嵌入式系统中设备号的意义
0赞设备号:设备号主要是用查找设备对象用的。
格式:设备号由主设备号和次设备号组成。一般的,主设备用来表征一类设备,次设备号用来表示该设备是第几个。
内核函数:
声明头文件:linux/kdev_t.h |
/* *功能:组装设备号 *参数: * int major主设备号 * int minor次设备号 *返回值: *设备号 */ dev_t MKDEV(int major, int minor); |
/* *功能:分离主设备号 *参数: * dev_t dev设备号 *返回值: *主设备号 */ intMAJOR(dev_t dev); |
/* *功能:分离次设备号 *参数: * dev_t dev设备号 *返回值: *次设备号 */ int MINOR(dev_t dev); |
声明头文件:linux/fs.h |
/* *功能:静态申请设备号 *参数: *dev_t被指定的设备号 *unsigned设备号的数量,从指定的次设备号开始分配,到这个值的指定数量结束 *const char *设备名称,如果申请成功cat /proc/devices中可以看到主设备号及该字符串指定的名称 *返回值: *成功:0;失败:错误码 */ int register_chrdev_region(dev_t, unsigned, const char *); |
/* *功能:动态分配设备号 *参数: *dev_t指向分配的设备号,用来保存内核分配的第一个设备号(次设备号是第二个参数指定的) *unsigned第一个次设备号 *unsigned设备号的数量,从指定的次设备号开始分配,到这个值的指定数量结束 *const char *设备名称,如果申请成功cat /proc/devices中可以看到主设备号及该字符串指定的名称 *返回值: *成功:0;失败:错误码 */ int alloc_chrdev_region(dev_t *, unsigned, unsigned, const char *); |
基本框架及测试应用程序范例:
#include
#include
#include
#include
#include
#include
#include
static int demo_major = 0;
static int demo_minor = 0;
static int demo_nrdevs = 1;
static const char demodevname[] = "demodev";
static struct cdev cdev;
static int demo_open(struct inode *inode, struct file *filep)
{
printk(KERN_INFO "demo_open\n");
return 0;
}
static int demo_release(struct inode *inode, struct file *filp)
{
printk(KERN_INFO "demo_release\n");
return 0;
}
static ssize_t demo_read(struct file *filep, char __user *buf, size_t count, loff_t *fpos)
{
printk(KERN_INFO "demo_read\n");
return 0;
}
static ssize_t demo_write(struct file *filep, const char __user *buf, size_t count, loff_t *fpos)
{
printk(KERN_INFO "demo_write\n");
return 0;
}
static struct file_operations fops = {
.owner = THIS_MODULE,
.read = demo_read,
.write = demo_write,
.open = demo_open,
.release = demo_release,
};
static void __exit demo_exit(void)
{
dev_t dev;
dev = MKDEV(demo_major, demo_minor);
cdev_del(&cdev);
unregister_chrdev_region(dev, demo_nrdevs);
}
static int __init demo_init(void)
{
int err;
dev_t dev;
if (demo_major) {
dev = MKDEV(demo_major, demo_minor);
err = register_chrdev_region(dev, demo_nrdevs, demodevname);
} else {
err = alloc_chrdev_region(&dev, demo_minor, demo_nrdevs, demodevname);
demo_major = MAJOR(dev);
}
if (err < 0) {
printk(KERN_ERR "Can't get major %d\n", demo_major);
return err;
}
cdev_init(&cdev, &fops);
cdev.owner = THIS_MODULE;
err = cdev_add (&cdev, dev, 1);
if (err){
printk(KERN_ERR "Error %d adding %s", err, demodevname);
goto ERR_STEP_0;
}
return 0;
ERR_STEP_1:
cdev_del(&cdev);
ERR_STEP_0:
unregister_chrdev_region(dev, demo_nrdevs);
return err;
}
MODULE_LICENSE("Dual BSD/GPL");
module_init(demo_init);
module_exit(demo_exit);