久久久久久久性爱潮,国产又粗又猛又爽又黄下载视频,尤物国产在线一区视频,欧美日本国产在线不卡

<sup id="4uqqy"><ol id="4uqqy"></ol></sup>
  • <th id="4uqqy"></th>

      • <strike id="4uqqy"><nobr id="4uqqy"><ins id="4uqqy"></ins></nobr></strike><sup id="4uqqy"></sup><strong id="4uqqy"><u id="4uqqy"></u></strong>
        <sub id="4uqqy"></sub>

          綠色資源網(wǎng):您身邊最放心的安全下載站! 最新軟件|熱門排行|軟件分類|軟件專題|廠商大全

          綠色資源網(wǎng)

          技術(shù)教程
          您的位置:首頁操作系統(tǒng)linux → 關(guān)于Linux的簡單字符設(shè)備驅(qū)動程序

          關(guān)于Linux的簡單字符設(shè)備驅(qū)動程序

          我要評論 2011/09/19 14:31:15 來源:綠色資源網(wǎng) 編輯:downcc.com [ ] 評論:0 點擊:178次

          一、重要知識點


          1. 主次設(shè)備號

          dev_t

          dev_t是內(nèi)核中用來表示設(shè)備編號的數(shù)據(jù)類型;

          int MAJOR(dev_t dev)

          int MINOR(dev_t dev)

          這兩個宏抽取主次設(shè)備號。

          dev­_t MKDEV(unsigned int major, unsignedint minor)

          這個宏由主/次設(shè)備號構(gòu)造一個dev_t結(jié)構(gòu)。



          2. 分配和釋放設(shè)備號

          int register_chardev_region(dev_t first,unsigned int count, char *name)

          靜態(tài)申請設(shè)備號。

          Int alloc_chardev_region(dev_t *dev,unsigned int firstminor, unsigned int count, char *name)

          動態(tài)申請設(shè)備號,注意第一個參數(shù)是傳地址,而靜態(tài)則是傳值。



          3. 幾種重要的數(shù)據(jù)結(jié)構(gòu)

          struct file

          file結(jié)構(gòu)代表一個打開的文件,它由內(nèi)核在open時創(chuàng)建,并傳遞給該文件上進行操作的所有函數(shù),直到最后的close函數(shù)。

          file結(jié)構(gòu)private_data是跨系統(tǒng)調(diào)用時保存狀態(tài)信息非常有用的資源。

          file結(jié)構(gòu)的f_ops 保存了文件的當(dāng)前讀寫位置。

          struct inode

          內(nèi)核用inode代表一個磁盤上的文件,它和file結(jié)構(gòu)不同,后者表示打開的文件描述符。對于單個文件,可能會有許多個表示打開文件的文件描述符file結(jié)構(gòu),但他們都指單個inode結(jié)構(gòu)。inode的dev_t i_rdev成員包含了真正的設(shè)備編號,struct cdev *i_cdev包含了指向struct cdev結(jié)構(gòu)的指針。

          struct file_operations

          file_operations結(jié)構(gòu)保存了字符設(shè)備驅(qū)動程序的方法。



          4. 字符設(shè)備的注冊和注銷

          struct cdev *cdev_alloc(void);

          void cdev_init(struct cdev *dev, structfile_operations *fops);

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

          void cdev_del(struct cdev *dev);

          用來管理cdev結(jié)構(gòu)的函數(shù),內(nèi)核中使用該結(jié)構(gòu)表示字符設(shè)備。注意cdev_add函數(shù)的count參數(shù)為次設(shè)備的個數(shù),要想擁有多個次設(shè)備,就必須將該參數(shù)設(shè)為次設(shè)備的個數(shù)。



          5. 并發(fā)處理

          信號量和自旋鎖的區(qū)別,使用信號量時當(dāng)調(diào)用進程試圖獲得一個鎖定了的鎖時會導(dǎo)致進程睡眠,而自旋鎖則是一直循法的等待一直到該鎖解鎖了為止。

          1)信號量

          DECLARE_MUTEX(name);

          DECLARE_MUTEX_LOCKED(name);

          聲明和初始化用在互斥模式中的信號量的兩個宏

          void init_MUTEX(struct semaphore *sem)

          void init_MUTEX_LOCKER(struct semaphore*sem);

          這兩個函數(shù)可以在運行時初始化信號量

          void down(struct semaphore *sem);

          int down_interruptible(struct semaphore*sem);

          int down_trylock(struct semahpore *sem);

          void up(struct semaphore *sem);

          鎖定和解鎖信號量。如果必要,down會將調(diào)用進程置于不可中斷的休眠狀態(tài);相反,down_interruptible可被信號中斷。down_trylock不會休眠,并且會在信號量不可用時立即返回。鎖定信號量的代碼最后必須使用up解鎖該信號量。

          2)自旋鎖

          spionlock_t lock = SPIN_LOCK_UNLOCKED;

          spin_lock_init(spinlock_t *lock);

          初始化自旋鎖的兩種方式。

          voidspin_lock(spinlock_t *lock);

          鎖定自旋鎖

          voidspin_unlock(spinlock_t *lock);

          解鎖自旋鎖

          二、驅(qū)動代碼




          view plaincopy to clipboardprint?#include <linux/module.h>
          #include <linux/types.h>
          #include <linux/fs.h>
          #include <linux/errno.h>
          #include <linux/mm.h>
          #include <linux/sched.h>
          #include <linux/init.h>
          #include <linux/cdev.h>
          #include <asm/io.h>
          #include <asm/system.h>
          #include <asm/uaccess.h>


          #define MEMDEV_MAJOR 251
          #define MEMDEV_NUM 2
          #define MEMDEV_SIZE 1024

          struct mem_dev
          {
          unsignedint size;
          char*data;
          structsemaphore sem;
          };


          static int mem_major = MEMDEV_MAJOR;

          struct cdev mem_cdev;
          struct mem_dev *mem_devp;


          static int mem_open(struct inode *inode,struct file *filp)
          {
          structmem_dev *dev;
          unsignedint num;

          printk("mem_open.\n");

          num= MINOR(inode->i_rdev);//獲得次設(shè)備號
          if(num> (MEMDEV_NUM -1)) //檢查次設(shè)備號有效性
          return-ENODEV;

          dev= &mem_devp[num];
          filp->private_data= dev; //將設(shè)備結(jié)構(gòu)保存為私有數(shù)據(jù)

          return0;
          }

          static int mem_release(struct inode *inode,struct file *filp)
          {
          printk("mem_release.\n");
          return0;
          }

          static ssize_t mem_read(struct file *filp,char __user *buf, size_t size, loff_t *ppos)
          {
          intret = 0;
          structmem_dev *dev;
          unsignedlong p;
          unsignedlong count;

          printk("mem_read.\n");

          dev= filp->private_data;//獲得設(shè)備結(jié)構(gòu)
          count= size;
          p= *ppos;

          //檢查偏移量和數(shù)據(jù)大小的有效性
          if(p> MEMDEV_SIZE)
          return0;
          if(count> (MEMDEV_SIZE-p))
          count= MEMDEV_SIZE - p;

          if(down_interruptible(&dev->sem))//鎖定互斥信號量
          return -ERESTARTSYS;

          //讀取數(shù)據(jù)到用戶空間
          if(copy_to_user(buf,dev->data+p, count)){
          ret= -EFAULT;
          printk("copyfrom user failed\n");
          }
          else{
          *ppos+= count;
          ret= count;
          printk("read%d bytes from dev\n", count);
          }

          up(&dev->sem);//解鎖互斥信號量

          returnret;
          }

          static ssize_t mem_write(struct file *filp,const char __user *buf, size_t size, loff_t *ppos)//注意:第二個參數(shù)和read方法不同
          {
          intret = 0;
          structmem_dev *dev;
          unsignedlong p;
          unsignedlong count;

          printk("mem_write.\n");

          dev= filp->private_data;
          count= size;
          p= *ppos;

          if(p> MEMDEV_SIZE)
          return0;
          if(count> (MEMDEV_SIZE-p))
          count= MEMDEV_SIZE - p;

          if(down_interruptible(&dev->sem))//鎖定互斥信號量
          return-ERESTARTSYS;

          if(copy_from_user(dev->data+p,buf, count)){
          ret= -EFAULT;
          printk("copyfrom user failed\n");
          }
          else{
          *ppos+= count;
          ret= count;
          printk("write%d bytes to dev\n", count);
          }

          up(&dev->sem);//解鎖互斥信號量

          returnret;
          }

          static loff_t mem_llseek(struct file *filp,loff_t offset, int whence)
          {
          intnewpos;

          printk("mem_llseek.\n");

          switch(whence)
          {
          case0:
          newpos= offset;
          break;

          case1:
          newpos= filp->f_pos + offset;
          break;

          case2:
          newpos= MEMDEV_SIZE - 1 + offset;
          break;

          default:
          return-EINVAL;
          }

          if((newpos<0)|| (newpos>(MEMDEV_SIZE - 1)))
          return-EINVAL;

          filp->f_pos= newpos;
          returnnewpos;
          }
          static const struct file_operationsmem_fops = {
          .owner= THIS_MODULE,
          .open= mem_open,
          .write= mem_write,
          .read= mem_read,
          .release= mem_release,
          .llseek= mem_llseek,
          };

          static int __init memdev_init(void)
          {
          intresult;
          interr;
          inti;

          //申請設(shè)備號
          dev_tdevno = MKDEV(mem_major, 0);

          if(mem_major)
          result= register_chrdev_region(devno, MEMDEV_NUM, "memdev");//注意靜態(tài)申請的dev_t參數(shù)和動態(tài)dev_t參數(shù)的區(qū)別 <

          關(guān)鍵詞:Linux,設(shè)備驅(qū)動

          閱讀本文后您有什么感想? 已有 人給出評價!

          • 1 歡迎喜歡
          • 1 白癡
          • 1 拜托
          • 1 哇
          • 1 加油
          • 1 鄙視