linux 驅動學習之poll與select

來源:互聯網
上載者:User

        在使用socket或串口的時候應用代碼經常使用select來判斷有沒接收到資料,驅動需要做什麼處理,應用程式層使用者才能正確判斷有資料收到並讀取資料呢?使用select能夠監視我們需要監視的檔案描述符的變化情況——讀寫或是異常。
       先建立簡單模型,應用使用select監聽裝置是否可讀,當裝置可讀將資料讀出後繼續監聽。已經有了一個監聽裝置可讀狀態的進程,還要開啟終端使用echo xxx >/dev/moddev60向裝置寫入資料,裝置驅動收到資料後控制裝置變成可讀狀態,select進程select函數返回,查詢裝置可讀後讀出資料。代碼為了示範做了簡化不做並發出錯處理等。

先看下應用c代碼

#include <stdio.h>#include <fcntl.h>unsigned char rdBuf[1024];int main (int *argc,char**argv){   int fd,res;fd_set fset;   FD_ZERO(&fset);   fd=open("/dev/moduledev60",O_RDWR);   if(fd<0){    printf("open devices error\n");return -1;    }    while(1) {   FD_ZERO(&fset);    FD_SET(fd,&fset);        res=select(fd+1,&fset,NULL,NULL,NULL);       if(res==-1)   { close(fd);       return -1;   }   else if(res==0)  break;   else   { /*select 返回後判斷可讀*/     if(FD_ISSET(fd,&fset)) {    read(fd,rdBuf,1024);    printf("read data:%s\n",rdBuf); }   } }close(fd);return 0;}

驅動關鍵代碼

struct file_operations ops={   .owner=THIS_MODULE  ,   .read =fileops_read ,   .write=fileops_write,   .poll =fileops_poll};

DECLARE_WAIT_QUEUE_HEAD(rdWait);//poll_wait中使用static unsigned char rdBuf[1024];//測試用讀寫緩衝 寫入資料和讀取資料0結尾static unsigned char rdFlag=0;   //可讀標記 0不可讀緩衝內無資料  1可讀ssize_t fileops_read(struct file *filp, char __user *buff, size_t count, loff_t *offp){  unsigned int len;  if(rdFlag==0) return 0;        //不可讀時直接返回  len=strlen(rdBuf);             //讀緩衝字串長  這個模型只做字串(0結尾)的寫入和讀取  copy_to_user(buff,rdBuf,len);  //  rdFlag=0;                      //清標記  return len;}ssize_t fileops_write(struct file *filp, const char __user *buff, size_t count, loff_t *offp){  copy_from_user(rdBuf,buff,count);//  rdBuf[count]=0;                  //補字串結束標記  rdFlag=1;                        //標記可讀 poll函數檢測這個標記  wake_up_interruptible(&rdWait);  /*fileops_poll 函數使用了 poll_wait 加入了rdWait等待列隊,執行後fileops_poll會被調用,如果不使用等待列隊                                    fileops_poll只在應用調用select時執行一次 這樣有資料select也不會返回*/  return count;}unsigned int fileops_poll(struct file *filp,poll_table *wait){  /*這裡測試只處理的可讀標記 也可以增加可寫標記*/  int mask=0;  poll_wait(filp,&rdWait,wait); //這個函數不阻塞的,當狀態改變時,應該喚醒列隊這個函數才會重新調用更新新的狀態。  if(rdFlag)   {     mask=POLLIN|POLLRDNORM;  }  return mask; }

編譯後測試結果先運行應用,監聽裝置是否可讀[root@localhost ctest]# ./main 開啟另外一個終端,寫入資料[root@localhost ctest]# echo eeee>/dev/moduledev60[root@localhost ctest]# echo eeee>/dev/moduledev60[root@localhost ctest]# echo eeee>/dev/moduledev60應用判斷到可讀後讀出資料[root@localhost ctest]# ./main read data:eeeeread data:eeeeread data:eeee

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.