<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > linux驅(qū)動之內(nèi)核定時器驅(qū)動設(shè)計

          linux驅(qū)動之內(nèi)核定時器驅(qū)動設(shè)計

          作者: 時間:2016-12-01 來源:網(wǎng)絡(luò) 收藏
          驅(qū)動程序:
          #include
          #include
          #include
          #include
          #include
          #include
          #include
          #include
          #include
          #include
          #include
          /*采用宏定義設(shè)置設(shè)備的主設(shè)備號*/
          #define SECOND_MAJOR 0
          /*靜態(tài)的分別保存靜態(tài)主設(shè)備號的變量*/
          static int second_major = SECOND_MAJOR;
          /*設(shè)備結(jié)構(gòu)體,通常在設(shè)備中包含需要的設(shè)備,比如字符、塊等類型*/
          struct second_dev{
          /*添加設(shè)備類型,
          我認(rèn)為可以采用一個聯(lián)合體,
          包含塊設(shè)備或者字符設(shè)備,類似inode的實(shí)現(xiàn)方法,
          這樣可以提高結(jié)構(gòu)體的通用性
          */
          struct cdev cdev;
          /*原子變量,用來統(tǒng)計*/
          atomic_t counter;
          /*添加內(nèi)核定時器結(jié)構(gòu)體變量*/
          struct timer_list s_timer;
          /*用于動態(tài)創(chuàng)建設(shè)備文件的設(shè)備類*/
          struct class *myclass;
          };
          /*結(jié)構(gòu)體指針或者采用全局變量直接定義結(jié)構(gòu)都可以*/
          struct second_dev *second_devp;
          /*如果定時時間到了,定時器的處理函數(shù)*/
          static void second_timer_handler(unsigned long arg)
          {
          /*
          修改定時器中的到期時間,增加時間為1s,
          需要注意的是mod_timer函數(shù)是重新注冊定時器到內(nèi)核
          而不管定時器是否被運(yùn)行過
          */
          mod_timer(&second_devp->s_timer,jiffies + HZ);
          /*原子變量的增加*/
          atomic_inc(&second_devp->counter);
          /*輸出jiffies值*/
          printk(KERN_NOTICE "Current jiffies is %d",jiffies);
          }
          /*open函數(shù)實(shí)現(xiàn)*/
          static int second_open(struct inode *inode,struct file *filp)
          {
          /*初始化定義的內(nèi)核定時器*/
          init_timer(&second_devp->s_timer);
          /*指定內(nèi)核定時器的處理函數(shù)是上面定義好的函數(shù)*/
          second_devp->s_timer.function = second_timer_handler;
          /*指定定時間隔是1s*/
          second_devp->s_timer.expires = jiffies + HZ;
          /*將定時器添加到內(nèi)核*/
          add_timer(&second_devp->s_timer);
          /*同時設(shè)備相關(guān)的統(tǒng)計值為0*/
          atomic_set(&second_devp->counter,0);
          return 0;
          }
          /*release函數(shù)的實(shí)現(xiàn)*/
          static int second_release(struct inode *inode,struct file *filp)
          {
          /*如果沒有到時間就關(guān)閉設(shè)備,直接刪除定時器*/
          del_timer(&second_devp->s_timer);
          return 0;
          }
          /*read函數(shù)的實(shí)現(xiàn)*/
          static ssize_t second_read(struct file *filp,char __user *buf,size_t count,loff_t *ppos)
          {
          int counter;
          /*讀當(dāng)前的值*/
          counter = atomic_read(&second_devp->counter);
          /*
          采用put_user實(shí)現(xiàn)數(shù)值的傳送
          put_user函數(shù)存在對指針變量的檢查,
          因此不需要檢測指針是否正確
          */
          if(put_user(counter,(int *)buf))
          return -EFAULT;
          else
          /*返回數(shù)據(jù)大小*/
          return sizeof(unsigned int);
          }
          /*具體的文件操作集合*/
          static const struct file_operations second_fops =
          {
          /*這是擁有者*/
          .owner = THIS_MODULE,
          .open = second_open,
          .release = second_release,
          .read = second_read,
          };
          /*初始化函數(shù)*/
          static int __init second_init(void)
          {
          int ret;
          /*設(shè)備號的申請,創(chuàng)建*/
          dev_t devno = MKDEV(second_major,0);
          /*靜態(tài)申請設(shè)備號*/
          if(second_major)
          {
          ret = register_chrdev_region(devno,1,"second");
          }
          /*動態(tài)申請設(shè)備號*/
          else
          {
          ret = alloc_chrdev_region(&devno,0,1,"second");
          second_major = MAJOR(devno);
          }
          if(ret < 0)
          {
          return ret;
          }
          /*分配設(shè)備結(jié)構(gòu)體的地址空間*/
          second_devp = kmalloc(sizeof(struct second_dev),GFP_KERNEL);
          /*檢查是否分配正確*/
          if(!second_devp)
          {
          ret = -ENOMEM;
          goto fail_malloc;
          }
          /*清零分配的空間*/
          memset(second_devp,0,sizeof(struct second_dev));
          /*創(chuàng)建設(shè)備類,用于自動創(chuàng)建設(shè)備文件*/
          second_devp->myclass = class_create(THIS_MODULE,"second_timer_class");
          /*字符設(shè)備初始化,綁定相關(guān)操作到設(shè)備*/
          cdev_init(&second_devp->cdev,&second_fops);
          /*設(shè)備的擁有者*/
          second_devp->cdev.owner = THIS_MODULE,
          /*添加設(shè)備到內(nèi)核*/
          ret = cdev_add(&second_devp->cdev,devno,1);
          /*錯誤處理*/
          if(ret)
          {
          printk(KERN_NOTICE "ERROR %d",ret);
          goto fail_malloc;
          }
          /*依據(jù)以前創(chuàng)建的設(shè)備類,創(chuàng)建設(shè)備*/
          device_create(second_devp->myclass,NULL,devno,NULL,"second%d",0);
          return 0;
          /*錯誤操作*/
          fail_malloc:
          unregister_chrdev_region(devno,1);
          return ret;
          }
          /*退出函數(shù)*/
          static void __exit second_exit(void)
          {
          /*釋放設(shè)備*/
          device_destroy(second_devp->myclass,MKDEV(second_major,0));
          /*刪除字符設(shè)備*/
          cdev_del(&second_devp->cdev);
          /*釋放設(shè)備類*/
          class_destroy(second_devp->myclass);
          /*釋放分配的內(nèi)存空間大小*/
          kfree(second_devp);
          /*釋放設(shè)備號*/
          unregister_chrdev_region(MKDEV(second_major,0),1);
          }
          /*卸載和加載*/
          module_init(second_init);
          module_exit(second_exit);
          /*LICENSE和作者信息*/
          MODULE_LICENSE("GPL");
          MODULE_AUTHOR("GP-");
          應(yīng)用程序:
          #include
          #include
          #include
          #include
          #include
          #include
          #include
          int main()
          {
          int fd;
          int counter = 0;
          int old_counter = 0;
          fd = open("/dev/second0",O_RDONLY);
          if(fd != -1)
          {
          while(1)
          {
          read(fd,&counter,sizeof(unsigned int));
          if(counter != old_counter)
          {
          printf("second after open /dev/second0 : %d",counter);
          old_counter = counter;
          }
          }
          }
          else
          {
          printf("Device open failure");
          exit(1);
          }
          exit(0);
          }
          實(shí)驗(yàn)效果:
          [root@EmbedSky Test]# ./app-timer
          Current jiffies is 2137721
          second after open /dev/second0 : 1
          Current jiffies is 2137921
          second after open /dev/second0 : 2
          Current jiffies is 2138121
          second after open /dev/second0 : 3
          Current jiffies is 2138321
          second after open /dev/second0 : 4
          Current jiffies is 2138521
          second after open /dev/second0 : 5
          Current jiffies is 2138721
          second after open /dev/second0 : 6
          以上的結(jié)果表明內(nèi)核定時器基本實(shí)現(xiàn)了效果,但從實(shí)驗(yàn)結(jié)果看好像為每兩秒實(shí)現(xiàn)一次顯示。具體的原因還有待于再次分析,因?yàn)閍rm中的HZ應(yīng)該為100,而不是200。
          上一頁 1 2 下一頁

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();