乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      最簡單的字符設(shè)備驅(qū)動(dòng)程序

       北漂之鄔 2014-01-23

      首先,先理清一下簡單字符設(shè)備驅(qū)動(dòng)程序的思路:

      (1)申請?jiān)O(shè)備號

            動(dòng)態(tài)申請:int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,const char *name)

            靜態(tài)申請:int register_chrdev_region(dev_t from,  unsigned count, const char *name)

            成功返回0,失敗返回負(fù)數(shù),并置于errno

      (2)分配cdev ,可以使用struct cdev *cdev_alloc(void) ,或者靜態(tài)定義全局cdev變量

      (3)初始化cdev

             若使用動(dòng)態(tài)分配,則需要進(jìn)行初始化:void cdev_init(struct cdev *cdev, const struct file_operations *fops)  ,mem_cdev.owner = THIS_MODULE;

             若動(dòng)態(tài)內(nèi)存定義初始化:struct cdev *mem_cdev = cdev_alloc();    mem_cdev->ops = &fops;   mem_cdev->owner = THIS_MODULE

      (4)添加cdev

            int cdev_add(struct cdev *p, dev_t dev,unsigned count)

      若使用內(nèi)存模擬字符設(shè)備,則還需申請空間:

           mem_devp = kmalloc( 2 * sizeof(struct mem_dev), GFP_KERNEL);
              if(!mem_devp){
                      result = -ENOMEM;
                      goto fail_malloc;
              }
              memset(mem_devp, 0, sizeof(struct mem_dev));
              for(i = 0; i < 2; i++)
              {
                      mem_devp[i].size = MEMDEV_SIZE;
                      mem_devp[i].data = kmalloc(MEMDEV_SIZE, GFP_KERNEL);
                      memset(mem_devp[i].data, 0, MEMDEV_SIZE);
              }

      申請失敗情況下,記得注銷設(shè)備號,使用void unregister_chrdev_region(dev_t from, unsigned count)

      (5)構(gòu)造file_operations結(jié)構(gòu)體(結(jié)構(gòu)體字段的初始化)

      static const struct file_operations mem_fops =
      {
              .owner = THIS_MODULE,
              .llseek = mem_llseek,
              .read = mem_read,
              .write = mem_write,
              .open = mem_open,
              .release = mem_release,
      };

      (6)實(shí)現(xiàn)file_operations支持的函數(shù)

       int mem_open(struct inode *inode, struct file *filp)
      {
              struct mem_dev *dev;
              int num = MINOR(inode->i_rdev);
              if(num >= MEMDEV_NR_DEVS)
                      return -ENODEV;
              dev = &mem_devp[num];
              filp->private_data = dev;

              return 0;
      }

      static ssize_t mem_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos)
      {
              unsigned long p = *ppos;
              unsigned int count = size;
              int ret = 0;
              struct mem_dev *dev = filp->private_data;
              if(p > MEMDEV_SIZE)
                      return 0;
              if(count > MEMDEV_SIZE - p)
                      count = MEMDEV_SIZE - p;
              if(copy_to_user(buf, (void *)(dev->data + p), count)){
              ret = -EFAULT;
              }
              else{
              *ppos += count;
              ret = count;
              printk(KERN_INFO "read %d bytes from %ld", count, p);
              }
              return ret;
      }
      static ssize_t mem_write(struct file *filp, const char __user *buf, size_t size, loff_t *ppos)
      {
              unsigned long p = *ppos;
              unsigned int count = size;
              int ret = 0;
              struct mem_dev *dev = filp->private_data;
              if(p > MEMDEV_SIZE)
                      return 0;
              if(count > MEMDEV_SIZE - p)
                      count = MEMDEV_SIZE - p;
              if(copy_from_user(dev->data + p, buf, count)){
              ret = -EFAULT;
              }
              else{
              *ppos += count;
              ret = count;
              printk(KERN_INFO "writen %d bytes from %ld", count, p);
              }
              return ret;
      }

      static loff_t mem_llseek(struct file *filp, loff_t offset, int whence)
      {
              loff_t newpos;
              switch(whence){
                      case 0:
                        newpos = offset;
                        break;
                      case 1:
                        newpos = filp->f_pos+offset;
                        break;
                      case 2:
                        newpos = MEMDEV_SIZE - 1 + offset;
                        break;
                      default:
                        return -EINVAL;
              }
              if((newpos < 0) || (newpos > MEMDEV_SIZE))
                      return -EINVAL;
              filp->f_pos = newpos;
              return newpos;
      }

      int mem_release(struct inode *inode, struct file *filp)
      {
              return 0;
      }

      測試代碼:

      #include <stdio.h>

      int main()
      {
              FILE *fp = NULL;
              char Buf[4096];

              strcpy(Buf, "mem is char dev!");
              printf("Buf:%s\n",Buf);

              fp = fopen("/dev/memdev1", "r+");
              if(fp == NULL){
              printf("open memdev1 error!\n");
              }

              fwrite(Buf, sizeof(Buf), 1, fp);
              fseek(fp, 0, SEEK_SET);

              strcpy(Buf,"Buf is NULL!");
              printf("Buf: %s\n",Buf);

              fread(Buf, sizeof(Buf), 1, fp);
              printf("Buf: %s\n",Buf);
              return 0;
      }

       

       


        

        本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多