如果有中斷關閉就要在程序執行完畢后打開中斷,如果邏輯出錯,會報如下錯誤: WARNING:at /sda1/yzhao-work-1/QC706EU-S/msm8916_1605_444/kernel/kernel/irq/manage.c:529 irq_set_irq_wake+0x88/0xe8() [ 8518.783716] —[ end trace 35ae10e4ba3033e2 ]— 一般是申請和釋放資源不匹配。
下面解決第二個bug,快速雙擊喚醒,長按不喚醒,這個可以有不同的邏輯實現,以下是我的邏輯,不正確的地方希望指出: 首先要熟悉上報坐標的流程,這里截取有用的一段進行分析,中斷的下半部函數為,gsl_ts_xy_worker,其中有process_gslX680_data處理坐標點,和上報坐標點。 gsl屏幕支持多點觸控,一次按下時把多個點的坐標值經過record_point計算成為一個點,后用report_data上報。函數中,有三個重要的變量,之前一直忽視了,卻起到了區分快速雙擊和長按的作用:cinfo.finger_num----->記錄按下的手指數id_state_old_flag[i]----->記錄上一次按下的狀態,是數組,按下為1,抬起為0id_state_flag[i]----->記錄此次按下的狀態,是數組,沒按為0,按下為1下面是這個函數的大致代碼,和加入的代碼,之后再分析區分思路static void process_gslX680_data(struct gsl_ts *ts){ int result = 0; //加入代碼,用于計算時間間隔,大于80個時鐘周期,兩次觸摸時間過長,level=0... record_point(x, y , id); //計算x和y report_data(ts, x_new, y_new, 200, id); //上報... //打印調試 pr_err("xhlin^le=%d cinfo.finger_num=%d, id_state_old_flag[i]=%d, id_state_flag[i]=%d,id_sign[i]=%d; /n",level,cinfo.finger_num,id_state_old_flag[1],id_state_flag[1],id_sign[1]);... if(flag == 1) //flag==1 進入休眠,準備喚醒 { result = jiffies - old; //計算兩次按下時間間隔 if(result > 80) //判斷時間間隔,大于80,說明兩次按下時間間隔長,level為0 level = 0; switch(level) { case 0: //第一階段 if((cinfo.finger_num == 1) && (id_sign[1] <= 8 )) { level = 1; //cinfo.finger_num == 1說明有一個手指頭按下,但是可能沒有抬起 old = jiffies; //記錄下第一次按下的時間 } break; case 1: //第二階段 if((cinfo.finger_num == 0) && (id_sign[1] ==0 )) level = 2; //在level為1的基礎上,cinfo.finger_num == 0說明有手指頭抬起,但是可能沒有按下第二次 break; case 2://第三階段 if((cinfo.finger_num == 1) && (id_sign[1] <= 8 )) level = 3; //在level為2的基礎上,cinfo.finger_num再次為1,說明有手指頭又按下,完成一次雙擊觸摸 break; } if(level == 3) //level為3時候,說明完成一次雙擊觸摸,可以喚醒系統 { level = 0; open_lcd(ts); //喚醒系統 } }...}//喚醒系統void open_lcd(struct gsl_ts *ts){ gsl_halt_flag = 0; flag = 0; old = 0; input_report_key(ts->input,KEY_POWER, 1); //power鍵按下 input_sync(ts->input); input_report_key(ts->input,KEY_POWER, 0); //power鍵抬起 input_sync(ts->input); }//一些全局變量static unsigned long old = 0;extern unsigned long volatile jiffies;static int level = 0;static int gsl_halt_flag;static int flag;思路: 調試的時候,根據log:pr_err(“xhlin^le=%d cinfo.finger_num=%d, id_state_old_flag[1]=%d, id_state_flag[1]=%d,id_sign[1]=%d; /n”,level,cinfo.finger_num,id_state_old_flag[1],id_state_flag[1],id_sign[1]); 發現快速雙擊的時候,cinfo.finger_num會由1,變為0,再變為1 長按的時候,cinfo.finger_num一直為1,且id_sign[1]的值不間斷變大
快速雙擊log
長按log 所以以此區別,來實現雙擊喚醒,每次喚醒后,和每次無效雙擊后,要把level清0
新聞熱點
疑難解答