Linuxデバイスドライバ開発 カーネルスレッド†
カーネルスレッド†
カーネルモジュールの中でkthreadを生成し、定期処理を行なうサンプル実装
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/types.h> /* dev_t */
- #include <linux/kdev_t.h> /* MKDEV(), MAJOR() */
- #include <linux/fs.h> /* register_chrdev_region(), alloc_chrdev_region(), unregister_chrdev() */
- #include <linux/kthread.h> /* kthread_run(), kthread_should_stop() */
-
- MODULE_LICENSE("Dual BSD/GPL");
-
- int drv_major = 0;
- int drv_minor = 0;
- int drv_nr_devs = 1;
- static struct task_struct *kthread_tsk;
-
- #define SKEL_DRV_NAME "skel_drv"
-
- static long get_timestamp(void)
- {
- unsigned long ts_us = 0;
- struct timeval tv;
-
- do_gettimeofday(&tv);
- ts_us = (unsigned long long)(tv.tv_sec)*1000000 + tv.tv_usec;
-
- return ts_us;
- }
-
- static void my_kthread_main(void)
- {
-
-
-
-
-
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1 * HZ);
-
-
- pr_info("my_kthread_main:%ld\n", get_timestamp());
- }
-
- static int my_kthread(void *arg)
- {
- pr_info("%s:I %ld HZ-%d\n", __FUNCTION__, get_timestamp(), HZ);
-
- while (!kthread_should_stop()) {
- my_kthread_main();
- }
-
- pr_info("%s:O\n", __FUNCTION__);
- return 0;
- }
-
- static int skel_init(void)
- {
- dev_t dev = 0;
- int ret;
-
- pr_info("%s\n", __FUNCTION__);
-
- if (drv_major) {
-
- dev = MKDEV(drv_major, drv_minor);
- ret = register_chrdev_region(dev, drv_nr_devs, SKEL_DRV_NAME);
- }
- else {
-
- ret = alloc_chrdev_region(&dev, drv_minor, drv_nr_devs, SKEL_DRV_NAME);
- drv_major = MAJOR(dev);
- }
-
- if (ret < 0) {
- pr_err("SKEL_DRV: cant't get major %d\n", drv_major);
- }
- else {
- pr_info("SKEL_DRV: char driver major number is %d\n", drv_major);
- }
-
-
- kthread_tsk = kthread_run(my_kthread, NULL, "skel kthread");
- if (IS_ERR(kthread_tsk)) {
- pr_err("SKEL_DRV: kthread_run failed\n");
- }
- else {
- pr_info("kthread_main pid:%d\n", kthread_tsk->pid);
- }
-
- return 0;
- }
- static void skel_exit(void)
- {
- pr_info("%s\n", __FUNCTION__);
-
-
- kthread_stop(kthread_tsk);
- unregister_chrdev(drv_major, SKEL_DRV_NAME);
- }
-
- module_init(skel_init);
- module_exit(skel_exit);
実行確認
$ sudo insmod skel_drv.ko
$ sudo rmmod skel_drv
$ dmesg
:
[514702.117329] skel_init
[514702.117332] SKEL_DRV: char driver major number is 243
[514702.117482] kthread_main pid:127959
[514702.117546] my_kthread:I 1548054143358956 HZ-250
[514703.117142] my_kthread_main:1548054144358638
[514704.117105] my_kthread_main:1548054145358691
[514705.117307] my_kthread_main:1548054146358977
[514706.117366] my_kthread_main:1548054147359125
[514706.425008] skel_exit
[514706.425015] my_kthread_main:1548054147666807
[514706.425016] my_kthread:O
ソースコード ダウンロード