请选择 进入手机版 | 继续访问电脑版

环信

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: mmap uikit gcc
查看: 341|回复: 2

8. udev(mdev) 自动创建设备文件

  [复制链接]

42

主题

68

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
发表于 2015-10-3 10:23:29 | 显示全部楼层 |阅读模式
本帖最后由 master 于 2015-12-22 12:12 编辑

自动创建设备文件(2.4内核)
devfs_register (devfs_handle_t dir,const char *name,unsigned int flags,unsigned int major,unsigned int minor,umode_t mode,void *ops, void *info)
在指定的目录中创建设备文件。dir:目录名,为空表示在/dev/目录下创建;name:文件名;
flags:创建标志;major:主设备号;minor:次设备号;mode:创建模式;ops:操作函数集;info:通常为空

自动创建设备文件(2.6内核)
相比devfs,udev(mdev)存在于应用层。利用udev(mdev)来实现设备文件的自动创建很简单,
在驱动初始化的代码里调用class_create为该设备创建一个class,再为每个设备调用device_create创建对应的设备。
例:
struct class *myclass = class_create(THIS_MODULE,“my_device_driver”);
device_create(myclass, NULL, MKDEV(major_num, 0), NULL,“my_device”);
当驱动被加载时,udev( mdev )就会自动在/dev下创建my_device设备文件。
回复

使用道具 举报

42

主题

68

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
 楼主| 发表于 2015-10-3 10:24:45 | 显示全部楼层
本帖最后由 master 于 2015-12-22 10:28 编辑

