娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

Smart210學習記錄-----linux定時器

發布者:鄉村樂園最新更新時間:2025-01-20 來源: cnblogs關鍵字:Smart210  linux  定時器 手機看文章 掃描二維碼
隨時隨地手機看文章

1.內核定時器


  Linux 內核所提供的用于操作定時器的數據結構和函數如下:


     (1) timer_list


  在 Linux 內核中,timer_list 結構體的一個實例對應一個定時器


  1 struct timer_list {

2          struct list_head entry; /* 定時器列表 */

3          unsigned long expires; /*定時器到期時間*/

4           void (*function)(unsigned long); /* 定時器處理函數 */

5          unsigned long data; /* 作為參數被傳入定時器處理函數 */

6          struct timer_base_s *base;

7   ...

8 };


當定時器期滿后,其中第 5 行的 function()成員將被執行,而第 4 行的 data 成員則是傳入其中的參數,第 3 行的 expires 則是定時器到期的時間(jiffies)。


如下代碼定義一個名為 my_timer 的定時器:

struct timer_list my_timer;



  (2)初始化定時器


    void init_timer(struct timer_list * timer);


    上述 init_timer()函數初始化 timer_list 的 entry 的 next 為 NULL,并給 base 指針賦值


    TIMER_INITIALIZER(_function, _expires, _data)宏用于賦值定時器結構體的function、expires、

    data 和 base 成員


    DEFINE_TIMER(_name,  _function,  _expires,  _data)宏是定義并初始化定時器成員的“快捷方

    式”。


    此外,static inline void setup_timer(struct timer_list * timer, void (*function)(unsigned long),unsigned long data)

    也可用于初始化定時器并賦值其成員


  (3)增加定時器


    void add_timer(struct timer_list* timer);


   (4)刪除定時器


    int  del_timer(struct timer_list* timer);


  del_timer_sync()是 del_timer()的同步版,在刪除一個定時器時需等待其被處理完,因此該函數的調用不能發生在中斷上下文。


   (5).修改定時器的 expire


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


  上述函數用于修改定時器的到期時間,在新的被傳入的 expires 到來后才會執行定時器函數。


 


2.內核中延時的工作delayed_work


注意,對于這種周期性的任務,Linux 內核還提供了一套封裝好的快捷機制,其本質利用工作隊列

和定時器實現,這套快捷機制是就是delayed_work,delayed_work結構體的定義如代碼清單10.11所示。

代碼清單 10.11   delayed_work 結構體

1  struct delayed_work {

2                struct work_struct work;

3                struct timer_list timer;

4  };

5  struct work_struct {


6                atomic_long_t data;

7  #define WORK_STRUCT_PENDING 0 

8  #define WORK_STRUCT_FLAG_MASK (3UL)

9  #define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)

10               struct list_head entry;

11               work_func_t func;

12 #ifdef CONFIG_LOCKDEP

13               struct lockdep_map lockdep_map;

14 #endif

15 };


我們可以通過如下函數調度一個 delayed_work 在指定的延時后執行:

int schedule_delayed_work(struct delayed_work *work, unsigned long delay);

當指定的 delay 到來時 delayed_work 結構體中 work 成員的 work_func_t 類型成員 func()會被

執行。work_func_t 類型定義為:

typedef void (*work_func_t)(struct work_struct *work);

其中 delay 參數的單位是 jiffies,因此一種常見的用法如下:

schedule_delayed_work(&work, msecs_to_jiffies(poll_interval));

其中的 msecs_to_jiffies()用于將毫秒轉化為 jiffies。

如果要周期性的執行任務,通常會在 delayed_work 的工作函數中再次調用 schedule_delayed_

work(),周而復始。

如下函數用來取消 delayed_work:

int cancel_delayed_work(struct delayed_work *work);

int cancel_delayed_work_sync(struct delayed_work *work);


3.內核延時


Linux 內核中提供了如下 3 個函數分別進行納秒、微秒和毫秒延遲:

void ndelay(unsigned long nsecs);

void udelay(unsigned long usecs);

void mdelay(unsigned long msecs);

上述延遲的實現原理本質上是忙等待,它根據 CPU 頻率進行一定次數的循環。


