-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathhr_device.c
108 lines (90 loc) · 2.38 KB
/
hr_device.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/random.h>
#include <linux/uaccess.h>
#include "hr_device.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("KernelTLV");
MODULE_DESCRIPTION("An imaginary heart rate monitor");
MODULE_VERSION("0.1");
static int major = 0;
static unsigned char heart_rate = 127;
static struct class *hr_class = NULL;
static struct device *hr_device = NULL;
static int hr_open(struct inode *inode, struct file *filp)
{
return 0;
}
static unsigned char new_hr_value(unsigned char hr_value)
{
char random = 0;
get_random_bytes(&random, sizeof(random));
if (random < 0)
{
return clamp(heart_rate - HEART_RATE_DELTA, 0, 255);
}
else
{
return clamp(heart_rate + HEART_RATE_DELTA, 0, 255);
}
}
static ssize_t hr_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
ssize_t pos = 0;
while (count > 0)
{
heart_rate = new_hr_value(heart_rate);
printk(KERN_DEBUG "%s: new heart rate value: %d\n", __func__, heart_rate);
if (copy_to_user(buf, &heart_rate, 1))
{
return -EFAULT;
}
++buf;
++pos;
--count;
}
return pos;
}
static const struct file_operations hr_fops = {
.open = hr_open,
.read = hr_read,
.llseek = noop_llseek,
};
static int __init hr_device_init(void)
{
printk(KERN_INFO "Heart rate monitor driver loaded!\n");
major = register_chrdev(0, DEVICE_NAME, &hr_fops);
if (major < 0)
{
printk(KERN_INFO "Unable to register hr device\n");
return major;
}
printk(KERN_INFO "Registered heart rate monitor device: %d\n", major);
hr_class = class_create(THIS_MODULE, DEVICE_NAME);
if (IS_ERR(hr_class))
{
unregister_chrdev(major, DEVICE_NAME);
return PTR_ERR(hr_class);
}
hr_device = device_create(hr_class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);
if (IS_ERR(hr_device))
{
class_destroy(hr_class);
unregister_chrdev(major, DEVICE_NAME);
return PTR_ERR(hr_device);
}
return 0;
}
static void __exit hr_device_exit(void)
{
device_destroy(hr_class, MKDEV(major, 0));
class_destroy(hr_class);
unregister_chrdev(major, DEVICE_NAME);
printk(KERN_INFO "Heart rate monitor driver unloaded!\n");
}
module_init(hr_device_init);
module_exit(hr_device_exit);