memdev.c
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/types.h>
  4. #include <linux/fs.h>
  5. #include <linux/errno.h>
  6. #include <linux/mm.h>
  7. #include <linux/sched.h>
  8. #include <linux/init.h>
  9. #include <linux/cdev.h>
  10. #include <asm/io.h>

  11. #include <linux/version.h>
  12. #if LINUX_VERSION_CODE > KERNEL_VERSION(3, 3, 0)
  13.         #include <asm/switch_to.h>
  14. #else
  15.         #include <asm/system.h>
  16. #endif
  17. #include <linux/slab.h>

  18. #include <asm/uaccess.h>
  19. #include <linux/device.h> /* device_create()*/

  20. #include "memdev.h"

  21. static int mem_major = MEMDEV_MAJOR;
  22. module_param(mem_major, int, S_IRUGO);
  23. struct mem_dev *mem_devp; /*设备结构体指针*/
  24. struct cdev cdev;

  25. /*文件打开函数*/
  26. int mem_open(struct inode *inode, struct file *filp)
  27. {
  28.     struct mem_dev *dev;
  29.    
  30.     /*获取次设备号*/
  31.     int num = MINOR(inode->i_rdev);

  32.     if (num >= MEMDEV_NR_DEVS)
  33.             return -ENODEV;
  34.     dev = &mem_devp[num];
  35.    
  36.     /*将设备描述结构指针赋值给文件私有数据指针*/
  37.     filp->private_data = dev;
  38.    
  39.     return 0;
  40. }

  41. /*文件释放函数*/
  42. int mem_release(struct inode *inode, struct file *filp)
  43. {
  44.     return 0;
  45. }

  46. /*读函数*/
  47. static ssize_t mem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
  48. {
  49.     unsigned long p =  *ppos;
  50.     unsigned int count = size;
  51.     int ret = 0;
  52.     struct mem_dev *dev = filp->private_data; /*获得设备结构体指针*/

  53.     /*判断读位置是否有效*/
  54.     if (p >= MEMDEV_SIZE)
  55.         return 0;
  56.     if (count > MEMDEV_SIZE - p)
  57.         count = MEMDEV_SIZE - p;

  58.     /*读数据到用户空间*/
  59.     if (copy_to_user(buf, (void*)(dev->data + p), count))
  60.     {
  61.         ret =  - EFAULT;
  62.     }
  63.     else
  64.     {
  65.         *ppos += count;
  66.         ret = count;

  67.         printk(KERN_INFO "read %d bytes(s) from %d\n", count, p);
  68.     }

  69.     return ret;
  70. }

  71. /*写函数*/
  72. static ssize_t mem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
  73. {
  74.     unsigned long p =  *ppos;
  75.     unsigned int count = size;
  76.     int ret = 0;
  77.     struct mem_dev *dev = filp->private_data; /*获得设备结构体指针*/

  78.     /*分析和获取有效的写长度*/
  79.     if (p >= MEMDEV_SIZE)
  80.         return 0;
  81.     if (count > MEMDEV_SIZE - p)
  82.         count = MEMDEV_SIZE - p;

  83.     /*从用户空间写入数据*/
  84.     if (copy_from_user(dev->data + p, buf, count))
  85.         ret =  - EFAULT;
  86.     else
  87.     {
  88.         *ppos += count;
  89.         ret = count;

  90.         printk(KERN_INFO "written %d bytes(s) from %d\n", count, p);
  91.     }

  92.     return ret;
  93. }

  94. /* seek文件定位函数 */
  95. static loff_t mem_llseek(struct file *filp, loff_t offset, int whence)
  96. {
  97.     loff_t newpos;

  98.     switch(whence) {
  99.       case 0: /* SEEK_SET */
  100.         newpos = offset;
  101.         break;

  102.       case 1: /* SEEK_CUR */
  103.         newpos = filp->f_pos + offset;
  104.         break;

  105.       case 2: /* SEEK_END */
  106.         newpos = MEMDEV_SIZE -1 + offset;
  107.         break;

  108.       default: /* can't happen */
  109.         return -EINVAL;
  110.     }
  111.     if ((newpos<0) || (newpos>MEMDEV_SIZE))
  112.         return -EINVAL;
  113.         
  114.     filp->f_pos = newpos;
  115.     return newpos;

  116. }

  117. /*文件操作结构体*/
  118. static const struct file_operations mem_fops =
  119. {
  120.     .owner = THIS_MODULE,
  121.     .llseek = mem_llseek,
  122.     .read = mem_read,
  123.     .write = mem_write,
  124.     .open = mem_open,
  125.     .release = mem_release,
  126. };

  127. struct class *myclass;
  128. /*设备驱动模块加载函数*/
  129. static int memdev_init(void)
  130. {
  131.     int result;
  132.     int i;

  133.     dev_t devno = MKDEV(mem_major, 0);

  134.     /* 静态申请设备号*/
  135.     if (mem_major)
  136.         result = register_chrdev_region(devno, 2, "memdev");
  137.     else  /* 动态分配设备号 */
  138.     {
  139.         result = alloc_chrdev_region(&devno, 0, 2, "memdev");
  140.         mem_major = MAJOR(devno);
  141.     }  

  142.     if (result < 0)
  143.         return result;

  144.     /*初始化cdev结构*/
  145.     cdev_init(&cdev, &mem_fops);
  146.     cdev.owner = THIS_MODULE;
  147.     cdev.ops = &mem_fops;

  148.     /* 注册字符设备 */
  149.     cdev_add(&cdev, MKDEV(mem_major, 0), MEMDEV_NR_DEVS);

  150.     /* 为设备描述结构分配内存*/
  151.     mem_devp = kmalloc(MEMDEV_NR_DEVS * sizeof(struct mem_dev), GFP_KERNEL);
  152.     if (!mem_devp)    /*申请失败*/
  153.     {
  154.         result =  - ENOMEM;
  155.         goto fail_malloc;
  156.     }
  157.     memset(mem_devp, 0, sizeof(struct mem_dev));

  158.     /*为设备分配内存*/
  159.     for (i=0; i < MEMDEV_NR_DEVS; i++)
  160.     {
  161.         mem_devp[i].size = MEMDEV_SIZE;
  162.         mem_devp[i].data = kmalloc(MEMDEV_SIZE, GFP_KERNEL);
  163.         memset(mem_devp[i].data, 0, MEMDEV_SIZE);
  164.     }

  165.     /*自动创建设备文件*/
  166.     myclass = class_create(THIS_MODULE,"test_char"); /* 在sys下创建类目录/sys/class/test_char */
  167.     device_create(myclass, NULL, MKDEV(mem_major,0), NULL, "memdev0");    /*在dev目录创建 /dev/memdev0 */
  168.     return 0;

  169.     fail_malloc:
  170.     unregister_chrdev_region(devno, 1);

  171.     return result;
  172. }

  173. /*模块卸载函数*/
  174. static void memdev_exit(void)
  175. {
  176.     cdev_del(&cdev);   /*注销设备*/

  177.     device_destroy(myclass, MKDEV(mem_major, 0));         //delete device node under /dev
  178.     class_destroy(myclass);                               //delete class created by us
  179.          
  180.     kfree(mem_devp);     /*释放设备结构体内存*/
  181.     unregister_chrdev_region(MKDEV(mem_major, 0), MEMDEV_NR_DEVS); /*释放设备号*/
  182. }

  183. MODULE_AUTHOR("David Xie");
  184. MODULE_LICENSE("GPL");

  185. module_init(memdev_init);
  186. module_exit(memdev_exit);