毫秒時延(以及更大的秒時延)已經比較大了,在內核中,最好不要直接使用 mdelay()函數,這將無謂地耗費 CPU 資源,對于毫秒級以上時延,內核提供了下述函數:

void msleep(unsigned int millisecs);

unsigned long msleep_interruptible(unsigned int millisecs);

void ssleep(unsigned int seconds);

上述函數將使得調用它的進程睡眠參數指定的時間,msleep()、ssleep()不能被打斷,而msleep_interruptible()則可以被打斷。


秒設備驅動程序


#include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include

 #include


static unsigned char timermajor = 0;

#define   TIMERNAME    'mytimer'


static struct class *timer_class;

static struct device *timer_device;


struct timer_dev {

    struct cdev cdev;

    atomic_t counter;

    struct timer_list  mytimer;

};


struct timer_dev *my_timer_dev;


static void my_timer_fun(unsigned int arg)

{

    mod_timer(&my_timer_dev->mytimer, jiffies + HZ);

    atomic_inc(&my_timer_dev->counter);

    printk(KERN_NOTICE 'current jiffies is %ldn', jiffies); 

}



static int my_timer_open(struct inode * inode, struct file * file)

{

    init_timer( &my_timer_dev->mytimer);

    my_timer_dev->mytimer.expires = jiffies+ HZ;

    my_timer_dev->mytimer.function = & my_timer_fun;


    add_timer(&my_timer_dev->mytimer);

    atomic_set(&my_timer_dev->counter, 0);

    return 0;

}


static ssize_t my_timer_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)

{

    int counter;


    counter = atomic_read(&my_timer_dev->counter);


    if(copy_to_user(buf, &counter, sizeof(int)))

            printk('copy_to_user errorn');


    return 0;

}


static int my_timer_close(struct inode *inode, struct file *file)

{

    del_timer( &my_timer_dev->mytimer);

    return 0;

}


struct file_operations timer_fops = {

    .owner    =    THIS_MODULE,

    .open     =    my_timer_open,

    .read     =    my_timer_read,

    .release  =    my_timer_close,

};



static void timer_setup_cdev(struct timer_dev *dev, int minor )

{

    unsigned char err;

    dev_t deno;

    deno = MKDEV(timermajor, minor);

    cdev_init(&dev->cdev, &timer_fops);

    dev->cdev.owner = THIS_MODULE;

    dev->cdev.ops   = &timer_fops;

    err = cdev_add(&dev->cdev, deno, 1);

    if(err)

        printk(KERN_ALERT'cdev_addd errorn');

}


static int __init my_timer_init(void)

{

    int err = 0;

    dev_t deno;

    if(timermajor) {

        register_chrdev_region(deno, 1, TIMERNAME);

    } else {

        err = alloc_chrdev_region(&deno, 0, 1, TIMERNAME);

        timermajor = MAJOR(deno);

    }

    if(err)

        printk(KERN_ALERT'alloc_chrdev_region errorn');

    

    printk(KERN_ALERT'timermajor is %dn', timermajor);

    

    my_timer_dev = kmalloc(sizeof(struct timer_dev), GFP_KERNEL);

    if(!my_timer_dev) {

        printk(KERN_ALERT'kmalloc errorn');

        return -ENOMEM;

    }

    memset(my_timer_dev, 0, sizeof(struct timer_dev) );

    

    timer_setup_cdev(my_timer_dev, 0);


    timer_class = class_create(THIS_MODULE, TIMERNAME);

    if(IS_ERR(timer_class)) {

        printk(KERN_ALERT'class_create errorn');

        return -EBUSY;

    }


    timer_device = device_create(timer_class, NULL, deno, NULL, TIMERNAME);

    if(IS_ERR(timer_device)) {

        printk(KERN_ALERT'device_create errorn');

        return -EBUSY;

    }

    

    return 0;

}


static void __exit my_key_exit(void)

{

    cdev_del(&my_timer_dev->cdev);

    unregister_chrdev_region(MKDEV(timermajor, 0), 1);

   kfree(my_timer_dev);

}


MODULE_LICENSE('GPL');

MODULE_AUTHOR('qigaohua');

