我是靠谱客的博主 稳重航空,这篇文章主要介绍Linux设备驱动开发 - 高精度定时器hrtimer概述问题hrtimer驱动示例修改版Makefile文件运行演示,现在分享给大家,希望可以做个参考。

By: fulinux
E-mail: fulinux@sina.com
Blog: https://blog.csdn.net/fulinus
喜欢的盆友欢迎点赞和订阅!
你的喜欢就是我写作的动力!

在这里插入图片描述

目录

  • 概述
  • 问题
  • hrtimer驱动示例修改版
  • Makefile文件
  • 运行演示

概述

我觉得这篇文章写的挺好,大家可以看下:Linux内核高精度定时器hrtimer 使用实例
主要是他还附带了示例。

问题

不过上述文章中的示例,我在使用时出现了多出错误的地方,可能是内核版本的区别,首先是hrtimer_test_ioctl函数的区别,主要集中在参数这一块,我看是空的我就给屏蔽了,再就是我执行echo语句时会出现内核错误:

复制代码
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
root@msm8937:~# echo 1 > /dev/hrtimer_test [ 494.983351] hrtimer enter [ 494.983380] hrtimer 48 [ 494.984945] hrtimer 50 [ 494.987206] Unhandled fault: page domain fault (0x01b) at 0x89371168 [ 494.989559] pgd = b82a23a5 [ 494.996058] [89371168] *pgd=aa5c3835, *pte=a5f2275f, *ppte=a5f22c7f [ 495.004562] Internal error: : 1b [#5] PREEMPT SMP ARM [ 495.004918] Modules linked in: hello(O) wlan(O) wglink_dlkm(O) usf_dlkm(O) stub_dlkm(O) pinctrl_wcd_dlkm(O) native_dlkm(O) platform_dlkm(O) machine_ext_dlkm(O) wcd9335_dlkm(O) swr_ctrl_dlkm(O) machine_dlkm(O) wsa881x_analog_dlkm(O) wsa881x_dlkm(O) swr_dlkm(O) hdmi_dlkm(O) digital_cdc_dlkm(O) cpe_lsm_dlkm(O) wcd_cpe_dlkm(O) analog_cdc_dlkm(O) wcd9xxx_dlkm(O) mbhc_dlkm(O) wcd_core_dlkm(O) q6_dlkm(O) adsp_loader_dlkm(O) apr_dlkm(O) q6_notifier_dlkm(O) [last unloaded: hello] [ 495.051351] CPU: 0 PID: 1902 Comm: sh Tainted: G D W O 4.9.218 #1 [ 495.051623] Hardware name: Qualcomm Technologies, Inc. QM215 [ 495.058392] task: c2b48f38 task.stack: 3a4e745d [ 495.064212] PC is at kstrtoint+0x24/0xc8 [ 495.068464] LR is at hrtimer_test_write+0x74/0x180 [hello] [ 495.072630] pc : [<c053579c>] lr : [<bf12e110>] psr: 600d0013 [ 495.072630] sp : ebac9e70 ip : ebac9e98 fp : ebac9e94 [ 495.077937] r10: 00000004 r9 : 00000000 r8 : ebac9f70 [ 495.089294] r7 : 89371168 r6 : bf12e09c r5 : 89371168 r4 : ebac9ea8 [ 495.094506] r3 : 00000000 r2 : 00000000 r1 : 0000000a r0 : 89371168 [ 495.101103] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none [ 495.107614] Control: 10c0383d Table: aa4d006a DAC: 00000051 [ 495.114814] [ 495.114814] PC: 0xc053571c: ...

错误原因是使用hrtimer_test_write函数里面的buf就会出错,我换成copy_from_user也是会出现相同问题,于是我换成kstrtoul_from_user函数即可。

hrtimer驱动示例修改版

复制代码
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
#include <linux/module.h> #include <linux/fs.h> #include <linux/jiffies.h> #include <linux/hrtimer.h> #include <linux/miscdevice.h> #include <linux/uaccess.h> unsigned int timer_count = 0; struct hrtimer hrtimer_test_timer; ktime_t m_kt; int value = 2000; static enum hrtimer_restart hrtimer_test_timer_poll(struct hrtimer *timer) { printk("timer_count=%dn", timer_count++); hrtimer_forward(timer, timer->base->get_time(), m_kt); return HRTIMER_RESTART; } static ssize_t hrtimer_test_write(struct file *fp, const char __user *buf, size_t count, loff_t *ppos) { int ret = 0; unsigned long val; printk("hrtimer entern"); printk("hrtimer %dn", __LINE__); printk("hrtimer count = %dn", count); ret = kstrtoul_from_user(buf, count, 0, &val); if (ret) { printk("kstrtoint error return %dn", ret); return -EINVAL; } printk("hrtimer Debug val:%d size:%dn", val, count); if (val == 1) { printk("hrtimer_startn"); m_kt = ktime_set(value / 1000, (value % 1000) * 1000000); hrtimer_start(&hrtimer_test_timer, m_kt, HRTIMER_MODE_REL); } else { printk("hrtimer_canceln"); hrtimer_cancel(&hrtimer_test_timer); } printk("hrtimer exitn"); return count; } static const struct file_operations hrtimer_test_fops = { .owner = THIS_MODULE, .write = hrtimer_test_write, }; static struct miscdevice hrtimer_test_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "hrtimer_test", .fops = &hrtimer_test_fops, }; int init_module(void) { int ret; printk("Hello World!n"); ret = misc_register(&hrtimer_test_dev); hrtimer_init(&hrtimer_test_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer_test_timer.function = hrtimer_test_timer_poll; return 0; } void cleanup_module(void) { printk("Goodbye Cruel World!n"); misc_deregister(&hrtimer_test_dev); } MODULE_LICENSE("GPL");

Makefile文件

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
obj-m := hello.o SRC := $(shell pwd) all: $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install: $(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_install clean: rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c rm -f Module.markers Module.symvers modules.order rm -rf .tmp_versions Modules.symvers

运行演示

复制代码
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
root:~# insmod hello.ko [ 928.049913] Hello World! root:~# echo 1 > /dev/hrtimer_test [ 930.322295] hrtimer enter [ 930.322326] hrtimer 47 [ 930.323892] hrtimer count = 2 [ 930.326151] hrtimer Debug val:1 size:2 [ 930.329258] hrtimer_start [ 930.334506] hrtimer exit root:~# [ 932.334636] timer_count=0 [ 934.334649] timer_count=1 [ 936.334512] timer_count=2 [ 938.334633] timer_count=3 [ 940.334513] timer_count=4 [ 942.334631] timer_count=5 ... root:~# echo 0 > /dev/hrtimer_test root:~# e[ 960.334665] timer_count=14 [ 964.794608] hrtimer enter [ 964.795294] hrtimer 47 [ 964.797980] hrtimer count = 2 [ 964.800445] hrtimer Debug val:0 size:2 [ 964.803284] hrtimer_cancel [ 964.806932] hrtimer exit

最后

以上就是稳重航空最近收集整理的关于Linux设备驱动开发 - 高精度定时器hrtimer概述问题hrtimer驱动示例修改版Makefile文件运行演示的全部内容,更多相关Linux设备驱动开发内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(76)

评论列表共有 0 条评论

立即
投稿
返回
顶部