欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Linux 内核定时器 二 例子demo

程序员文章站 2022-06-09 13:08:30
...

Linux 内核定时器 一 函数简介

Linux 内核定时器 二 例子demo

环境: Ubuntu16

Linux ubuntu 4.15.0-29-generic #31~16.04.1-Ubuntu SMP Wed Jul 18 08:54:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

 

我在写 demo 的时候,编译的时候遇到几个错误:

Linux 内核定时器 二 例子demo

 

打开 Linux 4.15.0-29 内核中的 timer.h 并没有搜索到宏init_timer 

Linux  4.15.0-29 和 Linux linux-3.10.y 中的 timer.h 改动蛮大。

Ubuntu18 都出来蛮久了,相信安装新虚拟机的朋友会选择更新 Ubuntu 版本。

我使用的是 Ubuntu16 环境:

下面给出我在写测试demo 时,发现的 timer.h 的差异:

  • 初始化函数的接口有所变动;
  •  struct timer_list  // 结构体组员变动

 

 struct timer_list 差异如下图所示

新的内核中删除了

// 删除的成员变量:	
    unsigned long data;
	int slack;
#ifdef CONFIG_TIMER_STATS
	int start_pid;
	void *start_site;
	char start_comm[16];
#endif

Linux 内核定时器 二 例子demo

 

初始化函数的接口

旧接口:

  • init_timer(timer)
  • DEFINE_TIMER(_name, _function, _expires, _data)
  • setup_timer(timer, fn, data)

新接口:

  • init_timer(timer) -删除
  • DEFINE_TIMER(_name, _function)
  • timer_setup(timer, callback, flags)

 

demo 代码

定时器调用流程:

1. 初始化

    a. 宏 init_timer

    b. 宏DEFINE_TIMER

    c. 宏  setup_timer

2.向内核中添加定时器

     a.  add_timer - 初始化完成后,向内核中添加定时器

     b. mod_timer - 如果需要周期性执行任务,在定时器回调函数中添加 mod_timer

3. 手动/自动释放

     a. 定时器运行后,不会再运行,类似自动注销;

     b.  定时器未运行,可手动释放 -  del_timer
 

dev_test.c

#include <linux/module.h>
#include <linux/timer.h>
#include <linux/jiffies.h>

void time_pre(struct timer_list *timer);
struct timer_list mytimer;
// DEFINE_TIMER(mytimer, time_pre);
void time_pre(struct timer_list *timer)
{
    printk("%s\n", __func__);
    mytimer.expires = jiffies + 500 * HZ/1000;  // 500ms 运行一次
    mod_timer(&mytimer, mytimer.expires);       // 2.2 如果需要周期性执行任务,在定时器回调函数中添加 mod_timer
}

// 驱动接口
int __init chr_init(void)
{
    timer_setup(&mytimer, time_pre, 0);        // 1. 初始化
    mytimer.expires = jiffies + 500 * HZ/1000;
    add_timer(&mytimer);                       // 2.1 向内核中添加定时器
    printk("init success\n");
    return 0;
}

void __exit chr_exit(void)
{
    if(timer_pending(&mytimer))
    {
        del_timer(&mytimer);    // 3.释放定时器
    }
    printk("exit Success \n");
}

module_init(chr_init);
module_exit(chr_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("XXX");
MODULE_DESCRIPTION("a simple char device example");

 

makefile

# makefile
obj-m := drv_test.o
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
.PHONY:clean

all:
	make -C $(KERNEL_DIR) M=$(PWD) modules

clean:
	rm -f *.o *.ko *.mod.c *.mod.o *.symvers

 

运行:

sudo insmod drv_test.ko   # 加载驱动
sudo rmmod drv_test       # 卸载驱动

Linux 内核定时器 二 例子demo

dmesg 查看内核打印信息

Linux 内核定时器 二 例子demo