使用内核定时器的second字符设备驱动及测试代码
生活随笔
收集整理的這篇文章主要介紹了
使用内核定时器的second字符设备驱动及测试代码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
驅動:
#include <linux/kernel.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/types.h> #include <linux/errno.h>#include <linux/cdev.h>//cdev #include <linux/device.h>//udev #include <linux/sched.h>//schedule #include <linux/uaccess.h>//copy_to_user #include <linux/slab.h>//kmalloc()#define DEVICE_NAME "second_drv" static int second_major=0;/*主設備號*/ struct class *second_class;/*second設備結構體*/ static struct second_dev {struct cdev cdev;/*cdev 結構體*/atomic_t counter;/*一共經歷了多少時間;定義原子變量*/ struct timer_list s_timer;/*定義一個定時器*/ }; struct second_dev *second_devp;/*定義設備結構體指針*//*定時器處理函數*/ static void second_timer_handler(unsigned long arg) {mod_timer(&second_devp->s_timer,jiffies+HZ);/*再次調度定時器*/atomic_inc(&second_devp->counter);/*counter 加1*/printk(KERN_NOTICE"current jiffies is %d!!\n",jiffies); }static int second_open(struct inode *inode, struct file *filp) {//printk("in the second_open!!\n");filp->private_data=second_devp;/*將設備結構體指針賦值給文件私有數據指針*//*初始化定時器*/init_timer(&second_devp->s_timer);second_devp->s_timer.function=&second_timer_handler;second_devp->s_timer.expires=jiffies+HZ;add_timer(&second_devp->s_timer);/*添加定時器*/atomic_set(&second_devp->counter,0);/*計數清零*/return 0; }static int second_release(struct inode *inode,struct file *filp) {del_timer(&second_devp->s_timer);/*刪除定時器*/return 0; }static ssize_t second_read(struct file *filp,char __user *buf,ssize_t count,loff_t *ppos) { //printk("in the second_read!!\n");int counter;counter=atomic_read(&second_devp->counter);/*獲取count值*/if(copy_to_user(buf,&counter,count))return -EFAULT;else return sizeof(unsigned int); }static ssize_t second_write(struct file *filp,const char __user *buf,ssize_t count,loff_t *ppos) {return 0; }/*文件操作結構體*/ static const struct file_operations second_fops={.owner = THIS_MODULE,.open =second_open,.release =second_release,.read =second_read,.write =second_write, };/*初始化并注冊cdev*/ static void second_setup_cdev(struct second_dev *dev,int index) {int err;dev_t devno=MKDEV(second_major,index);cdev_init(&dev->cdev,&second_fops);/*初始化cdev成員*/dev->cdev.owner=THIS_MODULE;err=cdev_add(&dev->cdev,devno,1);/*向系統注冊字符設備*/if(err)printk(KERN_NOTICE"error=%d",err); }/*設備驅動模塊加載函數*/ static int __init second_init(void) {/*申請設備號*/int ret;dev_t devno=MKDEV(second_major,0);/*獲得設備號*/if(second_major)ret=register_chrdev_region(devno,1,DEVICE_NAME);else{ /*動態申請設備號*/ret=alloc_chrdev_region(&devno,0,1,DEVICE_NAME);second_major=MAJOR(devno);}if(ret){printk("request chrdev failed!!\n");return ret;}/*動態申請設備結構體內存*/second_devp=kmalloc(sizeof(struct second_dev),GFP_KERNEL);if(!second_devp){ret= -ENOMEM;goto fail_kmalloc;}memset(second_devp,0,sizeof(struct second_dev));/*申請到的內存空間清零*//*注冊字符設備*/second_setup_cdev(second_devp,0);/*用udev機制自動創建設備文件結點*/second_class=class_create(THIS_MODULE,"second_class");/*在sys/class下添加second_class這個類*/if (IS_ERR(second_class)) {printk(KERN_ERR "class_create() failed for second_class\n");goto fail_class_create;}device_create(second_class,NULL,devno,NULL,DEVICE_NAME);/*創建設備/dev/$DEVICE_NAME*/printk("init second_drv success!!,major=%d!!\n",second_major);return 0;fail_class_create:cdev_del(&second_devp->cdev);/*注銷cdev*/kfree(second_devp);/*釋放設備結構體內存*/fail_kmalloc:unregister_chrdev_region(devno,1);/*釋放設備號*/return ret; }/*設備驅動模塊卸載函數*/ static void __exit second_exit(void) {device_destroy(second_class,MKDEV(second_major,0));/*注銷設備*/class_destroy(second_class);/*注銷類*/cdev_del(&second_devp->cdev);/*注銷cdev*/kfree(second_devp);/*釋放設備結構體內存*/unregister_chrdev_region(MKDEV(second_major,0),1);/*釋放設備號*/ }MODULE_AUTHOR("mhb@SEU"); MODULE_LICENSE("GPL");module_init(second_init); module_exit(second_exit);
測試代碼:
?
轉載于:https://www.cnblogs.com/hello2mhb/p/3303137.html
總結
以上是生活随笔為你收集整理的使用内核定时器的second字符设备驱动及测试代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 文档生成工具Sandcastle Hel
- 下一篇: WPF:ListView数据绑定及Sty