globalfifo 驅動例項(工作佇列)

2021-05-26 15:15:29 字數 3959 閱讀 4253

#define globalfifo_size 0x1000 /*全域性fifo最大4k位元組*/

#define fifo_clear 0x1  /*清0全域性記憶體的長度*/

#define globalfifo_major 200    /*預設的globalfifo的主裝置號*/

static int globalfifo_major = globalfifo_major;

module_param(globalfifo_major, int, s_irugo|s_iwugo);

module_parm_desc(globalfifo_major,"globalfifo major number");

/*globalfifo裝置結構體*/

struct globalfifo_dev                                    

;struct globalfifo_dev *globalfifo_devp; /*裝置結構體指標*/

/*檔案開啟函式*/

int globalfifo_open(struct inode *inode, struct file *filp)

/*檔案釋放函式*/

int globalfifo_release(struct inode *inode, struct file *filp)

/* ioctl裝置控制函式 */

static int globalfifo_ioctl(struct inode *inodep, struct file *filp, unsigned

int cmd, unsigned long arg)

return 0;

}static unsigned int globalfifo_poll(struct file *filp, poll_table *wait)

/*fifo非滿*/

if (dev->current_len != globalfifo_size)

up(&dev->sem);

return mask;

}/*globalfifo讀函式*/

static ssize_t globalfifo_read(struct file *filp, char __user *buf, size_t count,

loff_t *ppos)

__set_current_state(task_interruptible); //改變程序狀態為睡眠

up(&dev->sem);

schedule(); //排程其他程序執行

if (signal_pending(current))

//如果是因為訊號喚醒

down(&dev->sem);

}/* 拷貝到使用者空間 */

if (count > dev->current_len)

count = dev->current_len;

if (copy_to_user(buf, dev->mem, count))

else

out: up(&dev->sem); //釋放訊號量

out2:remove_wait_queue(&dev->w_wait, &wait); //從附屬的等待佇列頭移除

set_current_state(task_running);

return ret;

}/*globalfifo寫操作*/

static ssize_t globalfifo_write(struct file *filp, const char __user *buf,

size_t count, loff_t *ppos)

__set_current_state(task_interruptible); //改變程序狀態為睡眠

up(&dev->sem);

schedule(); //排程其他程序執行

if (signal_pending(current))

//如果是因為訊號喚醒

down(&dev->sem); //獲得訊號量

}/*從使用者空間拷貝到核心空間*/

if (count > globalfifo_size - dev->current_len)

count = globalfifo_size - dev->current_len;

if (copy_from_user(dev->mem + dev->current_len, buf, count))

else

//tasklet_schedule(&dev->tlet);

schedule_work(&dev->my_wq);//排程工作佇列執行

printk("in write jiffies=%d\n",jiffies);

out: up(&dev->sem); //釋放訊號量

out2:remove_wait_queue(&dev->w_wait, &wait); //從附屬的等待佇列頭移除

set_current_state(task_running);

return ret;

}/*檔案操作結構體*/

static const struct file_operations globalfifo_fops =

;/*初始化並註冊cdev*/

static void globalfifo_setup_cdev(struct globalfifo_dev *dev, int index)

/*void jit_tasklet_fn(unsigned long arg)

*/void my_do_work(unsigned long arg)//定義乙個處理函式

/*裝置驅動模組載入函式*/

int globalfifo_init(void)

if (ret < 0)

return ret;

/* 動態申請裝置結構體的記憶體*/

globalfifo_devp = kmalloc(sizeof(struct globalfifo_dev), gfp_kernel);

if (!globalfifo_devp)    /*申請失敗*/

memset(globalfifo_devp, 0, sizeof(struct globalfifo_dev));

globalfifo_setup_cdev(globalfifo_devp, 0);

init_mutex(&globalfifo_devp->sem);   /*初始化訊號量*/

init_waitqueue_head(&globalfifo_devp->r_wait); /*初始化讀等待佇列頭*/

init_waitqueue_head(&globalfifo_devp->w_wait); /*初始化寫等待佇列頭*/

/* register the tasklet */

// tasklet_init(&globalfifo_devp->tlet, jit_tasklet_fn, (unsigned long)globalfifo_devp);

//初始化工作佇列並將其與處理函式繫結

//init_work(&(globalfifo_devp->my_wq),my_do_work);//for 2.6.20

init_work(&(globalfifo_devp->my_wq),my_do_work,(unsigned long)globalfifo_devp);//for 2.6.14

return 0;

fail_malloc: unregister_chrdev_region(devno, 1);

return ret;

}/*模組解除安裝函式*/

void globalfifo_exit(void)

module_author("song baohua");

module_license("dual bsd/gpl");

module_init(globalfifo_init);

module_exit(globalfifo_exit);

globalfifo驅動例項(poll機制)

阻塞操作是指在執行裝置操作時若不能獲得資源則掛起程序,直到滿足可操作的條件後在進行操作。非阻塞操作的程序在不能進行裝置操作時並不掛起,它或者被放棄,或者不停的查詢,直到可以進行操作為止 喚醒程序的地方最大可能發生在中斷裡面,因為硬體資源獲得的同時往往伴隨著乙個中斷 在使用者程式中,select 和p...

支援非同步通知的globalfifo驅動

驅動程式執行在核心空間中,應用程式執行在使用者空間中,兩者是不能直接通訊的。但在實際應用中,在裝置已經準備好的時候,我們希望通知使用者程式裝置已經ok,使用者程式可以讀取了,這樣應用程式就不需要一直查詢該裝置的狀態,從而節約了資源,這就是非同步通知。好,那下乙個問題就來了,這個過程如何實現呢?簡單,...

驅動篇 支援輪詢操作的 globalfifo 驅動

1.globalfifo 驅動中增加輪詢操作 在 globalfifo 的 poll 函式中,首先將裝置結構體中的 r wait 和 w wait 等待佇列頭新增到等待列表,然後通過判斷 dev current len 是否等於 0 來獲得裝置的可讀狀態,通過判斷 dev current len 是...