module_init(my_timer_init);

module_exit(my_key_exit);


測試程序:


#include


#include


#include


#include


int main()

{

    int fd;

    int counter = 0;

    int old_counter = 0;

    fd = open('/dev/mytimer', O_RDWR);

    if(fd < 0) {

        printf('open /dev/mytimer errorn');

        return 0;

    }


    while(1) {

        read(fd, &counter, sizeof(int));

        if(counter != old_counter) {

            old_counter = counter;

            printf('counter is %dn', counter);

        }

    }

}


關鍵字:Smart210  linux  定時器 引用地址:Smart210學習記錄-----linux定時器

上一篇:Smart210學習記錄------paltform總線
下一篇:Smart210學習記錄-------linux驅動中斷

推薦閱讀最新更新時間:2025-04-16 19:36

《嵌入式-STM32開發指南》第二部分 基礎篇 - 第2章 Systick系統定時器(HAL)
2.1 STM32Cube新建工程 關于如何使用使用STM32Cube新建工程在前文已經講解過了,這里直說配置GPIO部分內容。本文要實現流水燈,其實輸出為初始化設置為高電平還是低電平都可以,因為流水燈需要不斷反轉 第1章 GPIO(HAL庫) 1.GPIO配置 我們將PB0、PG6、PG7配置輸出模式(高電平、低電平均可)、輸出速率、上/下拉等,默認即可。 圖1GPIO初始化 2.時鐘源配置 圖2時鐘源 3.時鐘配置 圖3時鐘配置 4.sys配置(滴答定時器配置) 圖4滴答定時器 以上配置和GPIO流水燈是一樣的,本文只具體講解Systick的內容。 2.2 Systick系統定時器具體代碼分析 Systic
[單片機]
s5pv210的定時器
不廢話了,下面從s5pv210 的定時器開始總結。 210有五個32位的定時器,其中0、1、2、3、4包含了脈沖寬度調制,有定時和計數的器 的功能。這里就不再贅述,相關資料隨時都可以找到,這里直接上代碼。 1、首先是定時器的初始化,主要設置定時器的輸入時鐘頻率、定時器倒數計數初值和重載、占空比、使能定時器中斷和開啟等 int init_timer(void) { unsigned int temp0=0; //禁止timer TCON = 0x0; //使能timer0中斷 TINT_CSTAT = 0x01; /* 設置時鐘的工作頻率為1M prescaler value = 65 divider value = 1 i
[單片機]
SysTick定時器介紹,SysTick定時器寄存器
SysTick定時器介紹 SysTick定時器也叫SysTick滴答定時器, 它是Cortex-M3內核的一個外設,被嵌入在 NVIC 中。它是一個 24 位向下遞減的定時器,每計數一次所需時間為1/SYSTICK,SYSTICK 是系統定時器時鐘,它可以直接取自系統時鐘,還可以通過系統時鐘 8 分頻后獲取,本套程序中我們采用后者,即每計數一次所需時間為1/(72/8)us,換句話說在 1us 的時間內會計數 9 次。當定時器計數到 0 時,將從LOAD 寄存器中自動重裝定時器初值,重新向下遞減計數,如此循環往復。如果開啟 SysTick 中斷的話,當定時器計數到 0,將產生一個中斷信號。因此只要知道計數的次數就可以準確得到它的延
[單片機]
SysTick<font color='red'>定時器</font>介紹,SysTick<font color='red'>定時器</font>寄存器
stm32tim定時器AutoReload和pwm輸出Pulse的關系
老是理不清定時器的自動重裝載和PWM通道Pulse的關系 先說PSC和AutoReload的關系 PSC是預分頻 ST32F103頻率可以上到72M 舉個例子: 72000000/72=1M 1/1M=1/1000000=0.000001秒 預分配會影響自動重裝載的計數速度 比如上面計算的,他可以0.000001s計一個數 當計到AutoReload的值時,就會產生一個中斷 /*中斷回調函數*/ pwm的脈沖數Pulse: 在AutoReload的計數周期內,設置脈沖的多少。 比如說舵機 要20ms的周期,那么根據公式: 定時器時間=1/(時鐘頻率/預分頻/計數周期) 20ms=1/(72000000/
[單片機]
stm32tim<font color='red'>定時器</font>AutoReload和pwm輸出Pulse的關系
利用定時器0寫秒表(注釋)
利用定時器定時出秒表時間,通過共陰數碼管將所定時的時間顯示出來。 #include reg52.h #define uchar unsigned char #define uint unsigned int uchar code table = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};//共陰段碼表 uchar code table_SMG = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};//位選 //------------------------變量區----------------
[單片機]
利用<font color='red'>定時器</font>0寫秒表(注釋)
ARM芯片開發(S5PV210芯片)——定時器、看門狗、RTC
1、計數器 計數器就是每隔一段固定的時間計數值就加一,于是我們可以根據計數值來計算時間:經過的時間=計數值x計數時間間隔。 2、定時器 2.1、定時器介紹 定時器具有計時的功能,類似于我們手機自帶的倒計時功能。比如我們先給定時器設置計時一小時,當一小時之后定時器就會發出終端信號,提醒CPU該執行提前綁定好的中斷處理程序。 2.2、定時器原理 定時器內部有一個計數器,當我們設定好計時的時間后,內部的計數器會通過計數值和計數時間間隔來計算經過的時間。當經過的時間等于設定的 計時時間,定時器就會發出終端信號,提醒CPU時間到了,該去處理相應的中斷函數。定時的時間由計數值和計數時間間隔有關,其中計數時間間隔和定時器的時鐘頻率有關,
[單片機]
ARM芯片開發(S5PV210芯片)——<font color='red'>定時器</font>、看門狗、RTC
STM32-自學筆記(8.使用STM32的SysTick定時器控制LED燈閃爍)
SysTick定時器,被稱為“系統節拍時鐘”。SysTick屬于ARM Cortex-M3內核的一個內設,STM32也帶有SysTick定時器。 SysTick定時器的基本結構 SysTick工作原理: SysTick從時鐘源接口獲得時鐘驅動 從重裝寄存器將重裝值讀入當前計數寄存器中,并在時鐘驅動下進行減一計數。 當SysTick發生下溢時,將計數標志位置位,并且觸發SysTick溢出中斷,同時進行一次重裝值載入操作。 實驗說明: 使用STM32的SysTick定時器產生長度為1s的時間間隔,并以此時間間隔閃爍LED燈。 硬件電路: GPIOA.4引腳接LED燈,再接一個限流電阻,最后接地。如圖 軟件設
[單片機]
STM32-自學筆記(8.使用STM32的SysTick<font color='red'>定時器</font>控制LED燈閃爍)
LPTIM低功耗定時器有哪些獨特功能?
1寫在前面 在早些年,可能較少聽見LPTIM這個名詞。隨著低功耗產品需求越來越嚴格,MCU廠商就推出了針對低功耗應用的LPTIM定時器。 定時器是我們常見的一種外設,之所以這么常見,原因在于定時器的用途非常廣泛。 在STM32所有MCU中都配有定時器,那么你有關注、對比過各系列,各型號MCU中定時器的差異嗎? 2哪些STM32配有LPTIM定時器 在STM32中,相對較新推出的MCU部分型號配有LPTIM定時器。 比如:STM32F7、H7高性能MCU,STM32L0、 L4低功耗MCU,以及最新推出的G0系列中配有這種LPTIM定時器。 具體哪些MCU配有LPTIM,大家可以下載對應的數據手冊查看。
[單片機]
LPTIM低功耗<font color='red'>定時器</font>有哪些獨特功能?
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 曲沃县| 吴桥县| 华容县| 柏乡县| 毕节市| 开原市| 马公市| 米泉市| 新宁县| 博野县| 临桂县| 石景山区| 都匀市| 望城县| 沙湾县| 洛宁县| 孟州市| 高要市| 阳泉市| 济宁市| 凌云县| 徐汇区| 剑川县| 南京市| 宝清县| 合川市| 德钦县| 苏尼特右旗| 新巴尔虎左旗| 兖州市| 化州市| 龙川县| 洪江市| 来宾市| 乡城县| 叶城县| 车险| 保德县| 于田县| 报价| 尚志市|