1. 程式人生 > >linux核心程式設計之核心定時器

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;        /* 期望定時器執行的jiffies值 */
    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);
然後還需為定時器結構成員expires、function、data(需要的話)賦值。
使用如下函式註冊定時器:
void add_timer(struct timer_list * timer);
這樣定時器將在expires之後執行函式function,不過此時只能執行一次,如果想在之後每個expires時間都執行function函式的話,需要在function函式裡面修改定時器expires的值。使用如下函式修改:
int mod_timer(struct timer_list *timer, unsigned long expires);
在定時器處理函式中,在做完相應的工作後,往往會延後 expires 並將定時器再次新增到核心定時器連結串列,以便定時器能再次被觸發。

一個示例如下:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/version.h>

#include <linux/timer.h>
#include <linux/delay.h>

struct timer_list   sln_timer;

void sln_timer_do(unsigned long l)
{
    mod_timer(&sln_timer, jiffies + HZ);//HZ為1秒,在此時間之後繼續執行

    printk(KERN_ALERT"jiffies: %ld\n", jiffies);//簡單列印jiffies的值
}

void sln_timer_set(void)
{
    init_timer(&sln_timer);//初始化定時器

    sln_timer.expires = jiffies + HZ;   //1s後執行
    sln_timer.function = sln_timer_do;    //執行函式

    add_timer(&sln_timer);    //向核心註冊定時器
}

static int __init sln_init(void)
{
    printk(KERN_ALERT"===%s===\n", __func__);

    sln_timer_set();
    return 0;
}

static void __exit sln_exit(void)
{
    printk(KERN_ALERT"===%s===\n", __func__);

    del_timer(&sln_timer);//刪除定時器
}

