Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 平台電容式觸摸屏的驅動原理

Android 平台電容式觸摸屏的驅動原理

編輯:關於Android編程

硬件工作原理

觸摸屏的工作原理概括來說就是上報坐標值,X軸、Y軸的值。所以在 Linux 中是采用 input 子系統來對其進行實現。

本文主要歸納其驅動基本原理 與 Android平台上的移植步驟,並分析總結移植過程中碰到的問題。

驅動基本原理

觸摸屏的驅動部分大概涉及到三個點:

中斷

Linux 內核的中斷處理機制如下:
\
為了在中斷執行時間盡可能短和中斷處理完成大量工作之間找到一個平衡點,Linux將中斷處理程序分解為兩個半部:頂半部(tZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcCBoYWxmo6m6zTxzdHJvbmc+tdew67K/PC9zdHJvbmc+o6hib3R0b20gaGFsZqOpoaM8L3A+DQo8cD48c3Ryb25nPralsOuyvzwvc3Ryb25nPs3qs8m+ob/JxNzJ2bXEsci9z730vLG1xLmmxNyjrMv8zfnN+da7ysc8c3Ryb25nPrzytaW12LbByKG8xLTmxvfW0LXE1tC2z9e0zKw8L3N0cm9uZz6yojxzdHJvbmc+x+Wz/dbQts+x6ta+PC9zdHJvbmc+uvO+zb340NAmbGRxdW87PHN0cm9uZz61x7zH1tC2zzwvc3Ryb25nPiZyZHF1bzu1xLmk1/ehoyZsZHF1bzu1x7zH1tC2zyZyZHF1bzvS4s6218W9q7XXsOuyv7SmwO2zzNDyudK1vbjDyeixuLXEtdew67K/1rTQ0LbTwdDW0MiloaM8YnIgLz4NCtXi0fmjrLalsOuyv9a00NC1xMvZtsi+zbvhuty/7KOsv8nS1Lf+zvG4/LbgtcTW0LbPx+vH86Gjz9bU2qOs1tC2z7SmwO25pNf3tcTW2NDEvs3C5NTawcu117Drsr+1xM23yc+jrMv8wLTN6rPJ1tC2z8rCvP61xL74tPO24Mr9yM7O8aGjPGJyIC8+DQo8c3Ryb25nPrXXsOuyvzwvc3Ryb25nPry4uvXX9sHL1tC2z7SmwO2zzNDyy/nT0LXEysLH6aOstvjH0jxzdHJvbmc+v8nS1LG70MK1xNbQts+08rbPPC9zdHJvbmc+o6zV4tKyyse117Drsr+6zbalsOuyv7XE1+6087K7zayjrNLyzqq2pbDrsr/N+c35sbvJ6LzGs8myu7/J1tC2z6Gjtdew67K/1PLP4LbUwLTLtbKisrvKx7fHs6O99LyxtcSjrLb4x9LP4LbUsci9z7rEyrGjrLK71NrTsrz+1tC2z7f+zvGzzNDy1tDWtNDQoaM8L3A+DQo8cD7X3Lb40dTWrqOsvLQ8c3Ryb25nPtbQts/Sqr6hv8nE3LrEyrGxyL3PtsyjrL6hv+y71ri0z7XNs9X9s6O198rUo6zL+dLUsNHW0LbPtKW3oqGi1tC2z9a00NC31r+qo6zSsr7NysfL+cu1tcQmbGRxdW87yc+w67K/t9ajqNbQts+0pbeio6mhorXXsOuyv6Oo1tC2z9a00NCjqTwvc3Ryb25nPqGjPC9wPg0KPHA+yc+w67K/t9ajqNbQts+0pbeio6mhorXXsOuyv6Oo1tC2z9a00NCjqSC8tCA8c3Ryb25nPtbQts/Jz8/CzsQ8L3N0cm9uZz6hozxiciAvPg0Kz8Kw67K/0ruw49PQIHRhc2tsZXQgus0gd29ya3F1ZXVlIMC0yrXP1qOsPHN0cm9uZz60pcP+xsHKx9PJIHdvcmtxdWV1ZSDAtMq1z9Y8L3N0cm9uZz61xKGjPC9wPg0KPGgzIGlkPQ=="工作隊列">工作隊列

tasklet 工作在軟中斷上下文,工作隊列工作在內核進程。
這種差異的本質原因是,在工作隊列機制中,將推後的工作交給一個稱之為工作者線程(worker thread)的內核線程去完成(單核下一般會交給默認的線程events/0)。因此,在該機制中,當內核在執行中斷的剩余工作時就處在進程上下文(process context)中。也就是說由工作隊列所執行的中斷代碼會表現出進程的一些特性,最典型的就是可以重新調度甚至睡眠。
對於tasklet機制(中斷處理程序也是如此),內核在執行時處於中斷上下文(interrupt context)中。而中斷上下文與進程毫無瓜葛,所以在中斷上下文中就不能睡眠。
因此,選擇tasklet還是工作隊列來完成下半部分應該不難選擇。當推後的那部分中斷程序需要睡眠時,工作隊列毫無疑問是你的最佳選擇;否則,還是用tasklet吧。

中斷上下文

同類的概念:進程上下文:一般的進程運行在用戶態,如果這個進程進行了系統調用,那麼此時用戶空間中的程序就進入了內核空間,並且稱內核代表該進程運行於內核空間中。由於用戶空間和內核空間具有不同的地址映射,並且用戶空間的進程要傳遞很多變量、參數給內核,內核也要保存用戶進程的一些寄存器、變量等,以便系統調用結束後回到用戶空間繼續執行。這樣就產生了進程上下文。

進程上下文實際上是指,一個進程在執行的時候,CPU的所有寄存器中的值、進程的狀態以及堆棧中的內容

工作隊列的使用方法

1.采用 struct work_struct 定義一個工作隊列。

struct work_struct my_wq;

2.定義一個處理函數

void my_wq_func(strcut work_struct *work);

3.初始化工作隊列並綁定處理函數

INIT_WORK(&my_wq,my_wq_func);

4.調度工作隊列執行函數

schedule_work(&my_wq);

代碼示例

/* 定義工作隊列和相關函數 */
struct work_struct xxx_wq;
void xxx_do_work(struct work_struct *work);

/* 底半部執行函數 */
void xxx_do_work(struct work_struct *work)
{
    ...
}

/* 頂半部執行函數 */
irqreturn_t xxx_interrupt(int irq, void *dev_id)
{
    ...
    schedule_work(&xxx_wq);
    ...
    return IRQ_HANDLED;
}

/* 設備驅動模塊加載函數 */
int xxx_init(void)
{
    ...
    /* 申請中斷 */
    result = request_irq(xxx_irq, xxx_interrupt, 0 ,"xxx", NULL);
    ...
    INIT_WORK(&xxx_wq, xxx_do_work);
    ...
}

/* 設備驅動模塊卸載函數 */
void xxx_exit(void)
{
    ...
    /* 釋放中斷 */
    free_irq(xxx_irq, xxx_interrupt);
    ...
}

input 子系統

輸入子系統是由輸入子系統設備驅動層輸入子系統核心層(InputCore)和輸入子系統事件處理層(Event Handler)組成。
設備驅動層提供對硬件各寄存器的讀寫訪問和將底層硬件對用戶輸入訪問的響應轉換為標准的輸入事件,再通過核心層提交給事件處理層;
核心層對下提供了設備驅動層的編程接口,對上又提供了事件處理層的編程接口;
事件處理層就為我們用戶空間的應用程序提供了統一訪問設備的接口和驅動層提交來的事件處理。
\

輸入子系統與驅動的關系

input 子系統驅動層實現原理

Input 設備用 input_dev 結構體描述,定義在 input.h 中。
需要按照如下步驟實現:
1. 驅動模塊加載函數中設置input設備支持input子系統的數據;
2.將 input 設備注冊到 input 子系統中;
3.在 input 設備發生輸入操作時,提交發生事件所對應的鍵值/坐標狀態。

EV_SYN     0x00     同步事件  
EV_KEY     0x01     按鍵事件  
EV_REL     0x02     相對坐標(如:鼠標移動,報告的是相對最後一次位置的偏移)  
EV_ABS     0x03     絕對坐標(如:觸摸屏和操作桿,報告的是絕對的坐標位置)  
EV_MSC     0x04     其它  
EV_LED     0x11     LED  
EV_SND     0x12     聲音  
EV_REP     0x14     Repeat  
EV_FF      0x15     力反饋  

//用於提交較常用的事件類型給輸入子系統的函數有:
void input_report_key(struct input_dev *dev, unsigned int code, int value); //提交按鍵事件的函數  
void input_report_rel(struct input_dev *dev, unsigned int code, int value); //提交相對坐標事件的函數  
void input_report_abs(struct input_dev *dev, unsigned int code, int value); //提交絕對坐標事件的函數  
//在提交輸入設備的事件後必須用下列方法使事件同步,讓它告知input系統,設備驅動已經發出了一個完整的報告:  
void input_sync(struct input_dev *dev)  

Linux 與 Android 的多點觸摸協議

Linux & Android 多點觸摸協議

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved