0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

淺析Linux應(yīng)用開發(fā)之定時器

嵌入式應(yīng)用研究院 ? 來源:TLPI系統(tǒng)編程筆記 ? 2023-04-27 15:29 ? 次閱讀

間隔定時器

#include 

int setitimer(int which,const struct itimerval* new_value,struct itimerval* old_value);

setitimer() 創(chuàng)建一個間隔式定時器,這種定時器會在未來某個時間點到期,并于此后(可選擇地)每間隔一段時間到期一次

which 可以指定以下值:

ITIMER_REAL :創(chuàng)建以真實時間倒計時的定時器,到期會產(chǎn)生 SIGALARM 信號并發(fā)送給進程

ITIMER_VIRTUAL:創(chuàng)建以進程虛擬時間(用戶模式下的 CPU 時間) 倒計時的定時器,到期時會產(chǎn)生信號 SIGVTALRM

ITIMER_PROF:創(chuàng)建一個 profiling 定時器,以進程時間(用戶態(tài)與內(nèi)核態(tài) CPU 時間的總和)倒計時,到期時,則會產(chǎn)生 SIGPROF 信號

針對所有這些信號的默認處置均會終止進程,除非真地期望如此,否則就需要針對這些定時器信號創(chuàng)建處理器函數(shù)。

struct itimerval{
    struct timeval it_interval; /* Interval for periodic timer */
    struct timeval it_value;    /* Current value(time until next expiration) */
};

struct timeval{
    time_t tv_sec;      /* Seconds */
    suseconds_t tv_usec;    /* Microseconds */
};

new_value 下屬的 it_value 指定了距離定時器到期的延遲時間,it_interval 則說明該定時器是否是周期性定時器,如果 it_interval 的兩個字段都是 0,那么該定時器屬于 it_value 所指定的時間間隔后到期的一次性定時器,只要 it_interval 中的任一字段非0,那么在每次定時器到期之后,都會將定時器重置為在指定間隔后再次到期

進程只能擁有上述3種定時器的一種,當?shù)诙握{(diào)用 settimer() 時,修改已有定時器的屬性要符合參數(shù) which 中的類型,如果調(diào)用 setitimer() 時將 new_value.it_value 的兩個字段均設(shè)置為 0,那么會屏蔽任何已有的定時器

若 old_value 不為 NULL,則以其所指向的 itimerval 結(jié)構(gòu)來返回定時器的前一設(shè)置:

如果 old_value.it_value 的兩個字段值均為 0,那么該定時器之前被設(shè)置處于屏蔽狀態(tài)

如果 old_value.it_interval 的兩個字段值均為 0,那么該定時器之前被設(shè)置為歷經(jīng) old_value.it_value 指定時間到期的一次性定時器

對需要在新定時器到期后將其還原的情況而言,獲取定時器的前一設(shè)置就很重要,如果不關(guān)心定時器的前一設(shè)置,可以將 old_value 設(shè)置為 NULL

定時器會從初始值 it_value 倒計時一直到 0 為止,遞減為 0 時,會將相應(yīng)信號發(fā)送給進程,隨后,如果時間間隔值 it_interval 非0,那么會再次將 it_value 加載到定時器,重新開始向 0 倒計時

可以在任何時刻調(diào)用 getitimer(),以了解定時器的當前狀態(tài),距離下次到期的剩余時間:

#include 

int getitimer(int which,struct itimerval* curr_value);

getitimer() 返回由 which 指定定時器的當前狀態(tài),并置于 curr_value 指向的緩沖區(qū)中

使用 setitimer() 和 alarm() 創(chuàng)建的定時器可以跨越 exec() 調(diào)用而得以保存,但由 fork() 創(chuàng)建的子進程并不繼承該定時器。

更為簡單的定時器接口:alarm()

#include 

unsigned int alarm(unsigned int seconds);

seconds 表示定時器到期的秒數(shù),到期時向調(diào)用進程發(fā)送 SIGALRM 信號

調(diào)用 alarm() 會覆蓋對定時器的前一個設(shè)置,調(diào)用 alarm(0) 可以屏蔽現(xiàn)有定時器

返回值是定時器前一設(shè)置距離到期的剩余描述,如果之前并無設(shè)置,則返回 0

setitimer() 和 alarm() 之間的交互

Linux 中 alarm() 和 setitimer() 針對同一進程共享一個實時定時器,無論調(diào)用兩者之中的哪個完成了對定時器的前一設(shè)置,同樣可以調(diào)用二者中的任一函數(shù)來改變這一設(shè)置。

程序設(shè)置實時定時器時,最好選用二者之一。

定時器的調(diào)度和精度

內(nèi)核配置項 CONFIG_HIGH_RES_TIMERS 可以支持高分辨率定時器,使得定時器的精度不受軟件時鐘周期的影響,可以達到底層硬件所支持的精度,在現(xiàn)代硬件平臺上,精度達到微秒級別是司空見慣的。

為阻塞操作設(shè)置超時

實時定時器的用途之一就是為某個阻塞系統(tǒng)調(diào)用設(shè)置其處于阻塞狀態(tài)的時間上限。

例如,處理 read() 操作:

調(diào)用 sigaction() 創(chuàng)建 SIGALRM 信號的處置函數(shù),排除 SA_RESTART 標志以確保系統(tǒng)調(diào)用不會重新啟動

調(diào)用 alarm() 或者 setitimer() 創(chuàng)建定時器,設(shè)置超時時間

執(zhí)行阻塞的系統(tǒng)調(diào)用

系統(tǒng)調(diào)用返回,再次調(diào)用 alarm() 或 setitimer() 屏蔽定時器

檢查系統(tǒng)調(diào)用失敗是否設(shè)置 errno 為 EINTR ,即系統(tǒng)調(diào)用遭到中斷

暫停運行一段固定時間

低分辨率休眠:sleep()

#include 

unsigned int sleep(unsigned int seconds);

sleep() 可以暫停調(diào)用進程執(zhí)行 seconds 秒,或者在捕獲信號后恢復(fù)進程的執(zhí)行

如果休眠正常結(jié)束,返回0,如果因信號中斷休眠,返回剩余的秒數(shù)

考慮到一致性,應(yīng)該避免 sleep() 和 alarm() 以及 setitimer() 之間的混用,Linux 將 sleep() 實現(xiàn)為對 nanosleep() 的調(diào)用,而有些老系統(tǒng)使用 alarm() 和 SIGALRM 信號處理函數(shù)實現(xiàn) sleep()

高分辨率休眠 nanosleep()

#include 

int nanosleep(const struct timespec *req, struct timespec *rem);

nanosleep() 與 sleep() 相似,但是分辨率更高

struct timespec:

struct timespec {
     time_t tv_sec;     /* seconds */
     long  tv_nsec;    /* nanoseconds */
};

規(guī)范規(guī)定不得使用信號實現(xiàn)該函數(shù),這意味著 nanosleep() 與 alarm() 和 setitimer() 混用,也不會危及程序的可移植性

盡管 nanosleep() 沒有使用信號,但還是可以通過信號處理器函數(shù)將其中斷,此時將返回 -1,并設(shè)置錯誤 EINTR,如果 remain 不為 NULL,則該指針所指向的緩沖區(qū)將返回剩余的休眠時間,可以利用這個返回值重啟該系統(tǒng)調(diào)用以完成休眠,但是由于返回的 remain 時間未必是軟件時鐘間隔的整數(shù)倍,故而每次重啟都會遭受取整,其結(jié)果是,每次重啟后的休眠時間都要長于前一調(diào)用返回的 remain 值,在信號接收頻率很高的情況下,進程的休眠可能永遠也結(jié)束不了,使用 TIMER_SBSTIME 選項的 clock_nanosleep() 可以避免這個問題

POSIX 時鐘

Linux 中需要使用 realtime,實時函數(shù)庫,需要鏈接 librt 即需要加入 -lrt 選項。

獲取時鐘的值

#include 

int clock_getres(clockid_t clk_id, struct timespec *res);
int clock_gettime(clockid_t clk_id, struct timespec *tp);

clock_gettime() 針對參數(shù) clk_id 所指定的時鐘返回時間,返回的時間,置于 tp 指向的結(jié)構(gòu)中

clockid_t 是 SUSv3 規(guī)范定義的數(shù)據(jù)類型,用于表示時鐘標識符:

010dcbf8-e4cc-11ed-ab56-dac502259ad0.png

CLOCK_REALTIME 時鐘是一種系統(tǒng)級時鐘,用于度量真實時間,它的設(shè)置是可以變更的

CLOCK_MONOTONIC 時鐘對時間的度量始于"未予規(guī)范的過去某一時間點",系統(tǒng)啟動后就不會改變它,Linux 上,這種時鐘對時間的測量始于系統(tǒng)啟動

CLOCK_PROCESS_CPUTIME_ID 時鐘測量調(diào)用進程所消耗的用戶和系統(tǒng) CPU 時間

CLOCK_THREAD_CPUTIME_ID 時鐘測量調(diào)用線程所消耗的用戶和系統(tǒng) CPU 時間

設(shè)置時鐘的值

#define _POSIX_C_SOURCE 199309L
#include 

int clock_settime(clockid_t clk_id, const struct timespec *tp);

clock_settime() 利用 tp 指向緩沖區(qū)中的時間來設(shè)置由 clockid 指定的時鐘

如果 tp 指向的時間并非 clock_getres() 所返回的時鐘分辨率的整數(shù)倍,時間會向下取整

特權(quán)級進程可以設(shè)置 CLOCK_REALTIME 時鐘,該時鐘的初始值通常自 Epoch 以來的時間,其他時鐘類型不可更改

獲取特定進程或線程的時鐘 ID

要測量特定進程或線程消耗的 CPU 時間,首先要獲取其時鐘 ID:

#define _XOPEN_SOURCE 600
#include 

int clock_getcpuclockid(pid_t pid, clockid_t *clock_id);

clock_getcpuclockid 將隸屬于 pid 進程的 CPU 時間時鐘的標識符置于 clock_id 指針指向的緩沖區(qū)中

#define _XOPEN_SOURCE 600
#include 
#include 

int pthread_getcpuclockid(pthread_t thread, clockid_t *clock_id);

pthread_getcpuclockid() 是 clock_getcpuclockid() 的 POSIX 線程版,返回的標識符所標識的時鐘用于度量調(diào)用進程中指定線程消耗的 CPU 時間

高分辨率休眠的改進版

#define _XOPEN_SOURCE 600
#include 

int clock_nanosleep(clockid_t clock_id, int flags,const struct timespec *request,struct timespec *remain);

默認情況下,flags 是0,request 指定的休眠間隔時間是相對時間,如果 flags 設(shè)置為 TIMER_ABSTIME ,request 則表示 clock_id 所測量的絕對時間,這個特性對于需要精確休眠一段指定時間的應(yīng)用程序至關(guān)重要,以相對時間進行休眠,進程可能執(zhí)行到一半就被占先了,結(jié)果休眠的時間要比預(yù)期的久

對于那些被信號處理器中斷并使用循環(huán)重啟休眠的進程來說,"嗜睡" 問題尤其明顯,如果以高頻接收信號,那么按相對時間休眠的進程在休眠時間上會有較大誤差,可以通過如下方式避免嗜睡:

先調(diào)用 clock_gettime() 獲取時間,再加上期望休眠的時間量

再以 TIMER_ABSTIME 標志調(diào)用 clock_nanosleep() 函數(shù),指定了 TIME_ABSTIME 時,不需要使用參數(shù) remain

信號處理器程序中斷了 clock_nanosleep() 調(diào)用,再次調(diào)用該函數(shù)來重啟休眠時,request 參數(shù)不變

struct timespec request;

if(clock_gettime(CLOCK_REALTIME,&request) == -1)
    errExit("clock_gettime");

request.tv_sec += 20;  /* sleep for 20 seconds from now*/

s = clock_nanosleep(CLOCK_REALTIME,TIMER_ABSTIME,&request,NULL);
if(s != 0)
{
    if(s == EINTR)
        printf("Interrupted by signal handler
");
    else 
        errExit("clock_nanosleep");
}

POSIX 間隔式定時器

使用 settimer() 來設(shè)置經(jīng)典 UNIX 間隔式定時器,會收到如下制約:

針對 ITIMER_REAL,ITIMER_VIRTUAL 和 ITIMER_PROF 這 3 類定時器,每種智能設(shè)置一個

只能通過發(fā)送信號的方式通知定時器到期,另外也不能改變到期時產(chǎn)生的信號

如果一個間隔式定時器到期多次,且相應(yīng)信號遭到阻塞時,那么會只調(diào)用一次信號處理器函數(shù),換言之,無從知曉是否出現(xiàn)定時器溢出的情況

定時器的分辨率只能達到微秒級

POSIX.1b 定義了一套 API 來突破這些限制,主要包含如下幾個階段:

timer_create() 創(chuàng)建一個新的定時器,并定義其到期時對進程的通知方法

timer_settime() 啟動或者停止一個定時器

timer_delete() 刪除不再需要使用的定時器

fork() 創(chuàng)建的子進程不會繼承 POSIX 定時器,調(diào)用 exec() 期間亦或是進程終止時將停止并刪除定時器。

使用 POSIX 定時器的 API 程序編譯時需要使用 -lrt 選項。

創(chuàng)建定時器

#define _POSIX_C_SOURCE 199309L
#include 
#include 

int timer_create(clockid_t clockid, struct sigevent *sevp,timer_t *timerid);

timer_create() 創(chuàng)建一個新的定時器,并以 clockid 指定的時鐘進行時間度量

clockid 可以是 SUSv3 規(guī)范定義的類型,也可以采用 clock_getcpuclockid() 或 pthread_getcpuclockid() 返回的 clockid 值

函數(shù)返回時,timerid 指向的緩沖區(qū)放置定時器句柄,供后續(xù)調(diào)用中指代該定時器之用

sevp 可決定定時器到期時,對應(yīng)應(yīng)用程序的通知方式,指向 struct sigevent:

union sigval {      /* Data passed with notification */
   int   sival_int;     /* Integer value */
   void  *sival_ptr;     /* Pointer value */
};

struct sigevent {
   int      sigev_notify; /* Notification method */
   int      sigev_signo;  /* Notification signal */
   union sigval sigev_value;  /* Data passed with notification */
   void    (*sigev_notify_function) (union sigval);  /* Function used for thread notification (SIGEV_THREAD) */
   void     *sigev_notify_attributes;   /* Attributes for notification thread (SIGEV_THREAD) */
   pid_t     sigev_notify_thread_id;    /* ID of thread to signal (SIGEV_THREAD_ID) */
};

sigev_notify 字段的值:

0119f680-e4cc-11ed-ab56-dac502259ad0.png

SIGEV_NONE:不提供定時器的到期通知,進程可以使用 timer_gettime() 來監(jiān)控定時器的運轉(zhuǎn)情況

SIGEV_SIGNAL:定時器到期時,為進程生成指定于 sigev_signo 中的信號,如果 sigev_signal 為實時信號,那么 sigev_value 字段則指定了信號的伴隨數(shù)據(jù),通過 siginfo_t 結(jié)構(gòu)的 si_value 可獲取這一數(shù)據(jù)

SIGEV_THREAD:定時器到期時,會調(diào)用由 sigev_notify_function 字段指定的函數(shù),調(diào)用該函數(shù)類似于調(diào)用新線程的啟動函數(shù)

SIGEV_THREAD_ID:與 SIGEV_THREAD 相類似,只是發(fā)送信號的目標線程 ID 要與 sigev_notify_thread_id 相匹配

配備和解除定時器

#define _POSIX_C_SOURCE 199309L
#include 

int timer_settime(timer_t timerid, int flags,const struct itimerspec *new_value,struct itimerspec *old_value);

timer_settime() 的參數(shù) timerid 是一個定時器句柄,由之前對 timer_create() 的調(diào)用返回

new_value 包含定時器的新設(shè)置,old_value 返回定時器的前一設(shè)置,如果對前一個設(shè)置不感興趣,可以設(shè)置為 NULLL

struct timespec {
   time_t tv_sec;         /* Seconds */
   long  tv_nsec;        /* Nanoseconds */
};

struct itimerspec {
   struct timespec it_interval;  /* Timer interval */
   struct timespec it_value;   /* Initial expiration */
};

it_value 指定了定時器首次到期的時間,it_interval 任意一個字段非0,那么就是一個周期性定時器,如果都是0,那么這個定時器將只到期一次

flags 如果是0,會將 value.it_value 視為始于 timer_settime() 調(diào)用時間點的相對值,如果 flags 設(shè)為 TIMER_ABSTIME,那么 value.it_value 則是一個絕對時間

為了啟動定時器,需要調(diào)用函數(shù) timer_settime(),并將 value.it_value 的一個或者全部字段設(shè)置為非0,如果之前曾經(jīng)配備過定時器,則 timer_settime() 會將之前的設(shè)置值替換掉

如果定時器的值和間隔時間并非對應(yīng)時鐘分辨率的整數(shù)倍,那么會對這些值向上取整

要解除定時器,需要調(diào)用 timer_settime(),并將 value.it_value 的所有字段設(shè)置為 0

獲取定時器的當前值

#define _POSIX_C_SOURCE 199309L
#include 

int timer_gettime(timer_t timerid, struct itimerspec *curr_value);

timer_gettime() 返回由 timerid 指定的 POSIX 定時器的間隔以及剩余時間

如果返回結(jié)構(gòu) curr_value.it_value 的兩個字段都是0,表示定時器處于停止狀態(tài),如果 curr_value.it_interval 的兩個字段都是0,那么該定時器僅在 curr_value.it_value 給定的時間到期過一次

刪除定時器

每個 POSIX 定時器都會消耗少量的系統(tǒng)資源,一旦使用完畢,應(yīng)當及時釋放這些資源:

#define _POSIX_C_SOURCE 199309L
#include 

int timer_delete(timer_t timerid);

對于已啟動的定時器,會在移除之前自動將其停止

進程終止時,會自動刪除所有定時器

通過信號發(fā)出通知

如果選擇通過信號來接收定時器通知,那么處理這些信號時既可以采用信號處理器函數(shù),也可以調(diào)用 sigwaitinfo() 或是 sigtimerdwait()。接收進程借助于這兩種方法可以獲取一個 siginfo_t 結(jié)構(gòu):

si_signo:包含由定時器產(chǎn)生的信號

si_code:置為 SI_TIMER,表示這是因為 POSIX 定時器到期而產(chǎn)生的信號

si_value:設(shè)置為以 timer_create()創(chuàng)建定時器在 evp.sigev_value 中提供的值

為 evp.sigev_value 指定不同的值,可以將到期時發(fā)送同類信號的不同定時器區(qū)分開。

Linux 還為 siginfo_t 結(jié)構(gòu)提供了如下非標準字段:

si_overrun:包含了定時器溢出個數(shù)

定時器溢出

假設(shè)已經(jīng)選擇通過信號傳遞的方式來接收定時器到期的通知。在捕獲或接收相關(guān)信號之前定時器到期多次,或者不論直接調(diào)用 sigprocmask() 還是在信號處理器函數(shù)中暗中處理,也都有可能堵塞相關(guān)信號的發(fā)送,那如何知道這些定時器溢出?

接收到定時器信號之后,有兩種方法可以獲取定時器的溢出值:

調(diào)用 timer_getoverrun()

使用隨信號一同返回的結(jié)構(gòu) siginfo_t 中的 si_overrun 字段值,這種方法可以避免 timer_getoverrun() 調(diào)用開銷,但是這種方法是 Linux 擴展方法,無法移植

#define _POSIX_C_SOURCE 199309L
#include 

int timer_getoverrun(timer_t timerid);

每次收到定時器信號后,都會重置定時器溢出計數(shù),若自處理或接收定時器信號之后,定時器僅到期一次,則溢出計數(shù)為 0

返回由參數(shù) timerid 指定的定時器的溢出值

timer_getoverrun() 是異步信號安全的函數(shù),故而在信號處理器函數(shù)內(nèi)部調(diào)用也是安全的

通過線程來通知

SIGEV_THREAD 標志允許程序從一個獨立的線程中調(diào)用函數(shù)來獲取定時器到期通知。

利用文件描述符進行通知的定時器

Linux 內(nèi)核特有的創(chuàng)建定時器的 timerfd API,可從文件描述符中讀取其所創(chuàng)建定時器的到期通知。

#include 

int timerfd_create(int clockid, int flags);

timerfd_create() 創(chuàng)建一個新的定時器對象,并返回一個指代該對象的文件描述符

clockid 的值,可以是:CLOCK_REALTIME 或者 CLOCK_MONOTONIC

flags 最初必須設(shè)置為0現(xiàn)在支持:

TFD_CLOEXEC:為新的文件描述符設(shè)置運行時關(guān)閉標志 FD_CLOEXEC 與 open() 的 O_CLOEXEC 適用于相同的情況

TFD_NONBLOCK:為底層的打開文件描述符設(shè)置 O_NONBLOCK 標志,隨后的讀操作將是非阻塞的

timerfd_create() 創(chuàng)建的定時器使用完畢后,應(yīng)該調(diào)用 close() 關(guān)閉相應(yīng)的文件描述符,以便內(nèi)核釋放相應(yīng)的資源

#include 

int timerfd_settime(int fd, int flags,const struct itimerspec *new_value,struct itimerspec *old_value);

timerfd_settime() 可以啟動或解除由文件描述符 fd 指代的定時器

new_value 為指定的新設(shè)置,old_value 為前一設(shè)置,如果不關(guān)心前一個設(shè)置可以將其設(shè)置為 NULL

flags 參數(shù)可以是0,此時將 new_value.it_value 的值視為相對于調(diào)用 timerfd_settime() 的相對時間點,也可以設(shè)置為 TFD_TIMER_ABSTIME 將其視為從時鐘0點開始測量的絕對時間點

#include 

int timerfd_gettime(int fd, struct itimerspec *curr_value);

timerfd_gettime() 返回文件描述符 fd 所標識的定時器間隔和剩余時間

如果返回的 curr_value.it_value 字段都是0,那么該定時器已經(jīng)被解除,如果返回的結(jié)構(gòu) curr_value.it_interval 中的兩個字段都是0,那么定時器只會到期一次,到期時間在 curr_value.it_value 中給出

timerfd 與 fork() 以及 exec() 之間的交互

調(diào)用 fork() 期間,子進程會繼承 timerfd_create() 所創(chuàng)建的文件描述符的拷貝。

timerfd_create() 創(chuàng)建額度文件描述符能夠跨越 exec() 得以保存,除非將描述符設(shè)置為運行時關(guān)閉,已配備的定時器在 exec() 之后會繼承生成到期通知。

從 timerfd 文件描述符讀取

一旦以 timer_settime() 啟動了定時器,就可以從相應(yīng)文件描述符中調(diào)用 read() 來讀取定時器的到期信息,處于這一目的,傳給 read() 的緩沖區(qū)必須滿足容納一個 uint64_t 類型的要求。

在上次使用 timerfd_settime() 修改設(shè)置以后,或者是最后一次執(zhí)行 read() 后,如果發(fā)生了一起或多起定時器到期時間,那么 read() 立即返回,返回的緩沖區(qū)中包含了到期的次數(shù)。

如果并無定時器到期,read() 將會阻塞至下一個到期。

也可以執(zhí)行 fcntl() 設(shè)置 O_NONBLOCK 標志,這時的讀動作將是非阻塞的,如果沒有定時器到期,則返回,設(shè)置錯誤 EAGAIN。

可以使用 select(),poll() 和 epoll() 對 timerfd 文件描述符進行監(jiān)控,如果定時器到期,則將對應(yīng)的文件描述符標記為可讀。





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 處理器
    +關(guān)注

    關(guān)注

    68

    文章

    19102

    瀏覽量

    228819
  • 定時器
    +關(guān)注

    關(guān)注

    23

    文章

    3232

    瀏覽量

    114331
  • Linux開發(fā)
    +關(guān)注

    關(guān)注

    0

    文章

    31

    瀏覽量

    6884

原文標題:Linux應(yīng)用開發(fā)之定時器

文章出處:【微信號:嵌入式應(yīng)用研究院,微信公眾號:嵌入式應(yīng)用研究院】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Linux驅(qū)動開發(fā)-內(nèi)核定時器

    內(nèi)核定時器是內(nèi)核用來控制在未來某個時間點(基于jiffies(節(jié)拍總數(shù)))調(diào)度執(zhí)行某個函數(shù)的一種機制,相關(guān)函數(shù)位于 和 kernel/timer.c 文件
    的頭像 發(fā)表于 09-17 15:06 ?1415次閱讀

    手把手教你寫Linux設(shè)備驅(qū)動---定時器(一)(基于友善臂4412開發(fā)板)

    手把手教你寫Linux設(shè)備驅(qū)動---定時器(一)(基于友善臂4412開發(fā)板)
    發(fā)表于 12-02 15:59

    Linux下實時定時器的實現(xiàn)及應(yīng)用

    在嵌入式平臺的開發(fā)過程中,由于控制硬件的要求,常常需要提供精度在μs級的定時器;而linux內(nèi)核由于采用了分時系統(tǒng),一般不提供這種級別的定時器。筆者在
    發(fā)表于 04-16 09:19 ?36次下載

    學(xué)單片機定時器部分

    帶您從零學(xué)單片機定時器部分 課程簡介1定時器/計數(shù)簡介2定時器/計數(shù)特殊功能寄存
    發(fā)表于 02-10 14:20 ?49次下載

    【實驗38】定時器定時

    HL配套C實驗例程100例定時器定時,配合開發(fā)板學(xué)習(xí)效果更好。
    發(fā)表于 04-11 16:09 ?7次下載

    HL配套C實驗例程100例定時器定時常用參數(shù)

    HL配套C實驗例程100例定時器定時常用參數(shù),配合開發(fā)板學(xué)習(xí)效果更好。
    發(fā)表于 04-11 16:09 ?3次下載

    PIC32系列參考手冊定時器

    本文主要介紹了PIC32系列參考手冊定時器。
    發(fā)表于 06-06 17:29 ?9次下載

    PIC32系列參考手冊看門狗定時器、程序監(jiān)控定時器和上電延時定時器

    本文主要介紹了PIC32系列參考手冊看門狗定時器、程序監(jiān)控定時器和上電延時定時器
    發(fā)表于 06-06 17:29 ?15次下載

    51單片機定時器\計數(shù)的工作原理

    51單片機定時器\計數(shù)的工作原理定時器/計數(shù)的結(jié)構(gòu):何時處于計數(shù)方式?何時處于
    發(fā)表于 11-11 11:36 ?10次下載
    51單片機<b class='flag-5'>之</b><b class='flag-5'>定時器</b>\計數(shù)<b class='flag-5'>器</b>的工作原理

    STM32定時器-基本定時器

    目錄定時器分類基本定時器功能框圖講解基本定時器功能時鐘源計數(shù)時鐘計數(shù)自動重裝載寄存
    發(fā)表于 11-23 18:21 ?31次下載
    STM32<b class='flag-5'>定時器</b>-基本<b class='flag-5'>定時器</b>

    ESP32 ESP-IDF 教學(xué)(三)——通用硬件定時器(Timer)

    ESP32 ESP-IDF 學(xué)習(xí)筆記(三)【通用硬件定時器(Timer)】文章目錄ESP32 ESP-IDF 學(xué)習(xí)筆記(三)【通用硬件定時器(Timer)】通用硬件
    發(fā)表于 11-26 11:36 ?37次下載
    ESP32 <b class='flag-5'>之</b> ESP-IDF 教學(xué)(三)——通用硬件<b class='flag-5'>定時器</b>(Timer)

    詳細剖析Linux和RTOS(RT-Thread)的時鐘和定時器的使用

    Linux發(fā)燒友1.RTOS篇1.1RT-Thread簡介1.2時鐘管理1.2.1時鐘節(jié)拍1.3獲取系統(tǒng)節(jié)拍1.4定時器分類1.5定時器源碼分析1.6定時器相關(guān)函數(shù)1.61動態(tài)創(chuàng)建一個
    發(fā)表于 01-17 09:31 ?4次下載
    詳細剖析<b class='flag-5'>Linux</b>和RTOS(RT-Thread)的時鐘和<b class='flag-5'>定時器</b>的使用

    淺析怎么在Linux上使用cron定時器

    如何在 Linux 上使用 cron 定時器 1創(chuàng)建一個 cronjob 要創(chuàng)建一個 cronjob,你可以使用 crontab 命令,并添加 -e 選項。
    的頭像 發(fā)表于 01-30 11:37 ?1325次閱讀

    Linux驅(qū)動開發(fā)高精度定時器的精度測量評測

    正點原子的示波器能不能支撐嵌入式開發(fā)流程。 Linux高精度定時器說明 其實傳統(tǒng)的低分辨率定時器隨著技術(shù)的演進,已經(jīng)無法滿足開發(fā)需求。而且硬
    的頭像 發(fā)表于 08-09 11:17 ?1998次閱讀

    Linux內(nèi)核定時器

    Linux內(nèi)核中,也可以通過定時器來完成定時功能。但和單片機不同的是,Linux內(nèi)核定時器是一種基于未來時間點的計時方式,它以當前時刻為啟
    的頭像 發(fā)表于 09-22 08:56 ?1851次閱讀
    <b class='flag-5'>Linux</b>內(nèi)核<b class='flag-5'>定時器</b>