复制代码


memdev.h

  1. #ifndef _MEMDEV_H_
  2. #define _MEMDEV_H_

  3. #ifndef MEMDEV_MAJOR
  4. #define MEMDEV_MAJOR 261   /*预设的mem的主设备号*/
  5. #endif

  6. #ifndef MEMDEV_NR_DEVS
  7. #define MEMDEV_NR_DEVS 2    /*设备数*/
  8. #endif

  9. #ifndef MEMDEV_SIZE
  10. #define MEMDEV_SIZE 4096
  11. #endif

  12. /*mem设备描述结构体*/
  13. struct mem_dev                                    
  14. {                                                        
  15.     char *data;                     
  16.     unsigned long size;      
  17. };

  18. #endif /* _MEMDEV_H_ */

复制代码


回复 支持 反对

使用道具 举报

42

主题

68

帖子

229

积分

中级会员

Rank: 3Rank: 3

积分
229
 楼主| 发表于 2015-12-22 10:29:00 | 显示全部楼层
app-mem.c

  1. #include <stdio.h>

  2. int main()
  3. {
  4.         FILE *fp0 = NULL;
  5.         char Buf[4096];
  6.        
  7.         /*初始化Buf*/
  8.         strcpy(Buf,"Mem is char dev!");
  9.         printf("BUF: %s\n",Buf);
  10.        
  11.         /*打开设备文件*/
  12.         fp0 = fopen("/dev/memdev0","r+");
  13.         if (fp0 == NULL)
  14.         {
  15.                 printf("Open Memdev0 Error!\n");
  16.                 return -1;
  17.         }
  18.        
  19.         /*写入设备*/
  20.         fwrite(Buf, sizeof(Buf), 1, fp0);
  21.        
  22.         /*重新定位文件位置(思考没有该指令,会有何后果)*/
  23.         fseek(fp0,0,SEEK_SET);
  24.        
  25.         /*清除Buf*/
  26.         strcpy(Buf,"Buf is NULL!");
  27.         printf("BUF: %s\n",Buf);
  28.        
  29.        
  30.         /*读出设备*/
  31.         fread(Buf, sizeof(Buf), 1, fp0);
  32.        
  33.         /*检测结果*/
  34.         printf("BUF: %s\n",Buf);
  35.        
  36.         return 0;       

  37. }
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|环信 Glofty.com ( 粤ICP备15084637号 )

GMT+8, 2017-1-23 16:34 , Processed in 0.211708 second(s), 21 queries .

快速回复 返回顶部 返回列表