新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > arm驅(qū)動linux等待隊列阻塞中斷IO的應(yīng)用

        arm驅(qū)動linux等待隊列阻塞中斷IO的應(yīng)用

        作者: 時間:2016-11-19 來源:網(wǎng)絡(luò) 收藏
        《[arm驅(qū)動]linux等待隊列阻塞中斷IO的應(yīng)用》涉及內(nèi)核驅(qū)動函數(shù)四個,內(nèi)核結(jié)構(gòu)體零個,分析了內(nèi)核驅(qū)動函數(shù)四個;可參考的相關(guān)應(yīng)用程序模板或內(nèi)核驅(qū)動模板一個,可參考的相關(guān)應(yīng)用程序模板或內(nèi)核驅(qū)動一個

        一、概念:
        要休眠進(jìn)程,必須有一個前提:有人能喚醒進(jìn)程,而起這個人必須知道在哪兒能喚醒進(jìn)程,這里,就引入了“等待隊列”這個概念。
        二、應(yīng)用場景:
        等待隊列用來實現(xiàn)進(jìn)程的阻塞,等待隊列可看作保存進(jìn)程的容器,在阻塞進(jìn)程時,將進(jìn)程放入等待隊列,當(dāng)喚醒進(jìn)程時,從等待等列中取出進(jìn)程。進(jìn)程進(jìn)入休眠后必須有個地方能夠喚醒休眠的進(jìn)程;喚醒進(jìn)程的地方最大可能是中斷里面,應(yīng)為硬件資源的獲取的同時往往伴隨著一個中斷。所以在中斷中常常使用等待隊列來休眠進(jìn)程,將cpu資源讓給其他進(jìn)程,中斷發(fā)生時喚醒進(jìn)程
        三、中斷休眠相關(guān)函數(shù)
        1、生成等待事件的函數(shù)

        本文引用地址:http://www.104case.com/article/201611/318222.htm

        內(nèi)核函數(shù)一)a)函數(shù)wait_event_interruptible(queue,condition)函數(shù)

        wait_event_interruptible(queue,condition) //當(dāng)condition(一個布爾表達(dá)式)為真時,立即返回;
        //否則讓進(jìn)程進(jìn)入TASK_INTERRUPTIBLE的睡眠,并掛在名為queue所指定的等待隊列上。

        內(nèi)核代碼一)b)內(nèi)核代碼

        #define wait_event_interruptible(wq, condition)
        ({
        int __ret = 0;
        if (!(condition))
        __wait_event_interruptible(wq, condition, __ret);
        __ret;
        })

        內(nèi)核函數(shù)二)2、wake_up_interruptible(queue);//喚醒隊列中的名為queue的隊列
        內(nèi)核代碼二)a)內(nèi)核源碼

        #define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL)
        void fastcall __wake_up(wait_queue_head_t *q, unsigned int mode,
        int nr_exclusive, void *key)
        {
        unsigned long flags;
        spin_lock_irqsave(&q->lock, flags);
        __wake_up_common(q, mode, nr_exclusive, 0, key);
        spin_unlock_irqrestore(&q->lock, flags);
        }

        3、定義隊列名為queue的兩種方法
        內(nèi)核函數(shù)三)a)靜態(tài)定義方法: DECLARE_QUEUE_HEAD(name)(常用)
        內(nèi)核代碼三)內(nèi)核代碼

        #define DECLARE_WAIT_QUEUE_HEAD(name) wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
        #define __WAIT_QUEUE_HEAD_INITIALIZER(name) {
        .lock = __SPIN_LOCK_UNLOCKED(name.lock),
        .task_list = { &(name).task_list, &(name).task_list } }

        內(nèi)核函數(shù)四)b)動態(tài)定義方法:

        wait_queue_head_t my_queue;
        init_waitqueue_head(&my_queue);

        內(nèi)代碼四)內(nèi)核代碼

        init_waitqueue_head(&my_queue)的內(nèi)核代碼
        void init_waitqueue_head(wait_queue_head_t *q)
        {
        spin_lock_init(&q->lock);
        INIT_LIST_HEAD(&q->task_list);
        }

        三、等待隊列代碼使用參考模板

        模板一)

        staticDECLARE_WAIT_QUEUE_HEAD(queue);
        staticintflag =0;
        staticirqreturn_t irq_handle(intirq, void*dev__id){
        //printk("irq = %dn", irq);
        //..........其他代碼.............
        flag = 1;
        wake_up_interruptible(&queue);
        returnIRQ_RETVAL(IRQ_HANDLED);//warn:榪斿洖IRQ_HANDLED
        }
        ssize_t XXXXX_read(structfile *filp,char__user *buf,size_tcount,loff_t *pos)
        {
        //pirntk(KERN_DEBUG "process %i (%s) going to sleepn",current->pid,current->comm);
        wait_event_interruptible(queue,flag);//此時進(jìn)程被加入等待隊列,等待中斷發(fā)生
        flag=0;
        //printk(KERN_DEBUG "awoken %i (%s) n",current->pid,current->comm);
        returncount;//這個count變量看自己需要更改
        }



        評論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 弋阳县| 衡南县| 海口市| 绥滨县| 苏尼特左旗| 余江县| 大方县| 乌拉特后旗| 濮阳市| 武鸣县| 洛南县| 开化县| 十堰市| 榕江县| 江川县| 高清| 车致| 夏河县| 连平县| 綦江县| 磐安县| 朝阳县| 巴里| 米易县| 铅山县| 屯门区| 连州市| 邢台县| 阆中市| 朝阳市| 凯里市| 大石桥市| 南川市| 杂多县| 长汀县| 靖远县| 泰安市| 雅安市| 德昌县| 万山特区| 若尔盖县|