新聞中心

        EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > S5PV210(TQ210)學(xué)習(xí)筆記——按鍵驅(qū)動(dòng)程序

        S5PV210(TQ210)學(xué)習(xí)筆記——按鍵驅(qū)動(dòng)程序

        作者: 時(shí)間:2016-11-28 來(lái)源:網(wǎng)絡(luò) 收藏
      1. init_waitqueue_head(&button_waitq);
      2. return0;
      3. device_error:
      4. class_destroy(buttons_class);
      5. class_error:
      6. cdev_del(&cdev);
      7. add_error:
      8. unregister_chrdev_region(devno,1);
      9. return-ENODEV;
      10. }
      11. voidbuttons_exit(void){
      12. device_destroy(buttons_class,devno);
      13. class_destroy(buttons_class);
      14. cdev_del(&cdev);
      15. unregister_chrdev_region(devno,1);
      16. }
      17. module_init(buttons_init);
      18. module_exit(buttons_exit);
      19. MODULE_LICENSE("GPL");
      20. 測(cè)試程序代碼:

        本文引用地址:http://www.104case.com/article/201611/322807.htm
        1. #include
        2. #include
        3. intmain(){
        4. intfd=open("/dev/buttons",O_RDWR);
        5. if(fd<0){
        6. printf("openerror");;
        7. return0;
        8. }
        9. unsignedcharkey;
        10. while(1){
        11. read(fd,&key,1);
        12. printf("Thekey=%x",key);
        13. }
        14. close(fd);
        15. }

        相比輪詢(xún)方式的按鍵驅(qū)動(dòng)程序,中斷方式編寫(xiě)的按鍵驅(qū)動(dòng)程序可以很大程度上節(jié)省CPU資源,因此,推薦使用中斷方式。

        二 支持POLL機(jī)制

        上面這種方式實(shí)現(xiàn)的按鍵驅(qū)動(dòng)程序有個(gè)弊端,如果我們不按鍵,應(yīng)用程序?qū)?huì)永遠(yuǎn)阻塞在這里,幸運(yùn)的是,linux內(nèi)核提供了poll機(jī)制,可以設(shè)置超時(shí)等待時(shí)間,如果在這個(gè)時(shí)間內(nèi)讀取到鍵值則正常返回,反之則超時(shí)退出。使內(nèi)核支持poll非常簡(jiǎn)單,為file_operations的poll成員提供poll處理函數(shù)即可。

        使內(nèi)核支持poll還需要以下幾步:

        添加poll頭文件

        1. #include

        編寫(xiě)poll處理函數(shù):

        1. staticunsignedbuttons_poll(structfile*file,poll_table*wait){
        2. unsignedintmask=0;
        3. poll_wait(file,&button_waitq,wait);
        4. if(pressed)
        5. mask|=POLLIN|POLLRDNORM;
        6. returnmask;
        7. }
        將poll處理函數(shù)添加給file_operations:
        1. .poll=buttons_poll,
        這樣,驅(qū)動(dòng)程序就支持poll機(jī)制了。下面是poll方式的測(cè)試程序:
        1. #include
        2. #include
        3. #include
        4. #include
        5. #include
        6. intmain(intargc,char**argv){
        7. intfd;
        8. unsignedcharkey_val;
        9. intret;
        10. structpollfdfds[1];
        11. fd=open("/dev/buttons",O_RDWR);
        12. if(fd<0){
        13. printf("cantopen!");
        14. }
        15. fds[0].fd=fd;
        16. fds[0].events=POLLIN;
        17. while(1){
        18. ret=poll(fds,1,5000);
        19. if(ret==0){
        20. printf("timeout");
        21. }
        22. else{
        23. read(fd,&key_val,1);
        24. printf("key_val=0x%x",key_val);
        25. }
        26. }
        27. return0;
        28. }

        這樣,應(yīng)用程序可以限制時(shí)間,如果在一定時(shí)間內(nèi)讀取不到鍵值就可以做特殊處理,這種思想在網(wǎng)絡(luò)通信中應(yīng)用廣泛。

        三 支持異步機(jī)制

        很多情況下,我們的程序在等待按鍵期間需要處理其它任務(wù)而不是在這里空等,這時(shí),就需要采用異步模式了。所謂異步模式,實(shí)際上是采用消息機(jī)制(以本文的按鍵程序?yàn)槔串?dāng)驅(qū)動(dòng)程序檢測(cè)到按鍵后發(fā)送消息給應(yīng)用程序,應(yīng)用程序接收到消息后再去讀取鍵值。與前面的兩種模式相比,最大的不同在于異步方式是驅(qū)動(dòng)告訴應(yīng)用程序來(lái)讀而不是應(yīng)用程序主動(dòng)去讀。添加異步支持更加簡(jiǎn)單,首先是為file_operations注冊(cè)fasync函數(shù),函數(shù)內(nèi)容如下:

        1. staticintbuttons_fasync(intfd,structfile*file,inton){
        2. returnfasync_helper(fd,file,on,&button_async);
        3. }
        然后再buttons_read函數(shù)中添加一行代碼,修改后的代碼如下:
        1. staticssize_tbuttons_read(structfile*file,char__user*data,size_tcount,loff_t*loff){
        2. if(count!=1){
        3. printk(KERN_ERR"Thedrivercanonlygiveonekeyvalueonce!");
        4. return-ENOMEM;
        5. }
        6. wait_event_interruptible(button_waitq,pressed);
        7. pressed=0;
        8. if(copy_to_user(data,&key_val,1)){
        9. printk(KERN_ERR"Thedrivercannotcopythedatatouserarea!");
        10. return-ENOMEM;
        11. }
        12. return0;
        13. }
        這樣,驅(qū)動(dòng)程序就支持異步獲取鍵值了,為了測(cè)試效果,測(cè)試程序也需要修改,代碼如下:
        1. #include
        2. #include
        3. #include
        4. #include
        5. #include
        6. #include
        7. #include
        8. /*sixthdrvtest
        9. */
        10. intfd;
        11. voidmy_signal_fun(intsignum)
        12. {
        13. unsignedcharkey_val;
        14. read(fd,&key_val,1);
        15. printf("key_val:0x%x",key_val);
        16. }
        17. intmain(intargc,char**argv)
        18. {
        19. unsignedcharkey_val;
        20. intret;
        21. intOflags;
        22. signal(SIGIO,my_signal_fun);
        23. fd=open("/dev/buttons",O_RDWR|O_NONBLOCK);
        24. if(fd<0){
        25. printf("cantopen!");
        26. return-1;
        27. }
        28. fcntl(fd,F_SETOWN,getpid());
        29. Oflags=fcntl(fd,F_GETFL);
        30. fcntl(fd,F_SETFL,Oflags|FASYNC);
        31. intrest;
        32. while(1){
        33. printf("Hello");
        34. while(rest=sleep(50)){
        35. sleep(rest);
        36. }
        37. }
        38. return0;
        39. }
        這里需要注意的是,應(yīng)用程序接收到消息會(huì)打斷sleep,比如執(zhí)行sleep(5)之后程序接收到了一個(gè)消息,這時(shí),應(yīng)用程序就被喚醒了,雖然是去執(zhí)行的消息處理函數(shù)。如果程序接收到消息時(shí)僅睡眠了2秒,那么sleep被中斷時(shí)會(huì)返回5-2=3,所以代碼中采用while循環(huán)方式進(jìn)行sleep,這樣,即使接收到了消息也能完整的休眠5秒,當(dāng)然,sleep函數(shù)本身是不夠精確的,不過(guò)相差無(wú)幾。

        到這里,這個(gè)驅(qū)動(dòng)程序基本上就算可以了,當(dāng)然,還有對(duì)阻塞和非阻塞的支持,同步與互斥的支持,而阻塞與非阻塞無(wú)非是加上個(gè)邏輯判斷,同步與互斥根應(yīng)用程序的同步控制也差不多,無(wú)非就是信號(hào)量或者原子操作,這里就不多說(shuō)了,如果有朋友需要這些內(nèi)容可以留言討論。


        上一頁(yè) 1 2 下一頁(yè)

        關(guān)鍵詞: S5PV210按鍵驅(qū)

        評(píng)論


        相關(guān)推薦

        技術(shù)專(zhuān)區(qū)

        關(guān)閉
        主站蜘蛛池模板: 西吉县| 乡城县| 杭锦后旗| 南溪县| 胶州市| 张掖市| 从化市| 宁明县| 汝城县| 邵阳县| 常宁市| 垦利县| 扶余县| 湘潭市| 莱州市| 邳州市| 柯坪县| 岚皋县| 滕州市| 广平县| 门源| 老河口市| 讷河市| 泽库县| 龙江县| 息烽县| 临汾市| 广元市| 新和县| 利津县| 丘北县| 从化市| 自贡市| 长阳| 吴桥县| 襄樊市| 渭源县| 偏关县| 焦作市| 招远市| 上虞市|