Linux Kernel timer usage instructions

Source: Internet
Author: User

Kernel timer usage

Linux Kernel timer is a mechanism used by the kernel to control the scheduling of a function at a certain time point (based on jiffies) in the future. Its implementation lies in <Linux/Timer. h> and kernel/Timer. c file.

The scheduled function must be executed asynchronously. It is similar to a "software interrupt" and is in a non-process context. Therefore, the scheduling function must comply with the following rules:

1) access to user space is not allowed without the current pointer. Because there is no process context, there is no connection between the relevant code and the interrupted process.

2) do not perform sleep (or function that may cause sleep) and scheduling.

3) Any accessed data structure should be protected against concurrent access to prevent competition conditions.

 

After the scheduling function of the kernel timer runs once, it will not be run again (equivalent to automatic logout), but you can re-schedule yourself in the scheduled function to run periodically.

 

In the SMP system, the scheduling function always runs on the same CPU that registers it, so as to obtain the cached performance as much as possible.

 

Timer API

 

Data Structure of kernel Timer

Struct timer_list {

Struct list_head entry;

 

Unsigned long expires;

Void (* function) (unsigned long );

Unsigned long data;

 

Struct tvec_base * base;

/*...*/

};

The expires field indicates the jiffies value to be executed by the timer. When the jiffies value is reached, the function is called and data is passed as the parameter. After a timer is registered to the kernel, the entry field is used to connect the timer to a kernel linked list. The base field is used for internal kernel implementation.

Note that the expires value is 32-bit, because the kernel timer is not suitable for long future time points.

 

Initialization

Before using struct timer_list, You need to initialize the data structure to ensure that all fields are correctly set. There are two methods for initialization.

Method 1:

Define_timer (timer_name, function_name, expires_value, data );

The macro creates a timer named timer_name kernel statically and initializes its function, expires, name, and base fields.

 

Method 2:

Struct timer_list mytimer;

Setup_timer (& mytimer, (* function) (unsigned long), unsigned long data );

Mytimer. expires = jiffies + 5 * Hz;

Method 3:

Struct timer_list mytimer;

Init_timer (& mytimer );

Mytimer-> timer. expires = jiffies + 5 * Hz;

Mytimer-> timer. Data = (unsigned long) Dev;

Mytimer-> timer. Function = & corkscrew_timer;/* timer handler */

Use init_timer () to dynamically define a timer. Then, bind the address and parameters of the processing function to a timer_list,

Note that no matter which method is used for initialization, the attribute is only assigned a value to the field. Therefore, you can directly modify the expires, function, and data fields before running add_timer.

For the macro and function definitions above, see include/Linux/Timer. h.

 

Register

