1. 程式人生 > >Linux 核心定時器使用 一 低精度定時器

Linux 核心定時器使用 一 低精度定時器

核心定時器是一個數據結構,它告訴核心在使用者定義的時間點使用使用者定義的引數來執行一個使用者定義的函式。其實現位於

<linux/timer.h>中。

核心提供了一組用來宣告、註冊和刪除核心定時器的函式,相關介面如下:

struct timer_list {
	/*
	 * All fields that change during normal runtime grouped to the
	 * same cacheline
	 */
	struct list_head entry;
	unsigned long expires;              //時間,通常精度在毫秒級別
	struct tvec_base *base;

	void (*function)(unsigned long);    //回撥函式
	unsigned long data;                 //回撥函式引數

	int slack;

#ifdef CONFIG_TIMER_STATS
	int start_pid;
	void *start_site;
	char start_comm[16];
#endif
#ifdef CONFIG_LOCKDEP
	struct lockdep_map lockdep_map;
#endif
};

//定時器動態初始化
void init_timer(struct timer_list &timer);

//定時器靜態初始化
#define DEFINE_TIMER(_name, _function, _expires, _data)

//新增定時器
void add_timer(struct timer_list *timer);

//刪除定時器
int del_timer(struct timer_list * timer);

//和上面類似,但該函式可確保在返回時沒有任何CPU在執行定時器函式
int del_timer_sync(struct timer_list *timer);

//修改定時器
int mod_timer(struct timer_list *timer, unsigned long expires);

//檢查定時器是否正在被排程執行
int timer_pending(const struct timer_list * timer);

下面給出定時器使用的小栗子,定時器以斐波那契數列為引數,當定時時間達到13秒時自動退出:

/*
 *  Description : 核心定時器demo
 *  Author : mason
 *  Date   : 201808
 */

#include <linux/timer.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>

static unsigned long data;
struct timer_list demo_timer;

/* 斐波那契數列 */
unsigned long fibonacci(unsigned long data)
{
    if (data == 1 || data == 2)
    {
        return 1;
    }
    else
    {
        return fibonacci(data-1) + fibonacci(data-2);
    }
}

/* 定時器回撥函式 */
void timer_handler(unsigned long arg)
{
    unsigned long intv;
    printk("current fibonacci is : %lu \r\n", arg);

    if (arg == 13) 
    {
        printk("Game Over Bye\r\n");
        del_timer(&demo_timer);
        return ;
    }
    else
    {
        data++;
        intv = fibonacci(data);

        /* HZ單位為秒 */
        demo_timer.expires = intv * HZ + jiffies;
        demo_timer.data = intv;

        /* 重新新增定時器 */
        add_timer(&demo_timer);
        return;
    }
}

static int __init timer_demo_init(void)
{
    printk("Hello timer\r\n");

    data = 1;

    /* 定時器初始化 */
    init_timer(&demo_timer);
    demo_timer.expires = data * HZ + jiffies;
    demo_timer.data = data;
    demo_timer.function = timer_handler;    
    add_timer(&demo_timer);
    return 0;
}

static void __exit timer_demo_exit(void)
{
    printk("Bye timer\r\n");
    return ;
}

module_init(timer_demo_init)
module_exit(timer_demo_exit)
MODULE_AUTHOR("mason");
MODULE_DESCRIPTION("netlink kernel test");
MODULE_LICENSE("GPL");

Makefile:

obj-m := timer_demo.o


PWD := $(shell pwd)
KERNEL_DIR := "/usr/src/linux-headers-"$(shell uname -r)/

modules:
	@$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules
clean:
	@rm -rf *.ko *.o *.mod.c *symvers *order .nl* .tmp*

	

核心版本 : 3.4.39

執行截圖:

參考資料 :

1. 《LInux 裝置驅動程式第三版》

2. 《深入理解Linux核心》

相關推薦

Linux 核心定時使用 精度定時