module_init(sln_init);
module_exit(sln_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("sln");

像定時器這種週期性的任務還可以使用延時工作佇列來實現。
給一個示例:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/version.h>

#include <linux/workqueue.h>
#include <linux/delay.h>

static struct workqueue_struct      *sln_wq = NULL;
static struct delayed_work          sln_dwq;


static void sln_do(struct work_struct *ws)
{
    queue_delayed_work(sln_wq, &sln_dwq, 1000);
    printk(KERN_ALERT"jiffies: %ld\n", jiffies);
}

static int __init sln_init(void)
{
    printk(KERN_ALERT"===%s===\n", __func__);

    sln_wq = create_workqueue("sln_work_queue");
    INIT_DELAYED_WORK(&sln_dwq, sln_do);
    queue_delayed_work(sln_wq, &sln_dwq, 0);

    return 0;
}

static void __exit sln_exit(void)
{
    printk(KERN_ALERT"===%s===\n", __func__);

    cancel_delayed_work(&sln_dwq);
    flush_workqueue(sln_wq);
    destroy_workqueue(sln_wq);
}

module_init(sln_init);
module_exit(sln_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("allen");


相關推薦

linux核心程式設計核心定時

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

linux核心分析定時筆記

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

linux 核心模組程式設計核心符號匯出(五)

/proc/kallsyms 記錄了核心中所有匯出的符號的名字與地址 我們需要編譯2個核心模組,然後其中一個核心模組去呼叫另一個核心模組中的函式 hello.c程式碼如下 #include <linux/module.h> #include <linux/in

Linux 核心程式設計檔案系統(二)

1.為了方便查詢,VFS引入了 目錄 項,每個dentry代表路徑中的一個特定部分。目錄項也可包括安裝點。 2.目錄項物件由dentry結構體表示 ,定義在檔案linux/dcache.h 標頭檔案中。   89struct dentry {  90        atomic_t d_count;     

linux 核心程式設計proc虛擬檔案系統

在 Linux 系統中,/proc 檔案系統十分有用,它被用於核心向用戶匯出資訊。/proc 檔案系統是一個虛擬檔案系統,通過它可以使用一種新的方法在 Linux 核心空間和使用者空間之間進行通訊。在/proc 檔案系統中,我們可以將對虛擬檔案的讀寫作為與核心中實體進行

Linux核心時間管理和定時

轉自:http://blog.csdn.net/zhenwenxian/article/details/7643742 時間管理在核心中佔有非常重要的地位。相對於事件驅動,核心中有大量的函式都是基於時間驅動的。核心必須管理系統的執行時間以及當前的日期和時間。 首先搞

linux核心設計與實現 —— 定時和時間管理(第11章)

核心中的時間概念 硬體為核心提供了一個系統定時器用以計算流逝的時間。系統定時器是一種可程式設計硬體晶片,它能以固定頻率產生中斷。該頻率可以通過程式設計預定,稱作節拍率(tick rate)。該中斷就是所謂的定時器中斷,它所對應的中斷處理程式負責更新系統時間,也

Windows核心程式設計執行緒

執行緒組成兩部分: 1. 一個執行緒的核心物件,作業系統用它管理執行緒。 2. 一個執行緒棧,用於維護執行緒執行時所需的所有函式引數和區域性變數。 何時建立執行緒?舉例: 作業系統的Windows Indexing Services,磁碟碎片整理程式等,都是使用多執行緒進行效能優化的

windows核心程式設計程序

什麼是程序? 程序是一個正在執行程式的例項。由兩部分組成:一個核心物件,用於管理程序以及一個地址空間,包含所有可執行檔案或DLL模組的程式碼和資料,此外還包含動態記憶體分配。 在分析程序之前,先看下windows程式是如何建立的? Windows應用程式分為CUI和GUI程式,即控

ARM cortex-M核心晶片的軟體定時功能異常問題解決

      最近一個專案中的使用了軟體定時器功能,程式執行在前後臺的系統中,使用軟體定時器建立任務處理應用。硬體上外接一個水流感測器,水流感測器輸出的是一個方波訊號,水流越快,訊號的頻率越高。CPU採用的是STM32L051的晶片,使用外部中斷接收這個方波訊號,中斷

23.Linux/Unix 系統程式設計手冊(上) -- 定時與休眠

1.定時器是程序規劃自己在未來某一時刻接獲通知的一種機制 使用 settitimer() 建立的定時器可以跨越 exec() 系統呼叫而得以儲存, 但由 fork() 建立的子程序並不繼承該定時器。 如果正常休眠結束,sleep() 返回 0,如果因為訊號中斷而結

Linux程序管理核心執行緒

    核心原始碼:linux-2.6.38.8.tar.bz2     目標平臺:ARM體系結構     在Linux系統中,程序和執行緒都使用task_struct結構體來表示,執行緒只不過是一種特殊(所謂的特殊也不過是在被建立時使用不同的clone標誌組合而已)的

最新版 17 幅思維導圖:Python 程式設計核心知識體系

導讀: 本文主要涵蓋了 Python 程式設計的核心知識,展示了一系列思維導圖,主

核心程式設計SSDTHook(3)Hook NtCreateSection監控所有可執行模組載入

在上兩篇博文中,我介紹了SSDTHook的原理,並給出了一個例項--通過Hook NtOpenProcess來實現程序保護:http://blog.csdn.net/zuishikonghuan/article/details/50765464 這次我們玩個更好玩的,攔截

核心程式設計SSDTHook(1)原理

說驅動開發這麼長時間了,也玩玩核心鉤子,鉤子(Hook)技術是一種截獲對某一物件訪問的技術,不僅在Windows平臺,Linux平臺上也有Hook技術。Hook技術種類繁多,實現細節也不同,還可以靈活使用。 我之前寫過兩篇Ring3下的API Inline Hook的博文

Linux 驅動開發核心模組開發 (二)—— 核心模組編譯 Makefile 入門

一、模組的編譯  我們在前面核心編譯中驅動移植那塊,講到驅動編譯分為靜態編譯和動態編譯;靜態編譯即為將驅動直接編譯進核心,動態編譯即為將驅動編譯成模組。 而動態編譯又分為兩種: a -- 內部編譯        在核心原始碼目錄內編譯 b -- 外部編譯        在核

windows 核心程式設計在應用程式中使用虛擬記憶體

Microsoft Windows 提供了以下三種機制來對記憶體進行操控: 虛擬記憶體 最適合用來管理大型物件陣列或大型結構陣列 記憶體對映檔案 最適合用來管理大型資料流(通常是檔案),以及在同一臺機器上執行多個程序之間共享資料 堆 最適合管理大量小型物件 本篇只討論第一

Windows核心程式設計:分頁記憶體與非分頁記憶體

Windows規定有些虛擬記憶體可以交換到檔案中,這類記憶體被稱為分頁記憶體 有些虛擬記憶體永遠不會交換到檔案中,這些記憶體叫非分頁記憶體 #define PAGEDCODE code_seg(“PAGE”);//分頁記憶體 #define LOCKEDCODE c

Windows核心程式設計郵槽實現程序間通訊

    郵槽是Windows系統提供的一種單向通訊的機制。即程序中的一方只能寫入或讀取資料,而另一方則只能讀取或寫入資料。通過郵槽,使用者可以實現一對多或跨網路的程序之間的通訊。但是,郵槽能傳輸的資料

windows核心程式設計使用執行緒APC回撥安全退出多個等待執行緒

前言 程式開發中經常遇到需要這些情況:輔助執行緒正在等待核心物件的觸發,主執行緒需要強制終止輔助執行緒。我們常常做的就是使用:TerminateThread來強制終止執行緒。這樣做當然是不太好的,強制