Second Linux Driver Demo

Driver:

  1 #include <linux/module.h>
  2 #include <linux/fs.h>
  3 #include <linux/mm.h>
  4 #include <linux/init.h>
  5 #include <linux/cdev.h>
  6 #include <linux/slab.h>
  7 #include <linux/uaccess.h>
  8 
  9 #define SECOND_MAJOR 248
 10 
 11 static int second_major = SECOND_MAJOR;
 12 module_param(second_major, int, S_IRUGO);
 13 
 14 struct second_dev {
 15     struct cdev cdev;
 16     atomic_t counter;
 17     struct timer_list s_timer;
 18 };
 19 
 20 static struct second_dev *second_devp;
 21 
 22 static void second_timer_handler(unsigned long arg)
 23 {
 24     mod_timer(&second_devp->s_timer, jiffies + HZ); /* 触发下一次定时 */
 25     atomic_inc(&second_devp->counter); /* 增加秒计数 */
 26 
 27     printk(KERN_INFO "current jiffies is %ld\n", jiffies);
 28 }
 29 
 30 static int second_open(struct inode *inode, struct file *filp)
 31 {
 32     init_timer(&second_devp->s_timer);
 33     second_devp->s_timer.function = &second_timer_handler;
 34     second_devp->s_timer.expires = jiffies + HZ;
 35 
 36     add_timer(&second_devp->s_timer);
 37 
 38     atomic_set(&second_devp->counter, 0);  /* 初始化秒计数为0 */                   
 39 
 40     return 0;
 41 }
 42 
 43 static int second_release(struct inode *inode, struct file *filp)
 44 {
 45     del_timer(&second_devp->s_timer);
 46 
 47     return 0;
 48 }
 49 
 50 static ssize_t second_read(struct file *filp, char __user * buf, size_t count,
 51     loff_t * ppos)
 52 {
 53     int counter;
 54 
 55     counter = atomic_read(&second_devp->counter);
 56     if (put_user(counter, (int *)buf)) /* 拷贝counter到userspace */
 57         return -EFAULT;
 58     else
 59         return sizeof(unsigned int);
 60 }
 61 
 62 static const struct file_operations second_fops = {
 63     .owner = THIS_MODULE,
 64     .open = second_open,
 65     .release = second_release,
 66     .read = second_read,
 67 };
 68 
 69 static void second_setup_cdev(struct second_dev *dev, int index)
 70 {
 71     int err, devno = MKDEV(second_major, index);
 72 
 73     cdev_init(&dev->cdev, &second_fops);
 74     dev->cdev.owner = THIS_MODULE;
 75     err = cdev_add(&dev->cdev, devno, 1);
 76     if (err)
 77         printk(KERN_ERR "Failed to add second device\n");
 78 }
 79 
 80 static int __init second_init(void)
 81 {
 82     int ret;
 83     dev_t devno = MKDEV(second_major, 0);
 84 
 85     if (second_major)
 86         ret = register_chrdev_region(devno, 1, "second");
 87     else {        
 88         ret = alloc_chrdev_region(&devno, 0, 1, "second");
 89         second_major = MAJOR(devno);
 90     }
 91     if (ret < 0)
 92         return ret;
 93 
 94     second_devp = kzalloc(sizeof(*second_devp), GFP_KERNEL);
 95     if (!second_devp) {
 96         ret = -ENOMEM;
 97         goto fail_malloc;
 98     }
 99 
100     second_setup_cdev(second_devp, 0);
101 
102     return 0;
103 
104 fail_malloc:
105     unregister_chrdev_region(devno, 1);
106     return ret;
107 }
108 module_init(second_init);
109 
110 static void __exit second_exit(void)
111 {
112     cdev_del(&second_devp->cdev);    
113     kfree(second_devp);    
114     unregister_chrdev_region(MKDEV(second_major, 0), 1);
115 }
116 module_exit(second_exit);
117 
118 MODULE_AUTHOR("Barry Song <[email protected]>");
119 MODULE_LICENSE("GPL v2"); 

TstCase:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 #include <fcntl.h>
 5 #include <unistd.h>
 6 #include <signal.h>
 7 #include <sys/stat.h>
 8 
 9 
10 int main(int argc, char **argv){
11   int fd;
12 
13   int counter = 0;
14   int old_counter = 0;
15 
16   fd = open("/dev/second", O_RDONLY);
17 
18   if (fd != - 1) {
19     while (1) {
20       read(fd,&counter, sizeof(unsigned int));
21 
22       if(counter!=old_counter) {    
23           printf("seconds after open /dev/second :%d\n",counter);
24           old_counter = counter;
25       }
26     }    
27   } else {
28     printf("Device open failure\n");
29   }
30 }

Makefile

KVERS = $(shell uname -r)

# Kernel modules
obj-m += second.o

# Specify flags for the module compilation.
#EXTRA_CFLAGS=-g -O0

build: kernel_modules user_test

kernel_modules:
	make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
user_test:
	gcc -o second_test second_test.c

clean:
	make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

猜你喜欢

转载自www.cnblogs.com/xliang1015/p/9827751.html