<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > S5PV210(TQ210)學(xué)習筆記——按鍵驅動(dòng)程序

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

作者: 時(shí)間:2016-11-28 來(lái)源:網(wǎng)絡(luò ) 收藏
  • init_waitqueue_head(&button_waitq);
  • return0;
  • device_error:
  • class_destroy(buttons_class);
  • class_error:
  • cdev_del(&cdev);
  • add_error:
  • unregister_chrdev_region(devno,1);
  • return-ENODEV;
  • }
  • voidbuttons_exit(void){
  • device_destroy(buttons_class,devno);
  • class_destroy(buttons_class);
  • cdev_del(&cdev);
  • unregister_chrdev_region(devno,1);
  • }
  • module_init(buttons_init);
  • module_exit(buttons_exit);
  • MODULE_LICENSE("GPL");
  • 測試程序代碼:

    本文引用地址:http://dyxdggzs.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)方式的按鍵驅動(dòng)程序,中斷方式編寫(xiě)的按鍵驅動(dòng)程序可以很大程度上節省CPU資源,因此,推薦使用中斷方式。

    二 支持POLL機制

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

    使內核支持poll還需要以下幾步:

    添加poll頭文件

    1. #include

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

    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處理函數添加給file_operations:
    1. .poll=buttons_poll,
    這樣,驅動(dòng)程序就支持poll機制了。下面是poll方式的測試程序:
    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. }

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

    三 支持異步機制

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

    1. staticintbuttons_fasync(intfd,structfile*file,inton){
    2. returnfasync_helper(fd,file,on,&button_async);
    3. }
    然后再buttons_read函數中添加一行代碼,修改后的代碼如下:
    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. }
    這樣,驅動(dòng)程序就支持異步獲取鍵值了,為了測試效果,測試程序也需要修改,代碼如下:
    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. }
    這里需要注意的是,應用程序接收到消息會(huì )打斷sleep,比如執行sleep(5)之后程序接收到了一個(gè)消息,這時(shí),應用程序就被喚醒了,雖然是去執行的消息處理函數。如果程序接收到消息時(shí)僅睡眠了2秒,那么sleep被中斷時(shí)會(huì )返回5-2=3,所以代碼中采用while循環(huán)方式進(jìn)行sleep,這樣,即使接收到了消息也能完整的休眠5秒,當然,sleep函數本身是不夠精確的,不過(guò)相差無(wú)幾。

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


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

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

    評論


    相關(guān)推薦

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

    關(guān)閉
    国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
    <dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>