Linux内核的学习(三)之字符设备驱动的设备号

用户进程是通过什么来调用驱动?

系统编程,经常用open,read write 来操作设备文件来调用驱动。

crw-rw----  1 root video    10, 175 Dec 11 17:45 agpgart
crw------T  1 root root     10, 235 Dec 11 17:45 autofs
drwxr-xr-x  2 root root         660 Dec 11 17:45 block
drwxr-xr-x  2 root root         100 Dec 11 17:45 bsg
crw------T  1 root root     10, 234 Dec 11 17:45 btrfs-control

设备文件名字不重要,设备号才是最重要的。设备号是由主设备号和次设备号组成一个字符设备。

如autofs 的主设备号是10 , 次设备号是175;

crw--w----  1 root tty       4,  11 Dec 11 17:45 tty11
crw--w----  1 root tty       4,  12 Dec 11 17:45 tty12
crw--w----  1 root tty       4,  13 Dec 11 17:45 tty13
crw--w----  1 root tty       4,  14 Dec 11 17:45 tty14
crw--w----  1 root tty       4,  15 Dec 11 17:45 tty15
第一个字符’c’表示字符设备文件

主设备号通常表示一个字符设备驱动,上面5个设备它们驱动方法是一样的, 可以同用一个驱动。

在驱动里可通过次设备号来区分不同的硬件接口。

设备号很重要,在系统里是不可以重用的资源。注意是设备号不能重用,但主设备号可以重用

Linux 是用类型“dev_t(unsigned int )”  来表示一个设备号,dev_t是32位,高12位用于存放主设备号,低20位用于存放次设备号。

#incude <linux/kdev_t.h>

#define MINORBITS   20
#define MINORMASK   ((1U << MINORBITS) - 1)

#define MAJOR(dev)  ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev)  ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi)    (((ma) << MINORBITS) | (mi))
// 提供了设备号的宏操作

设备号像GPIO一样,使用前需要向内核申请,使用完后需返还内核。

#include <linux/fs.h>

int register_chrdev_region(dev_t from, unsigned count , const char *name);
//静态:申请设备号,from为设备号, count 指定使用该驱动有多少个设备(次设备号), name(名字,长度不能大于64字节)

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count , const char *name)
//动态申请设备号,由内核分配没有使用的主设备号,分配好的设备号存在dev(不需要初始化) baseminor指次设备号从多少开始,count多少个, 名字

void unregister_chrdev_region(dev_t from , unsigned count );
//释放设备号

//可通过”cat /proc/devices”查看系统里主设备号的使用状况 

步骤:

  1. 申请一个dev_t的对象 dev_t devid;
  2. devid = MKDEV(123, 321); 组合成一个设备号;
  3. 内核申请设备号,register_chrdev_region(devid, 3, "mydev");
  4. 使用完后需要回收设备号 unregister_chrdev_region(devid , 3);
编译后加载模块后 :
cat /proc/devices

posted on 2017-12-12 18:02  131927  阅读(221)  评论(0)    收藏  举报

导航