【原创】嵌入式系统中设备号的意义
0赞设备号:设备号主要是用查找设备对象用的。
格式:设备号由主设备号和次设备号组成。一般的,主设备用来表征一类设备,次设备号用来表示该设备是第几个。
内核函数:
声明头文件:linux/kdev_t.h |
/* *功能:组装设备号 *参数: * int major主设备号 * int minor次设备号 *返回值: * 设备号 */ dev_t MKDEV(int major, int minor); |
/* *功能:分离主设备号 *参数: * dev_t dev设备号 *返回值: * 主设备号 */ int MAJOR(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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/cdev.h>
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);