zoukankan      html  css  js  c++  java
  • 等待队列和内核线程 在触摸屏代码中的应用

    相关的头文件




    #include "tpd.h"

    #include <linux/interrupt.h>
    #include <cust_eint.h>
    #include <linux/i2c.h>
    #include <linux/sched.h>
    #include <linux/kthread.h>
    #include <linux/rtpm_prio.h>
    #include <linux/wait.h>
    #include <linux/time.h>
    #include <linux/delay.h>


    #include "tpd_custom_ft5206.h"




    #include "cust_gpio_usage.h"


     
     
    extern struct tpd_device *tpd;
     
    struct i2c_client *i2c_client = NULL;
    struct task_struct *thread = NULL;
     

    static DECLARE_WAIT_QUEUE_HEAD(waiter);  //定义等待队列头



     
    static int touch_event_handler(void *unused)
     {
      
        struct touch_info cinfo, pinfo;
    
    	 struct sched_param param = { .sched_priority = RTPM_PRIO_TPD };
    	 sched_setscheduler(current, SCHED_RR, ¶m);
     
    	 do
    	 {
    	  mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM); 
    		 set_current_state(TASK_INTERRUPTIBLE); //设置当前进程状态为 可中断睡眠
    		  wait_event_interruptible(waiter,tpd_flag!=0);// 把进程加入到waiter的等待队列上面睡觉去,然后等待tpd_flag=1 发生
    						 
    			 tpd_flag = 0;//如果发生 重置tpd_flag
    
    			 
    		 set_current_state(TASK_RUNNING);//让进程进去运行态
    		 
    
    		  if (tpd_touchinfo(&cinfo, &pinfo)) {
    		  TPD_DEBUG("point_num = %d\n",point_num);
    		  
                if(point_num >0) {
                    tpd_down(cinfo.x[0], cinfo.y[0], 1);
                 if(point_num>1)
                 	{
    			 	tpd_down(cinfo.x[1], cinfo.y[1], 1);
    			   if(point_num >2) tpd_down(cinfo.x[2], cinfo.y[2], 1);
                 	}
                    input_sync(tpd->dev);
    				TPD_DEBUG("press --->\n");
    				
                } else  {
                TPD_DEBUG("release --->\n"); 
                    input_mt_sync(tpd->dev);
                    input_sync(tpd->dev);
                }
            }
    
     }while(!kthread_should_stop());
     
    	 return 0;
     }

    static void tpd_eint_interrupt_handler(void)// 中断处理函数
     {
    	 TPD_DEBUG("TPD interrupt has been triggered\n");
    	 tpd_flag = 1;//设置上面内核线程等待条件
    	 wake_up_interruptible(&waiter);//唤醒在waiter上面睡觉的进程,
    	 
     }
     static int __devinit tpd_probe(struct i2c_client *client, const struct i2c_device_id *id)
     {	 
    	int retval = TPD_OK;
    	char data;
    	i2c_client = client;
    
    	#ifdef TPD_CLOSE_POWER_IN_SLEEP	 
    	hwPowerDown(TPD_POWER_SOURCE,"TP");
    	hwPowerOn(TPD_POWER_SOURCE,VOL_3300,"TP");
    	msleep(100);
    	#else
    	mt_set_gpio_mode(GPIO_CTP_EN_PIN, GPIO_CTP_EN_PIN_M_GPIO);
        mt_set_gpio_dir(GPIO_CTP_EN_PIN, GPIO_DIR_OUT);
    	mt_set_gpio_out(GPIO_CTP_EN_PIN, GPIO_OUT_ONE);
    	msleep(100);
    	mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);
        mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);
        mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE);
    	#endif
    
    	mt_set_gpio_mode(GPIO_CTP_EINT_PIN, GPIO_CTP_EINT_PIN_M_EINT);
        mt_set_gpio_dir(GPIO_CTP_EINT_PIN, GPIO_DIR_IN);
        mt_set_gpio_pull_enable(GPIO_CTP_EINT_PIN, GPIO_PULL_ENABLE);
        mt_set_gpio_pull_select(GPIO_CTP_EINT_PIN, GPIO_PULL_UP);
     
    	  mt65xx_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_SENSITIVE);
    	  mt65xx_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);
    	  mt65xx_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_EN, CUST_EINT_TOUCH_PANEL_POLARITY, tpd_eint_interrupt_handler, 1); // 注册中断号 中断处理程序
    	  mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
     

    从下面的注释我们可以看出,
    wait_event_interruptible_timeout(wq, condition, timeout)
    检查条件是在执行了
    wake_up() 或者变体函数看下面的函数,一旦中断发生,这个中断处理函数就要执行,唤醒等待队列中上的进程,然后才会执行这个函数
    wait_event_interruptible(waiter,tpd_flag!=0);,所以有些朋友说,发生中断了,怎么我的进程没有唤醒呢? 答案就是你没执行wake_up()这个操作。

    
    
     static void tpd_eint_interrupt_handler(void)
    {
    	TPD_DEBUG("TPD interrupt has been triggered\n");
    	tpd_flag = 1;
    	wake_up_interruptible(&waiter);
    }

     
    /**
     * wait_event_interruptible_timeout - sleep until a condition gets true or a timeout elapses
     * @wq: the waitqueue to wait on
     * @condition: a C expression for the event to wait for
     * @timeout: timeout, in jiffies
     *
     * The process is put to sleep (TASK_INTERRUPTIBLE) until the
     * @condition evaluates to true or a signal is received.
     * The @condition is checked each time the waitqueue @wq is woken up.
     *
     * wake_up() has to be called after changing any variable that could
     * change the result of the wait condition.
     *
     * The function returns 0 if the @timeout elapsed, -ERESTARTSYS if it
     * was interrupted by a signal, and the remaining jiffies otherwise
     * if the condition evaluated to true before the timeout elapsed.
     */
    #define wait_event_interruptible_timeout(wq, condition, timeout)	\
    ({									\
    	long __ret = timeout;						\
    	if (!(condition))						\
    		__wait_event_interruptible_timeout(wq, condition, __ret); \
    	__ret;								\
    })
    
    #define __wait_event_interruptible_exclusive(wq, condition, ret)	\
    do {									\
    	DEFINE_WAIT(__wait);						\
    									\
    	for (;;) {							\
    		prepare_to_wait_exclusive(&wq, &__wait,			\
    					TASK_INTERRUPTIBLE);		\
    		if (condition) {					\
    			finish_wait(&wq, &__wait);			\
    			break;						\
    		}							\
    		if (!signal_pending(current)) {				\
    			schedule();					\
    			continue;					\
    		}							\
    		ret = -ERESTARTSYS;					\
    		abort_exclusive_wait(&wq, &__wait, 			\
    				TASK_INTERRUPTIBLE, NULL);		\
    		break;							\
    	}								\
    } while (0)
    

  • 相关阅读:
    C# Dapper 2.0源码
    C#实现隐藏手机号、邮箱、姓名等敏感信息扩展方法
    C# 自定义弹窗提醒
    用sqlyog 连 mysql 8 时,报错:plugin caching_sha2_password could not be loaded
    汇总最全的C#.NET(数据库/.net/其它)面试题及参考答案
    安装sql2008r2后,数据库引擎为空是为什么?
    SQL Server 2008找不到SQL Server配置管理器的问题
    PrintDialog.ShowDialog不能显示打印对话框
    PrintDialog控件
    PrintPreviewControl控件
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124206.html
Copyright © 2011-2022 走看看