`
tomhibolu
  • 浏览: 1375812 次
文章分类
社区版块
存档分类
最新评论

字符设备驱动程序

 
阅读更多

哈尔滨理工大学软件工程专业08-7李万鹏原创作品,转载请标明出处

http://blog.csdn.net/woshixingaaa/archive/2010/11/13/6007342.aspx

LINUX设备驱动程序分为字符设备驱动(无缓冲且只能顺序存取),块设备驱动程序(有缓冲且可以随机存取)。每个字符设备和块设备都必须有主,次设备号,主设备号相同的设备是同类设备(使用同一驱动程序)。这些设备中,有些设备是对实际物理硬件的抽象,而有些设备则是则是内核自身提供的功能(不依赖于特定的物理硬件,又称为“虚拟设备”)。每个设备在/dev目录下都有一个对应的文件(节点),可以通过 cat /proc/devices命令查看当前已经加载的设备驱动程序的主设备号。

在内核中,dev_t类型用来保存设备编号(包括主设备号和次设备号):

  • 主设备号=MAJOR(dev_t dev)
  • 次设备号=MINOR(dev_t dev)
  • 设备编号=MKDEV(int major,int minor)

dev_t是无符长整型

  • typedef u_long dev_t ;
  • typedef unsigned long u_long;

分配和释放设备号:

  • int register_chrdev_region(dev_t first, unsigned int count, char *name);
  • int alloc_chrdev_region(dev_t *dev, unsigned int firstminor, unsigned int count, char *name);
  • void unregister_chrdev_region(dev_t first, unsigned int count);

字符设备的注册:

  • void cdev_init(struct cdev *cdev, struct file_operations *fops);
  • int cdev_add(struct cdev *dev, dev_t num, unsigned int count);
  • void cdev_del(struct cdev *dev);

早期的办法:

  • int register_chrdev(unsigned int major, const char *name, struct file_operations *fops);
  • int unregister_chrdev(unsigned int major, const char *name);

在内核空间和用户空间之间拷贝数据使用:

  • unsigned long copy_to_user(void __user*to,const void *from,unsigned long count);
  • unsigned long copy_from_user(void *to, const void __user *from,unsigned long count);

scull设备的布局:

这个结构是一个二维数组,qset是第一个下限,quantum是第二个下限。

下面是我写的驱动程序,没有用书上的,数了一下,书上的例子快到两千行代码了,所以自己写个容易的,设备是内存,first.c 需要注意的地方是,下面的struct file_operations first_fops是用C99标准写的,是标记化结构体初始化语法。左边的open,release,read,write都是系统调用,也就是说调用read是去执行read_test,调用write时执行write_test。在用户空间和内核空间之间传输数据应该使用函数copy_to_user和copy_from_user.

初始化模块时:

  • 获得设备号 alloc_chrdev_region,若已知则调用register_chrdev_region
  • 初始化字符设备 cdev_init
  • 将设备添加到系统中 cdev_add

注销模块:

  • 释放设备号 unregister_chrdev_region
  • 删除已经注册的char设备 cdev_del

Makefile

首先make,进行编译,生成first.ko文件。执行:

  • sudo insmod first.ko
  • cat /proc/devices 查看主设备号
  • sudo mknod /dev/test c 252 0 (c是字符设备的意思,250是我查看得到的主设备号,0是次设备号)

test.c

  • 然后编译用户空间的测试文件test.c 运行


    分享到:
    评论

    相关推荐

    Global site tag (gtag.js) - Google Analytics