zephyr筆記 2 2 2 定時器

2021-08-19 13:26:55 字數 3350 閱讀 3288

計時器是乙個核心物件,它使用核心的系統時鐘來度量時間的流逝。 當達到定時器的指定時間限制時,它可以執行應用程式定義的操作,或者它可以簡單地記錄到期並等待應用程式讀取其狀態。

我正在學習 zephyr,乙個很可能會用到很多物聯網裝置上的作業系統,如果你也感興趣,可點此檢視帖子zephyr學習筆記彙總。

可以定義任意數量的定時器。每個定時器都由位址引用。

計時器具有以下關鍵屬性:

定時器必須在使用前初始化。這指定了其到期函式和停止函式值,將定時器的狀態設定為零,並使定時器進入停止狀態。

定時器通過指定持續時間和週期來啟動。定時器的狀態被重置為零,然後定時器進入執行狀態並開始到期的倒計時。

當乙個正在執行的定時器到期時,它的狀態會增加,如果存在到期函式的話會執行到期函式; 如果乙個執行緒正在等待定時器,它將被解除阻塞。 如果定時器的週期為零,則定時器進入停止狀態; 否則定時器會以等於其週期的新持續時間重新啟動。

如果需要,正在執行的計時器可以在倒計時期間中止。定時器的狀態保持不變,然後定時器進入停止狀態並執行其停止函式(如果存在)。如果乙個執行緒正在等待定時器,它將被解除阻塞。試圖停止不執行的計時器是允許的,但它對定時器沒有影響,因為它已經停止。

如果需要,正在執行的定時器可以在倒數計時器中重新啟動。定時器的狀態重置為零,然後定時器使用呼叫者指定的新的持續時間和週期值開始倒計時。如果乙個執行緒正在等待定時器,它將繼續等待。

可以隨時直接讀取定時器的狀態,以確定定時器自上次讀取狀態以來已經過了多少次。讀定時器的狀態會將其值重置為零。定時器到期之前剩餘的時間量也可以讀取;值為零表示定時器已停止。

執行緒可以通過與定時器同步來間接讀取定時器的狀態。這會阻塞執行緒,直到定時器的狀態為非零(表示它至少已經過期)或定時器停止;如果定時器狀態已經非零或定時器已經停止,則執行緒繼續而不等待。同步操作返回定時器的狀態並將其重置為零。

注意:由於讀取狀態(直接或間接)會改變其值,因此只有乙個使用者應該檢查任何給定定時器的狀態。 同樣,一次只有乙個執行緒應該與給定的定時器同步。isr不允許與定時器同步,因為isr不允許被阻塞。
由於定時器基於系統時鐘,因此使用定時器時指定的延遲值為最小值。 (請參閱zephyr筆記 2.2.1 核心時鐘中的時鐘限制章節。)

定時器使用 struct k_timer 型別的變數來定義。 它必須通過呼叫 k_timer_init() 來初始化。

以下**定義並初始化乙個計時器。

struct k_timer my_timer;

extern

void my_expiry_function(struct k_timer *timer_id);

k_timer_init(&my_timer, my_expiry_function, null);

或者,可以通過呼叫k_timer_define在編譯時定義和初始化計時器。

以下**與上面的**段具有相同的效果。

k_timer_define(my_timer, my_expiry_function, null);
以下**使用計時器定期執行重要操作。由於所需工作不能在中斷級完成,因此計時器的到期函式將工作項提交給系統工作佇列,該工作佇列的執行緒執行工作。

void my_work_handler(struct k_work *work)

k_work_define(my_work, my_work_handler);

void my_timer_handler(struct k_timer *dummy)

k_timer_define(my_timer, my_timer_handler, null);

.../* start periodic timer that expires once every second */

k_timer_start(&my_timer, k_seconds(1), k_seconds(1));

以下**直接讀取計時器的狀態以確定計時器是否已過期。

k_timer_define(my_status_timer, null, null);

.../* start one shot timer that expires after 200 ms */

k_timer_start(&my_status_timer, k_msec(200), 0);

/* do work */

.../* check timer status */

if (k_timer_status_get(&my_status_timer) > 0) else

if (k_timer_remaining_get(&my_status_timer) == 0) else

以下**執行定時器狀態同步以允許執行緒執行有用的工作,同時確保一對協議操作按指定的時間間隔分隔。

k_timer_define(my_sync_timer, null, null);

.../* do first protocol operation */

.../* start one shot timer that expires after 500 ms */

k_timer_start(&my_sync_timer, k_msec(500), 0);

/* do other work */

.../* ensure timer has expired (waiting for expiry, if necessary) */

k_timer_status_sync(&my_sync_timer);

/* do second protocol operation */

...

注意:如果執行緒沒有其他工作要做,它可以簡單地在兩個協議操作之間休眠,而不使用定時器。
使用定時器在指定的時間後啟動非同步操作。

使用計時器確定是否已經過了指定的時間量。

使用計時器執行其他工作,同時執行涉及時間限制的操作。

注意:如果乙個執行緒在等待時間通過時沒有其他工作要執行,它應該呼叫k_sleep() 。 如果執行緒需要測量執行操作所需的時間,它可以直接讀取系統時鐘或硬體時鐘,而不是使用定時器。

下列定時器api,都在 kernel.h 中提供了:

k_timer_define

k_timer_init

()k_timer_start

()k_timer_stop

()k_timer_status_get

()k_timer_status_sync

()k_timer_remaining_get

()

定時器 tick 時間輪定時器學習筆記

參考自時間輪的原理和手錶的指標計時類似,將任務結束的時間加入對應最高端的時間輪轉盤中。例如任務結束時間為4 30 20,時間輪盤有三個,分別對應,小時,分鐘和秒。開始時將任務加入4小時所在的時間輪中。四小時過去後,任務的剩餘時間時間為0 30 20就將任務加入30分所在的時間輪中。30分鐘過去後,將...

Mysql 檢視定時器 開啟定時器 設定定時器時間

1.檢視是否開啟evevt與開啟evevt。1.1 mysql evevt功能預設是關閉的,可以使用下面的語句來看evevt的狀態,如果是off或者0,表示是關閉的。show variables like sche 1.2 開啟evevt功能 setglobal event scheduler 1 ...

定時器 STM32定時器 基本定時器1

我是鼎!定時器時鐘一定要明確其中有哪些變數。上圖為stm407資料手冊摘出來的,可能看不清楚,其實就蘊含了幾點資訊。注意一點,我們看圖2,我們以apb1舉例,上面掛著很多的外設,包括usart1 adc 以及定時器,我們知道apb1上面最高時鐘頻率為84mhz,但是定時器的時鐘是要在此基礎上乘2,也...