1 驅動程序有主設備號,次設備號之分,主設備號是區分設備屬於哪個驅動的標誌,次設備號是驅動程序用來區別多個設備的。
2 設備號的內部表示:
typedef unsigned long dev_t;其中搞12位爲主設備號,低20位爲次設備號。
已知dev_t類型的變量,要想獲取主設備號或者次設備號,使用宏:MAJOR(dev_t dev) MINOR(dev_t dev)
已知主次設備號,生成dev_t類型變量,使用宏:MKDEV(int major, int minor);
3 分配主次設備號的方法
一般請求分配設備號的時機應該是在驅動程序的初始化函數中,內核API有:
int register_chrdev_region(dev_t first, unsigned int count, char *name)
靜態請求設備號,失敗返回負數,dev_t爲要申請的主次設備號,count爲總共要申請的設備個數,name爲驅動的名稱
int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name)
動態申請設備號,失敗返回負數,dev保存得到的設備號,firstminor爲第一個要求申請的次設備號,count爲申請的設備個數,name爲驅動名稱
例子:
int scull_minor=0;
if(scull_major)
{
dev=MKDEV(scull_major, scull_minor);
result=register_chrdev_region(dev, scull_nr_devs, "scull");
}
else
{
result=alloc_chrdev_region(&dev, scull_minor, scull_nr_devs, "scull");
}
if(result<0)
{
printk("cannot get major");
return result;
}
4 釋放設備號
unregister_chrdev_region(devno, scull_nr_devs);
#mknod /dev/scull0 c 252 0
c爲字符設備文件
dev->cdev.owner=THIS_MODULE;
dev->cdev.ops=&scull_fops;
err=cdev_add(&dev->cdev, devno, 1);
if(err)
printk("add scull fail");
其中cdev_init和下面的兩行代碼都是初始化各個cdev的字段,cdev_add是將這個設備加入到操作系統字符設備鏈表中。
cdev_del(&scull_devices[i].cdev);
cdev_del是將字符設備從字符設備鏈表中移除。
struct file_operations scull_fops = {
.owner = THIS_MODULE,
.llseek = scull_llseek,
// .llseek = no_llseek,
.read = scull_read,
.write = scull_write,
.compat_ioctl = scull_ioctl,
.open = scull_open,
.release = scull_release,
};
int scull_open(struct inode *inode, struct file *filp)
用戶程序調用open的時候系統會調用驅動的open
int scull_release(struct inode *inode, struct file *filp)
用戶調用close的時候一般會調用函數,是當文件表被釋放的時候調用的,如果close的時候文件表沒有被釋放,則不會調用release函數
ssize_t scull_read(struct file *filp, char __user *buf, size_t count,
loff_t *f_pos)
用戶調用read的時候,系統會調用驅動中的read函數,filp爲文件表指針,buf,count爲用戶調用時傳入的,f_pos爲文件表中的f_pos字段
ssize_t scull_write(struct file *filp, const char __user *buf, size_t count,
loff_t *f_pos)
loff_t scull_llseek(struct file *filp, loff_t off, int whence)
int scull_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)