核心定時器是一個數據結構,它告訴核心在使用者定義的時間點使用使用者定義的引數來執行一個使用者定義的函式。其實現位於 <linux/timer.h>中。 核心提供了一組用來宣告、註冊和刪除核心定時器的函式,相關介面如下: struct timer_list {

golang 高效精度定時實現

    golang預設定時器是通過time模組提供的,不管是golang,libev,libevent也好,定時器都是通過最小堆實現的,導致加入定時器時間複雜度為O(lgn),在需要大量定時器時效率較低,所以Linux提供了基於時間輪的實現,我們本次提供的貼一張Linux時

手把手教你移植linux核心---------OK6410(

配置資訊: 移植核心:linux-3.3.5       可以從  http://www.kernel.org/     下載純正的版本    編譯環境:vmware下ubuntu11.04 交叉編譯版本:4.3.2 準備工作: 一塊OK6410開發板,交叉網線,串列埠線

Linux核心——cli()和sti()——標誌暫存的中斷標誌

cli()和sti()有點類似於彙編指令中的CLI和STL,當某個任務在執行的過程中不想被中斷,則可以在任務的開始出執行cli(),在任務的結束處執行sti(),恢復中斷的執行。 為了避免競爭條件和中斷對臨界程式碼區的干擾,在Linux 0.12核心程式碼中許多地方使用

linux核心程式設計實驗

問題 A : 1、提取cpu 型別 2、提取核心版本 問題 B: 1、啟動以來經歷的時間,以 dd:hh:mm:ss 報告 問題 C: 1、cpu 執行使用者態、系統態、空閒態所用時間 2、多少次磁碟請求 3、多少次上下文切換 4、啟動了多少次

Linux核心中斷機制():中斷註冊方法

今天在網上看到一份不錯的講解核心中斷原理的文章,分享給大家! 1.中斷註冊方法 在 linux 核心中用於申請中斷的函式是 request_irq(),函式原型在Kernel/irq/manage.c 中定義: int request_irq(unsigned int

linux核心除錯技巧:printk

printk是Linux核心的一個系統呼叫,也是核心程式碼除錯時最常用的技巧。 printk的格式化字串,參考:點選開啟連結 對於迴圈中的變數,或者被多次呼叫的函式裡面的變數, 有時候只需要列印一次,

Linux時間子系統之六:高精度定時(HRTIMER)的原理和實現

3.4 size 屬於 running return repr 而是 復雜度 ctu 上一篇文章,我介紹了傳統的低分辨率定時器的實現原理。而隨著內核的不斷演進,大牛們已經對這種低分辨率定時器的精度不再滿足,而且,硬件也在不斷地發展,系統中的定時器硬件的精度也越來越高,這也給

linux核心定時 記錄

驅動程式中使用timer的幾個必要的操作 1.分配 static struct timer_list pwm_timer; 2.設定、新增 pwm_timer.function = pwm_timer_function; pwm_timer.expires  = jiffies

Linux精度定時hrtimers簡單介紹和應用場景

hrtimer:high-resolution kernel timers:   hrtimers的誕生是由於核心開發者在使用過程中發現,原始的定時器kernel/timers.c,已經可以滿足所有場景的,但是在實際的大量測試中發現還是無法滿足所有場景,所以hrtime

Linux核心定時-- timer_list

一.概述       核心經常要推後執行某些程式碼,如底半部機制就是為了將工作推後執行。timer_list為我們提供一種方式,使工作能夠在指定時間點上執行。       定時器使用簡單,只須執行一些初始化工作,設定一個超時時間,指定超時發生後執行的函式,然後啟用定時器就可

hrtimer核心精度定時

#include <linux/kernel.h> #include <linux/module.h> #include <linux/hrtimer.h> #include <linux/ktime.h> MODULE_LI

手把手教你寫Linux裝置驅動---定時()(基於友善之臂4412開發板)

這個專題我們來說下Linux中的定時器。在Linux核心中,有這樣的一個定時器,叫做核心定時器,核心定時器用於控制某個函式,也就是定時器將要處理的函式在未來的某個特定的時間內執行。核心定時器註冊的處理函

[轉載]linux 核心定時詳解

Linux核心2.4版中去掉了老版本核心中的靜態定時器機制,而只留下動態定時器。相應地在timer_bh()函式中也不再通過run_old_timers()函式來執行老式的靜態定時器。動態定時器與靜態定時器這二個概念是相對於Linux核心定時器機制的可擴充套件功能而言的,動態定時器是指核心的定時器佇列

linux核心分析之軟定時筆記

定時器是一種軟體功能,即允許在將來的某個時刻,函式在給定的時間間隔用完時被呼叫。超時表示與定時器相關的時間間隔已經用完的那個時刻。 linux上考慮兩種型別的定時器,即動態定時和間隔定時器。第一種型別由核心使用,而間隔定時器由程序在使用者態建立。 動態定時器 動態定時的主要

linux核心程式設計之核心定時

如果我們需要在將來某個時間點排程執行某個動作,同時在該時間點到達之前不會阻塞當前程序,可以使用核心定時器。核心定時器可用來在未來的某個特定時間點排程執行某個函式,從而可用於完成許多工。 Linux 核心所提供的用於操作定時器的資料結構和函式(位於 <linux/ti

Linux核心系統定時TIMER實現過程分析

Linux系統定時器,在核心中扮演著重要角色。核心的許多重要實現如任務排程,工作佇列等均以系統定時器關係密切。系統定時器能以可程式設計的頻率中斷處理,這一中斷叫做軟中斷。此頻率即為每秒的定時器節拍數HZ。HZ的越大,說明定時器節拍越小,執行緒排程的準確性會越高。但HZ設得

把握linux核心設計思想(七):核心定時定時執行

途】        前面章節說到了把工作推後到除現在以外的時間執行的機制是下半部機制,但是當你需要將工作推後到某個確定的時間段之後執行,使用定時器是很好的選擇。         上一節核心時間管理中講到核心在始終中斷髮生執行定時器,定時器作為軟中斷在下半部上下文中執行。時鐘中斷處理程式會執行update_p

linux核心分析筆記----定時和時間管理

在這一次裡,主要講講和時間相關的東西,這個我們都比較熟悉,我就直接如主題。       首先要明白兩個概念:系統定時器和動態定時器。週期性產生的事件都是有系統定時器驅動的,這裡的系統定時器是一種可程式設計硬體晶片,它能以固定頻率產生中斷。該中斷就是定時器中斷

Linux核心定時詳解

static struct pin_desc *irq_pd; /* 鍵值: 按下時, 0x01, 0x02, 0x03, 0x04 */ /* 鍵值: 鬆開時, 0x81, 0x82, 0x83, 0x84 */ static unsigned char key_val; struct pin_desc{u