春節不停更,此文正在參加「星光計劃-春節更帖活動」https://harmonyos.51cto.com/posts/9923
(OpenHarmony3.1Beta喂狗使用者态源碼解讀
一、使用者代碼分析
1.程式等待ko加載建立字元裝置
WaitAtStartup("/dev/watchdog");
#define WAIT_MAX_COUNT 10
static void WaitAtStartup(const char *source)
{
unsigned int count = 0;
struct stat sourceInfo;
unsigned int waitTime = 500000;
do {
usleep(waitTime);
count++;
} while ((stat(source, &sourceInfo) < 0) && (errno == ENOENT) && (count < WAIT_MAX_COUNT));
if (count == WAIT_MAX_COUNT) {
INIT_LOGE("wait for file:%s failed after %f.", source, WAIT_MAX_COUNT>>1);
}
return;
}
程式起來等待喂狗KO加載建立/dev/watchdog 5s的時間
2.喂狗程式
int interval = 0;
if (argc >= 2) { // Argument nums greater than or equal to 2.
interval = atoi(argv[1]);
}
interval = (interval > 0) ? interval : DEFAULT_INTERVAL;
int gap = 0;
if (argc >= 3) { // Argument nums greater than or equal to 3.
gap = atoi(argv[2]); // 2 second parameter.
}
gap = (gap > 0) ? gap : DEFAULT_GAP;
INIT_LOGI("watchdoge started (interval %d, margin %d), fd = %d\n", interval, gap, fd);
// 兩個入參之和為使用者态喂狗逾時時間
int timeoutSet = interval + gap;
int timeoutGet = 0;
int ret = ioctl(fd, WDIOC_SETTIMEOUT, &timeoutSet);
if (ret) {
INIT_LOGE("Failed to set timeout to %d\n", timeoutSet);
}
ret = ioctl(fd, WDIOC_GETTIMEOUT, &timeoutGet);
if (ret) {
INIT_LOGE("Failed to get timeout\n");
} else {
// 使用者态設定喂狗逾時時間為大于gap 使用者态喂狗間隔時間為
// 擷取核心的逾時間 - gap,如果小于gap 使用者态喂狗逾時時間為1s
interval = (timeoutGet > gap) ? (timeoutGet - gap) : 1;
}
while (1) {
ioctl(fd, WDIOC_KEEPALIVE);
sleep(interval);
}
close(fd);
fd = -1;
return -1;
}
二、喂狗流程
加載喂狗KO ——> 建立/dev/watchdog
——> 注冊核心函數接口open,ioctl,release
——> 建立核心喂狗線程hidog,并以30.01s喂狗
——> 使用者态等待/dev/watchdog建立
——> 設定和擷取逾時時間,并計算使用者态喂狗時間間隔
——> 以計算的喂狗時間間隔喂狗
如果使用者态設定的喂狗時間超過30s,那麼使用者态喂狗程式退出不會影響核心線程喂狗,系統不會重新開機。
想了解更多關于鴻蒙的内容,請通路:
51CTO和華為官方戰略合作共建的鴻蒙技術社群
https://harmonyos.51cto.com/#bkwz