Chinaunix首页 | 论坛 | 博客
  • 博客访问: 224800
  • 博文数量: 39
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 584
  • 用 户 组: 普通用户
  • 注册时间: 2015-04-18 20:24
个人简介

学习总结,分享快乐。 望指正错误, 共同提高!!!

文章分类

全部博文(39)

分类: 嵌入式

2015-06-01 22:52:22


1> 思路:
            分配3块内存空间,抽象为设备(u盘),对应同1套设备驱动,进行操作,就是《LDD3》中“SCULL”的实例。
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2> 源码:

点击(此处)折叠或打开

  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/kernel.h>
  4. #include <linux/fs.h>
  5. #include <asm/uaccess.h>
  6. #include <linux/cdev.h>
  7. #include <linux/slab.h>

  8. #define SZ     1024

  9. /*设备类型*/
  10. typedef struct {
  11.         char *buf; //内存设备地址
  12.         u32 len;
  13.         struct cdev cdev;
  14. }kbuf_t;


  15. static int major = 0;
  16. static int minor = 0;
  17. static int count = 3;
  18. static dev_t devnum;

  19. static   kbuf_t *kbuf;

  20. //3步 填写说明书
  21.     /*my_open, my_read, my_write*/

  22. static int my_open (struct inode *inodp, struct file *filp)
  23. {
  24.         printk("device %d is open!\n", iminor(inodp));

  25.     /*存入需要的数据,供后面函数使用*/
  26.         filp->private_data = &kbuf[iminor(inodp)];

  27.        return 0;
  28. }

  29. static ssize_t my_read (struct file *filp, char _ _user *buf, size_t count, loff_t * fpos)
  30. {
  31.         kbuf_t *p = filp->private_data;    

  32.         count = min(count, p->len);

  33.         if(copy_to_user(buf, p->buf, count)){
  34.                     return -EAGAIN;
  35.         } else {
  36.                     memcpy(p->buf, p->buf+count, p->len - count);
  37.                     p->len -= count;
  38.         }

  39.     return count;
  40. }

  41. static ssize_t my_write (struct file *filp, const char __user *buf, size_t count, loff_t *fpos)
  42. {
  43.     kbuf_t *p = filp->private_data;    

  44.     count = min(count, (size_t)(SZ - p->len));

  45.     if(copy_from_user(p->buf+p->len, buf, count)){
  46.         return -EAGAIN;
  47.     }else{
  48.         p->len += count;    
  49.     }

  50.     return count;        
  51. }

  52. static int my_release (struct inode *inodep, struct file *filp)
  53. {
  54.     return 0;
  55. }

  56. static struct file_operations fops = {
  57.     .owner = THIS_MODULE,
  58.     .open = my_open,
  59.     .read = my_read,
  60.     .write = my_write,
  61.     .release = my_release,
  62. };

  63. static int __init my_init(void)
  64. {
  65.     int ret;
  66.     int i, j;

  67.     /*分配3个设备结构体*/
  68.     kbuf = kmalloc(sizeof(*kbuf)*count, GFP_KERNEL);

  69.     if(NULL == kbuf){
  70.         return -ENOMEM;
  71.     }

  72.     /*实例化3个设备,可把它想象为你现在有 3 个 U盘*/
  73.     for(i = 0; i < count; i++){
  74.         kbuf[i].buf = kzalloc(SZ, GFP_KERNEL);
  75.         if(kbuf[i].buf == NULL){
  76.             ret = -ENOMEM;
  77.             goto error0;
  78.         }
  79.     }

  80. //1步:分配设备号
  81.     if(major){                 /*静态分配设备号*/
  82.         devnum = MKDEV(major, minor);
  83.         ret = register_chrdev_region(devnum, count, "kbuf");
  84.     }else{                     /*动态分配设备号*/
  85.         ret = alloc_chrdev_region(&devnum, minor, count, "kbuf");
  86.         major = MAJOR(devnum);
  87.     }
  88.     if(ret < 0){
  89.         goto error0;
  90.     }    

  91.     for(j = 0; j < count; j++){
  92. //2步:将说明书与设备绑定
  93.             /*cdev->ops = fops;*/
  94.             cdev_init(&kbuf[j].cdev, &fops);

  95. //4步:向内核添加。这必须最后一步。
  96.             ret = cdev_add(&kbuf[j].cdev,   MKDEV(major, j,    1);    
  97.             if(ret < 0){
  98.                     goto error1;
  99.             }    
  100.     }

  101.     return 0;

  102. error1:
  103.     while(j){
  104.         cdev_del(&kbuf[j-1].cdev);
  105.     }
  106.     unregister_chrdev_region(devnum, count);

  107. error0:
  108.     while(i){
  109.         kfree(kbuf[i-1].buf);
  110.         i--;    
  111.     }
  112.     kfree(kbuf);
  113.     return ret;
  114. }

  115. static void __exit my_exit(void)
  116. {
  117.     int i;

  118. /*释放分配的内存空间*/
  119.     for(i = 0; i < count; i++){
  120.         cdev_del(&kbuf[i].cdev);
  121.         kfree(kbuf[i].buf);
  122.     }

  123. /*释放分配的3个设备号*/
  124.     unregister_chrdev_region(devnum, count);

  125. /*释放分配的3个结构体空间*/
  126.     kfree(kbuf);

  127.     printk("Bye bye\n");
  128. }

  129. module_init(my_init);
  130. module_exit(my_exit);

  131. MODULE_LICENSE("GPL");
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3> 测试:

点击(此处)折叠或打开

  1. # cat /pro/devices
  2. 251 kbuf      /*主设备号*/
  3.                  
  4. mknod u1 c 251 0
  5. mknod u2 c 251 1
  6. mknod u3 c 251 2

点击(此处)折叠或打开

  1. # echo 123456789 >> u1
  2.  device 0 is open

  3. # echo 111111111 >> u2
  4. device 1 is open

  5. # echo 222222222 >> u3
  6. device 2 is open


  7. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  8. # cat u1
  9. device 0 is open
  10. 123456789

  11. # cat u2
  12. device 1 is open
  13. 111111111

  14. # cat u3
  15. device 2 is open
  16. 222222222
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

4> 原理:鉴于目前水平 删掉其中不明白的代码,只是大概理解

alloc_chrdev_region(&devnum, minor, count, "kbuf")
//@&devnum:动态分配的设备号存入devnum
//@cout:连续分配次设备号个数
//@minor:次设备号起始号
//@kbuf:你猜?
………………………………………………………………………………………………………………………………

点击(此处)折叠或打开

  1. struct cdev {

  2.         struct module *owner;
  3.         const struct file_operations *ops;
  4.         dev_t dev;
  5.         unsigned int count;
  6. };

点击(此处)折叠或打开

  1. cdev_init(&kbuf[j].cdev,    &fops)
  2.  
  3. void cdev_init(struct cdev *cdev, const struct file_operations *fops)
  4. {
                  cdev->ops = fops;
    }
  5. //将设备操作函数与设备绑定

…………………………………………………………………………………………………………………………………………………………

点击(此处)折叠或打开

  1. cdev_add(&kbuf[j].cdev, MKDEV(major, j), 1)

  2. int cdev_add(struct cdev *p, dev_t dev, unsigned count)
  3. {
  4.         p->dev = dev;
  5.         p->count = count;
  6.         return kobj_map(cdev_map, dev, count, NULL, exact_match, exact_lock, p);    //不明白,
  7. }

            //向内核添加。


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
总结:
        1> 分清设备号, 主设备号, 次设备号。
        2> 主要的3大步: 分配设备号 --》说明书与设备绑定 ----》交给管家











阅读(1842) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~