To take effect, the timer must also be connected to the dedicated linked list of the kernel, which can be achieved through add_timer (struct timer_list * timer.

 

Register again

To modify the scheduling time of a timer, call mod_timer (struct timer_list * timer, unsigned long expires ). Mod_timer () re-registers the timer to the kernel, regardless of whether the timer function has been run.

 

Cancel

To cancel a timer, you can use del_timer (struct timer_list * timer) or del_timer_sync (struct timer_list * timer ). Among them, del_timer_sync is used on the SMP system (in a non-SMP system, it is equal to del_timer). When the timer function to be deregistered is running on another CPU, del_timer_sync () wait until it is finished, so this function will sleep. In addition, it should be prevented from competing with the scheduled function to use the same lock. For a timer that has been run and has not been re-registered, there is nothing to do to deregister the function.

 

Int timer_pending (const struct timer_list * timer)

This function is used to determine whether a timer is added to the kernel linked list for scheduling. Note: When a timer function is about to be run, the kernel will delete the corresponding timer from the kernel linked list (equivalent to deregistering)

 

A simple example

# Include <Linux/module. h>

# Include <Linux/Timer. h>

# Include <Linux/jiffies. h>

 

Struct timer_list mytimer;

 

Static void myfunc (unsigned long data)

{

Printk ("% s/n", (char *) data );

Mod_timer (& mytimer, jiffies + 2 * Hz );

}

 

Static int _ init mytimer_init (void)

{

Setup_timer (& mytimer, myfunc, (unsigned long) "Hello, world! ");

Mytimer. expires = jiffies + Hz;

Add_timer (& mytimer );

 

Return 0;

}

 

Static void _ exit mytimer_exit (void)

{

Del_timer (& mytimer );

}

 

Module_init (mytimer_init );

Module_exit (mytimer_exit );

 

Example 2

Static struct timer_list power_button_poll_timer;

 

Static void power_button_poll (unsigned long dummy)

{

If (gpio_line_get (n2100_power_button) = 0 ){

Ctrl_alt_del ();

Return;

}

 

Power_button_poll_timer.expires = jiffies + (Hz/10 );

Add_timer (& power_button_poll_timer );

}

 

 

Static void _ init n2100_init_machine (void)

{

;

;

Init_timer (& power_button_poll_timer );

Power_button_poll_timer.function = power_button_poll;

Power_button_poll_timer.expires = jiffies + (Hz/10 );

Add_timer (& power_button_poll_timer );

}

 

 

 

Example 3

 

Device open initialization and registration Timer

 

Static int corkscrew_open (struct net_device * Dev)

 

{

;

;

Init_timer (& VP-> timer );

VP-> timer. expires = jiffies + media_tbl [Dev-> if_port]. Wait;

VP-> timer. Data = (unsigned long) Dev;

VP-> timer. Function = & corkscrew_timer;/* timer handler */

Add_timer (& VP-> timer );

:

;

}

The timer time-out processing function, which re-assigns a value to the time-out period of the timer.

 

Static void corkscrew_timer (unsigned long data)

{

;

;

VP-> timer. expires = jiffies + media_tbl [Dev-> if_port]. Wait;

Add_timer (& VP-> timer );

;

;

}

 

Delete the timer when the device is close

Static int corkscrew_close (struct net_device * Dev)

{

;

;

Del_timer (& VP-> timer );

;

;

}

Example 4

In this example, a static timer is created using define_timer.

# Include <Linux/module. h>

# Include <Linux/jiffies. h>

# Include <Linux/kernel. h>

# Include <Linux/init. h>

# Include <Linux/Timer. h>

# Include <Linux/LEDs. h>

 

Static void ledtrig_ide_timerfunc (unsigned long data );

 

Define_led_trigger (ledtrig_ide );

Static define_timer (ledtrig_ide_timer, ledtrig_ide_timerfunc, 0, 0 );

Static int ide_activity;

Static int ide_lastactivity;

 

Void ledtrig_ide_activity (void)

{

Ide_activity ++;

If (! Timer_pending (& ledtrig_ide_timer ))

Mod_timer (& ledtrig_ide_timer, jiffies + msecs_to_jiffies (10 ));

}

Export_symbol (ledtrig_ide_activity );

 

Static void ledtrig_ide_timerfunc (unsigned long data)

{

If (ide_lastactivity! = Ide_activity ){

Ide_lastactivity = ide_activity;

Led_trigger_event (ledtrig_ide, led_full );

Mod_timer (& ledtrig_ide_timer, jiffies + msecs_to_jiffies (10 ));

} Else {

Led_trigger_event (ledtrig_ide, led_off );

}

}

 

Static int _ init ledtrig_ide_init (void)

{

Led_trigger_register_simple ("ide-disk", & ledtrig_ide );

Return 0;

}

 

Static void _ exit ledtrig_ide_exit (void)

{

Led_trigger_unregister_simple (ledtrig_ide );

}

 

Module_init (ledtrig_ide_init );

Module_exit (ledtrig_ide_exit );

 

Module_author ("Richard purdie <rpurdie@openedhand.com> ");

Module_description ("led IDE disk activity trigger ");

Module_license ("GPL ");

 

For details about how to use jiffies to calculate the kernel timing time, see the following URL:

Http://blog.csdn.net/zhandoushi1982/article/details/5536210

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.