设备驱动开发"/>
Linux设备驱动开发
By: fulinux
E-mail: fulinux@sina
Blog:
喜欢的盆友欢迎点赞和订阅!
你的喜欢就是我写作的动力!
目录
- 概述
- 问题
- hrtimer驱动示例修改版
- Makefile文件
- 运行演示
概述
我觉得这篇文章写的挺好,大家可以看下:Linux内核高精度定时器hrtimer 使用实例
主要是他还附带了示例。
问题
不过上述文章中的示例,我在使用时出现了多出错误的地方,可能是内核版本的区别,首先是hrtimer_test_ioctl
函数的区别,主要集中在参数这一块,我看是空的我就给屏蔽了,再就是我执行echo语句时会出现内核错误:
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驱动示例修改版
#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=%d\n", 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 enter\n");printk("hrtimer %d\n", __LINE__);printk("hrtimer count = %d\n", count);ret = kstrtoul_from_user(buf, count, 0, &val);if (ret) {printk("kstrtoint error return %d\n", ret);return -EINVAL;}printk("hrtimer Debug val:%d size:%d\n", val, count);if (val == 1) {printk("hrtimer_start\n");m_kt = ktime_set(value / 1000, (value % 1000) * 1000000);hrtimer_start(&hrtimer_test_timer, m_kt, HRTIMER_MODE_REL);} else {printk("hrtimer_cancel\n");hrtimer_cancel(&hrtimer_test_timer);}printk("hrtimer exit\n");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文件
obj-m := hello.oSRC := $(shell pwd)all:$(MAKE) -C $(KERNEL_SRC) M=$(SRC)modules_install:$(MAKE) -C $(KERNEL_SRC) M=$(SRC) modules_installclean:rm -f *.o *~ core .depend .*.cmd *.ko *.mod.crm -f Module.markers Module.symvers modules.orderrm -rf .tmp_versions Modules.symvers
运行演示
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设备驱动开发
发布评论