新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > Linux驅(qū)動總結3

        Linux驅(qū)動總結3

        作者: 時間:2016-12-01 來源:網(wǎng)絡 收藏
        3、確定一個具體的條件,比如數(shù)據(jù)有無,具體的條件根據(jù)實際的情況設計。
        /*等待條件*/
        static bool havedata = false;
        4、在需要堵塞的讀函數(shù),寫函數(shù)中分別實現(xiàn)堵塞,首先定義等待隊列的節(jié)點,并添加到隊列中去,然后等待事件的喚醒進程。但是由于讀寫操作的兩個等待隊列都是基于條件havedata的,所以在讀完成以后需要喚醒寫,寫完成以后需要喚醒讀操作,同時更新條件havedata,最后還要移除添加的等待隊列節(jié)點。
        /*read函數(shù)的實現(xiàn)*/
        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;
        /*參數(shù)的檢查,首先判斷文件位置*/
        if(p >= MEMDEV_SIZE)
        return 0;
        /*改正文件大小*/
        if(count > MEMDEV_SIZE - p)
        count = MEMDEV_SIZE - p;
        #if 0
        /*添加一個等待隊列節(jié)點到當前進程中*/
        DECLARE_WAITQUEUE(wait_r,current);
        /*將節(jié)點添加到等待隊列中*/
        add_wait_queue(&dev->rdqueue,&wait_r);
        /*添加等待隊列,本來采用if即可,但是由于信號等可能導致等待隊列的喚醒,因此采用循環(huán),確保不會出現(xiàn)誤判*/
        #endif
        while(!havedata)
        {
        /*判斷用戶是否設置為非堵塞模式讀,告訴用戶再讀*/
        if(filp->f_flags & O_NONBLOCK)
        return -EAGAIN;
        /*依據(jù)條件havedata判斷隊列的狀態(tài),防止進程被信號喚醒*/
        wait_event_interruptible(dev->rdqueue,havedata);
        }
        spin_lock(&dev->lock);
        /*從內(nèi)核讀數(shù)據(jù)到用戶空間,實質(zhì)就通過private_data訪問設備*/
        if(copy_to_user(buf,(void *)(dev->data p),count))
        {
        /*出錯誤*/
        ret = -EFAULT;
        }
        else
        {
        /*移動當前文件光標的位置*/
        *ppos = count;
        ret = count;
        printk(KERN_INFO "read %d bytes(s) from %d",count,p);
        }
        spin_unlock(&dev->lock);
        #if 0
        /*將等待隊列節(jié)點從讀等待隊列中移除*/
        remove_wait_queue(&dev->rdqueue,&wait_r);
        #endif
        /*更新條件havedate*/
        havedata = false;
        /*喚醒寫等待隊列*/
        wake_up_interruptible(&dev->wrqueue);
        return ret;
        }
        /*write函數(shù)的實現(xiàn)*/
        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;
        /*檢查參數(shù)的長度*/
        if(p >= MEMDEV_SIZE)
        return 0;
        if(count > MEMDEV_SIZE - p)
        count = MEMDEV_SIZE - p;
        #if 0
        /*定義并初始化一個等待隊列節(jié)點,添加到當前進程中*/
        DECLARE_WAITQUEUE(wait_w,current);
        /*將等待隊列節(jié)點添加到等待隊列中*/
        add_wait_queue(&dev->wrqueue,&wait_w);
        #endif
        /*添加寫堵塞判斷*/
        /*為何采用循環(huán)是為了防止信號等其他原因?qū)е聠拘?/
        while(havedata)
        {
        /*如果是以非堵塞方式*/
        if(filp->f_flags & O_NONBLOCK)
        return -EAGAIN;
        /*分析源碼發(fā)現(xiàn),wait_event_interruptible 中存在DECLARE_WAITQUEUE和add_wait_queue的操作,因此不需要手動添加等待隊列節(jié)點*/
        wait_event_interruptible(&dev->wrqueue,(!havedata));
        }
        spin_lock(&dev->lock);
        if(copy_from_user(dev->data p,buf,count))
        ret = -EFAULT;
        else
        {
        /*改變文件位置*/
        *ppos = count;
        ret = count;
        printk(KERN_INFO "writted %d bytes(s) from %d",count,p);
        }
        spin_unlock(&dev->lock);
        #if 0
        /*將該等待節(jié)點移除*/
        remove_wait_queue(&dev->wrqueue,&wait_w);
        #endif
        /*更新條件*/
        havedata = true;
        /*喚醒讀等待隊列*/
        wake_up_interruptible(&dev->rdqueue);
        return ret;
        }
        5、應用程序采用兩個不同的進程分別進行讀、寫,然后檢測順序是否可以調(diào)換,檢查等待是否正常。
        上一頁 1 2 3 下一頁

        關鍵詞: Linux驅(qū)動總

        評論


        技術專區(qū)

        關閉
        主站蜘蛛池模板: 辉南县| 奈曼旗| 玉田县| 广水市| 永城市| 长乐市| 绵竹市| 高雄市| 梨树县| 高碑店市| 郯城县| 洪江市| 东乡县| 九江市| 长海县| 敖汉旗| 民乐县| 榆林市| 黄冈市| 奉贤区| 左云县| 平利县| 通城县| 鹿泉市| 长沙市| 特克斯县| 梅州市| 普洱| 胶州市| 察隅县| 虎林市| 伊川县| 灵台县| 阳高县| 松阳县| 宁波市| 宿迁市| 固阳县| 化德县| 南涧| 子长县|