久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

新聞中心

EEPW首頁 > 嵌入式系統 > 設計應用 > Linux驅動總結3

Linux驅動總結3

作者: 時間:2016-12-01 來源:網絡 收藏
3、確定一個具體的條件,比如數據有無,具體的條件根據實際的情況設計。
/*等待條件*/
static bool havedata = false;
4、在需要堵塞的讀函數,寫函數中分別實現堵塞,首先定義等待隊列的節點,并添加到隊列中去,然后等待事件的喚醒進程。但是由于讀寫操作的兩個等待隊列都是基于條件havedata的,所以在讀完成以后需要喚醒寫,寫完成以后需要喚醒讀操作,同時更新條件havedata,最后還要移除添加的等待隊列節點。
/*read函數的實現*/
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 0
/*添加一個等待隊列節點到當前進程中*/
DECLARE_WAITQUEUE(wait_r,current);
/*將節點添加到等待隊列中*/
add_wait_queue(&dev->rdqueue,&wait_r);
/*添加等待隊列,本來采用if即可,但是由于信號等可能導致等待隊列的喚醒,因此采用循環,確保不會出現誤判*/
#endif
while(!havedata)
{
/*判斷用戶是否設置為非堵塞模式讀,告訴用戶再讀*/
if(filp->f_flags & O_NONBLOCK)
return -EAGAIN;
/*依據條件havedata判斷隊列的狀態,防止進程被信號喚醒*/
wait_event_interruptible(dev->rdqueue,havedata);
}
spin_lock(&dev->lock);
/*從內核讀數據到用戶空間,實質就通過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
/*將等待隊列節點從讀等待隊列中移除*/
remove_wait_queue(&dev->rdqueue,&wait_r);
#endif
/*更新條件havedate*/
havedata = false;
/*喚醒寫等待隊列*/
wake_up_interruptible(&dev->wrqueue);
return ret;
}
/*write函數的實現*/
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 0
/*定義并初始化一個等待隊列節點,添加到當前進程中*/
DECLARE_WAITQUEUE(wait_w,current);
/*將等待隊列節點添加到等待隊列中*/
add_wait_queue(&dev->wrqueue,&wait_w);
#endif
/*添加寫堵塞判斷*/
/*為何采用循環是為了防止信號等其他原因導致喚醒*/
while(havedata)
{
/*如果是以非堵塞方式*/
if(filp->f_flags & O_NONBLOCK)
return -EAGAIN;
/*分析源碼發現,wait_event_interruptible 中存在DECLARE_WAITQUEUE和add_wait_queue的操作,因此不需要手動添加等待隊列節點*/
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
/*將該等待節點移除*/
remove_wait_queue(&dev->wrqueue,&wait_w);
#endif
/*更新條件*/
havedata = true;
/*喚醒讀等待隊列*/
wake_up_interruptible(&dev->rdqueue);
return ret;
}
5、應用程序采用兩個不同的進程分別進行讀、寫,然后檢測順序是否可以調換,檢查等待是否正常。
上一頁 1 2 3 下一頁

關鍵詞: Linux驅動總

評論


技術專區

關閉