1. gzyueqian
      13352868059
      首頁 > 新聞中心 > > 正文

      內核入門:較為基礎的Linux系統設備驅動

      更新時間: 2007-12-12 15:34:45來源: 粵嵌教育瀏覽量:645


      驅動程序為:



      #include
      #include
      #include
      #include
      #include
      #include
      #include
      #include
      #include
      #include
      #include

      static unsigned int major = 0;
      static unsigned int minor = 0;
      static unsigned int devno;
      static char *filename = "mydevice";
      static struct cdev *mycdev = NULL;
      static int mycdevflg = 0;
      static int devnoflg = 0;
      static int adddevflg = 0;
      MODULE_LICENSE("Dual BSD/GPL");
      static int myopen(struct inode *inodep, struct file *flipl)
      {
      printk("my open is run\n");
      return 0;
      }
      static ssize_t myread(struct file *flip, char __user *buf, size_t size, loff_t offset)
      {
      printk("myread is ok!\n");
      static int i = 0;
      ///copy_to_user(buf,from,size);
      *buf = i++;
      return 0;
      }
      static int myrelease(struct inode *myindoe, struct file *flip)
      {
      printk("myrelease is run.\n");
      return 0;
      }
      static struct file_operations myfops =
      {
      .owner = THIS_MODULE,
      .open = myopen,
      .read = myread,
      .release= myrelease,
      };
      /* 初始化設備的過程主要是三步:1,生成設備號;2初始化設備;3,添加到內核。
      */
      static int __init myinit(void)
      {
      int result = -1;
      if(major)
      {
      devno = MKDEV(major,minor); //生成設備號
      result = register_chrdev_region(devno,1,filename);//注冊設備號devno,1為設備的個數
      devnoflg = 1;
      }
      else
      {
      result = alloc_chrdev_region(&devno,minor,1,filename);//生成設備號兵注冊,
      mior為次設備號,這里注意的是指針devno?
      major = MAJOR(devno);
      devnoflg = 1;
      }
      if(result < 0)
      {
      printk("can't register the major num!\n");
      devnoflg = 0;
      return -1;
      }
      //mycdev = kmalloc(sizeof(struct cdev),GFP_KERNEL);
      //如果采用cdev_init(struct cdev*,struct file *)方式的話,這個才需要。
      mycdev = cdev_alloc();//申請cdev內存兵初始化設備cdev,不能在這之前申請內存,
      否則要釋放兩次!
      if(NULL == mycdev)
      {
      printk("can't request the memory!\n");
      }
      mycdevflg = 1;
      //memset(mycdev,0,sizeof(mycdev));

      mycdev->owner = THIS_MODULE;//如果采用cdev_init(struct cdev*,struct file *)方式的話,
      這兩項可以去掉
      mycdev->ops = &myfops;//如果采用cdev_init(struct cdev*,struct file *)方式的話,
      這兩項可以去掉
      result = cdev_add(mycdev,devno,1);//設備和設備號聯系起來,
      即通常說的添加設備到內核
      if(result < 0)
      {
      printk("can't add cdev.2\n");
      adddevflg = 0;
      }
      else
      {
      adddevflg = 1;
      }
      return 0;
      }
      /* 以和設備注冊的次序"卸載",注意有的時候,當出錯的時候,要注意是否用到這些操作,
      所以要加上判斷,否則比如對空指針free會導致系統崩潰!
      */
      static void myexit(void)
      {
      printk("myexit begin.\n");
      if(adddevflg)
      {
      cdev_del(mycdev);
      adddevflg = 0;
      }
      if(mycdev)
      {
      kfree(mycdev);
      mycdev = NULL;
      }
      if(devnoflg)
      {
      unregister_chrdev_region(devno,1);
      devno = 0;
      devnoflg = 0;
      }
      printk("exit over.\n");
      }
      module_init(myinit);
      module_exit(myexit);



      應用程序為:



      #include
      #include
      #include
      #include
      #include
      int main()
      {
      int fd;
      int i=0;
      fd = open("/dev/mydevice", O_RDONLY);
      if (fd < 0)
      {
      printf("error1\n");
      return -1;
      }
      int j = 0;
      while(j++<10000)
      {
      if (read(fd, &i, sizeof(int)) < 0)
      {
      printf("read error2\n");
      return -1;
      }
      printf("i = %d\n",i);
      }
      close("/dev/mydevice");
      return 0;
      }



      一定要注意register_chrdev_region(),alloc_chrdev_region(),cdev_init(),cdev_alloc(),cdev_add()這些函數的參數類型,不要把指針當成非指針,把int類型當作指針(或者&)來使用!

      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 性爱国产精品福利在线 | 一区二区三区精品国产日韩免费 | 香港三级日本三级韩级人妇 | 亚洲欧美日韩久久精品一区 | 亚洲欧美日韩精品久久 | 日本久久精品免费观看 |