kernel timer

concept

The Linux kernel timer uses a point-in-time timing method: starting at the current time and ending at a future time.

Kernel timer precision is not high

Kernel timer is not running periodically and will shut down automatically after timeout. You can turn on the timer again in the timer processing function.

Structures and functions

include/linux/timer.h

timer_list structure

struct timer_list{
	struct list_head entry;
	unsigned long expires;  //Timer timeout beats
	struct tvec_base *base;
	void (*function)(unsigned long);  //Timer Processing Function
	unsigned long data;  //Pass the parameters of a given time-processing function
	int slack;
};

expires requires the number of beats, not a time parameter

variable

The global variable jiffies in the kernel represents the current number of beats, and the macro HZ represents the number of clock beats corresponding to one second.

The kernel has a macro HZ that represents the number of beats per second. CONFIG_HZ can configure Kernel Features ---- Timer frequency option when compiling the kernel. The default beat per second in video tutorials is 100 hz, which means the number of beats per second is 100.

Time Conversion Function

ms to clock beat

unsigned long msecs_to_jiffies(const unsigned int m)

us to clock beat

unsigned long usecs_to_jiffies(const unsigned int u)

Timer 10ms:expires = jiffies + msecs_to_jiffies(10)

Timer 10us:expires = jiffies + usecs_to_jiffies(10)

Initialize Macro

Statically define struct variables and initialize function, expires, data members

#define DEFINE_TIMER(_name, _function, _expires, _data)
//parameter
_name Variable name, used for initialization timer_list structural morphology
_function Timeout handler,
_expires Arrival time, tempo
_data Parameters passed to the timeout function

add_timer function

void add_timer(struct timer_list *timer)

Register a timer with the Linux kernel using add_timer starts running when timer is registered

del_timer function

int del_timer(struct timer_list *timer)

Delete a timer, regardless of whether the timer is activated or not, you can use this function to delete.

On a multiprocessor system, timers may run on other processors, so calls to delete timers wait for timer functions from other processors to exit.

Return value: 0, timer has not been activated; 1, Timer is activated

mod_timer function

Modify the timer value. If the timer is not activated, the calling function activates the timer

int mod_timer(struct timer_list *timer, unsigned long expires)

Return value: 0, timer has not been activated; 1, Timer is activated

This function can be called in the timer processing function to reset the timer.

Experimental ideas

  • Using DEFINE_TIMER macro defines and initializes timer
  • Defines the writing of timer processing functions in which mod_ The timer function modifies and reactivates the timer
  • Use add_at module entry The timer function registers the timer with the kernel and edits the timer beat function of the timer structure here
  • Module Exit, del_timer release timer

Code

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

#include <linux/timer.h>

//Declare timer processing functions
static void ta_timer_func(unsigned long dat);  

//Define and initialize the timer. The expires parameter does not need to be initialized anymore, but calculates the beat when it needs to be turned on
DEFINE_TIMER(taxue_timer, ta_timer_func, 0, 0);

//Define timer processing functions
static void ta_timer_func(unsigned long dat){
    static int count=0;
    printk("hello timer count=%d\n",count++);
    if(count <= 50){
        //Modify the timer so that it works again
        //Tempo set to current time + count*10 ms
        mod_timer(&taxue_timer, jiffies + msecs_to_jiffies(count*10));
    }else{
        printk("done\n");
    }
}

static int driver_init_timer(void){
    printk("Hello MengYu\n");
    taxue_timer.expires = jiffies + 1*HZ;  //Current beat + 1 second beat
    add_timer(&taxue_timer);  //Register Timer with Kernel
    return 0;
}

static void driver_exit_timer(void){
    del_timer(&taxue_timer);    //Delete timer
    printk("platform driver exit!\n");
}


module_init(driver_init_timer);  //Module entry to execute functions within parameters when loading drivers
module_exit(driver_exit_timer);  //Module Exit, functions within parameters executed when module is unloaded

MODULE_LICENSE("Dual BSD/GPL"); //Follow BSD and GPL open source licenses
MODULE_AUTHOR("TAXUE");  //Module Author

Tags: Linux Driver

Posted on Fri, 05 Nov 2021 12:21:28 -0400 by OniLink