和菜鳥一起學linux之input系統簡單一實例

來源:互聯網
上載者:User

      
三伏天說來就來了,比起去年,今年的夏天沒熱得那麼不可思議了。也許真正的炎熱還沒有到來。任時光匆匆而過,也沒得到自己想要的生活,覺得有點得過且過的樣子。需要換位思考,需要領悟人生的真諦,需要去追求自己想要的。覺得,孟非老師說的一句話很實在,工作再努力,提早完成了之後,能得到什麼呢?只會換來領導的一句話,恩,不錯,那個,那個這些事你也做一下吧。哈哈,的確如此,所以何不善待自己呢?做自己喜歡的事,而不是一味的工作,工作中雖然可以學到東西,但是,不可能只學一樣啊,那樣如果你想換換生活,換換工作,你又能做些什麼呢?努力是需要的,我有我的夢想,我的未來,我的一切,合理安排時間,而不是把生活全部都放在了工作中,那樣,豈不毀了一生,直待老去之後就只能慢慢懊悔,究竟得到了什麼。。。。。。。。

       閑話講了太多了,接下來還是迴歸正題吧。話說剛開始接觸linux驅動時就是從char裝置開始的,然後接著又把那個char裝置改寫為input裝置了,從中也開始對於linux裝置驅動編程入了個小門了接著就把那個代碼貼一下,用以以後可以記起。

 

具體的代碼含義都加了注釋了:

 

#include <linux/slab.h>#include <linux/irq.h>#include <linux/interrupt.h>#include <linux/poll.h>#include <asm/io.h>#include <linux/delay.h>#include <linux/module.h>#include <linux/time.h>#include <linux/gpio.h>#include <linux/wait.h>#include <linux/input.h>#include <linux/init.h> static gpio_base = 96;       //gpio的基址,看不同的平台而定的。static pow_btn = 18;        //按鍵的中斷號,也是依賴於平台的 struct input_dev *btn_dev;      //input裝置的結構體,這裡定義了btn_devstruct delayed_work btn_work;    //這個是工作隊列,用於讓中斷處理常式在中斷後半部分 static irqreturn_t power_isr(int irq, void *dev_id);  //中斷入口函數 static int __init button_init(void);         static void __exit button_exit(void); static void power_work_fn(struct work_struct *work)        //中斷下半部分處理,即工作隊列中處理{    struct timeval tm_p, tm_n;    unsigned char flag = 1;    unsigned int width = 0;        if(gpio_get_value(power)) return;           do_gettimeofday(&tm_p);        //取當前的時間    while(!gpio_get_value(pow_btn))   //判斷按鍵是否彈起    {       if(!flag) continue;              do_gettimeofday(&tm_n);        //再取間        width = 1000000 * (tm_n.tv_sec - tm_p.tv_sec)    //計算兩次的時間差,就是按鍵一直沒彈起                 + tm_n.tv_usec - tm_p.tv_usec;       if(width >= 1500000)   //自己定義的超過了1.5s就上報一次,       {           input_report_key(btn_dev, KEY_POWER, 0);  //上報按索引值           input_report_key(btn_dev, KEY_POWER, 1);              input_sync(btn_dev);           flag =0;       }    }        if(flag)    {       input_report_key(btn_dev, KEY_POWER, 1);        input_report_key(btn_dev, KEY_POWER, 0);       input_sync(btn_dev);    }} static irqreturn_t power_isr(int irq, void *dev_id)     //中斷處理函數{    schedule_delayed_work(&power_work, 0);      //把中斷函數放在工作隊列裡去做了    return IRQ_HANDLED;} static int __init button_init(void){    int error;    gpio_request(pow_btn, "power-gpio");      //初始化申請gpio    gpio_direction_input(pow_btn);            //設定gpio口為輸入     //申請中斷    if(reques_irq(gpio_base+pow_btn, power_isr, IRQ_DISABLED, "my_power", NULL) != 0)    {       printk(KERN_ERR "my_power: can't allocate irq %d\n", pow_btn);        return (-EIO);    }         //分配input裝置    btn_dev = input_allocate_device();    if(!btn_dev)    {       printk(KERN_ERR "button: not enough memory\n");        error = -ENOMEM;        goto err_free_irq;    }        //把相應的按鍵給置上    btn_dev->evbit[0] = BIT_MASK(EV_KEY);    btn_dev->keybit[BIT_WORK(KEY_POWER)] |= BIT_MASK(KEY_POWER);        //註冊input裝置    error = input_register_device(btn_dev);    if(error)    {       printk(KERN_ERR "button: failed to register device\n");        goto err_free_dev;    }           //初始化工作隊列    INIT_DELAYED_WORK(&power_work, power_work_fn);     printk("$$$$$$$my_power button register ok\n");    return 0; err_free_dev:    input_free_device(btn_dev); err_free_irq:    free_irq(gpio_base+pow_btn, power_isr);     return error;    } static void __exit button_exit(void){    input_free_device(btn_dev);    free_irq(gpio_base+pow_btn, power_isr);} module_init(button_init);module_exit(button_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("eastmoon"); 

 

 

        好了,這就是一個按鍵的裝置驅動了,其中用到了很多知識了,像中斷啊,input裝置啊,工作隊列啊,時間的擷取啊。GPIO的使用啊。分析好了這個驅動,下面貼個應用程式層的調用。總不能只有個驅動,而沒法測試吧。

 

 

 

#include <stdio.h>#include <sys/ioctl.h>#include <unistd.h>#include <fcntl.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/select.h>#include <sys/time.h>#include <linux/input.h> #define DEVICE "/dev/event0" int main(int argc, char *argv[]){    struct input_event btn;    int fd, rev;    unsigned short type;    unsigned short code;    int value;     fd = open(DEVICE, O_RDWR);    if(fd < 0)    {        printf("Open file %s failed!\n", DEVICE);        return -1;    }     while(1)    {     rev = read(fd, &btn, sizeof(struct input_event));        if(rev > 0)        {              type = btn.type;              code = btn.code;              value = btn.value;              printf("type = %d, code = %d, value = %d\n", type, code ,value);        }    }    close(fd);     return 0;} 

    相比知道了上面的驅動程式,應用程式肯定顯得那麼簡單了。就不多做分析了。

   
這個就是最最簡單的input的基本模型了,相信以這個為基礎,其他的input裝置也是大同小異的了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.