1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//build 20240425
//看门狗组件,用于监控应用是否卡死,设置一个超时时间,如果超过这个时间没有喂狗,会自动触发设备重启
//注意使用看门狗之前可能需要先初始化gpio
//依赖组件 dxDriver,dxLogger,dxCommon,dxMap,dxGpio
import { watchdogClass } from './libvbar-b-dxwatchdog.so'
import dxMap from './dxMap.js'
import logger from './dxLogger.js'
import dxCommon from './dxCommon.js'
 
const map = dxMap.get("___watchdog")
const watchdogObj = new watchdogClass();
 
const watchdog = {}
watchdog.last = new Date().getTime()
/**
 * 打开看门狗设备
 * @param {number} type 必填
 * @param {string} id 句柄id,非必填(若初始化多个实例需要传入唯一id)
 */
watchdog.open = function (type, id) {
    let pointer = watchdogObj.open(type)
    if (pointer === undefined || pointer === null) {
        throw new Error("watchdog.open: open failed")
    }
    dxCommon.handleId("watchdog", id, pointer)
}
/**
 * 控制指定通道开关
 * @param {number} chan 通道id,必填
 * @param {string} id 句柄id,非必填(需保持和init中的id一致)
 * @returns true/false
 */
watchdog.enable = function (chan, id) {
    let pointer = dxCommon.handleId("watchdog", id)
    return watchdogObj.enable(pointer, chan)
}
/**
 * 开启看门狗总定时器
 * @param {*} timeout 必填
 * @param {string} id 句柄id,非必填(需保持和init中的id一致)
 * @returns true/false
 */
watchdog.start = function (timeout, id) {
    let pointer = dxCommon.handleId("watchdog", id)
    return watchdogObj.start(pointer, timeout)
}
/**
 * 判断是否是上电复位,看门狗是否已经启动
 * @param {string} id 句柄id,非必填(需保持和init中的id一致)
 * @returns true/false
 */
watchdog.isPoweron = function (id) {
    let pointer = dxCommon.handleId("watchdog", id)
    return watchdogObj.isPoweron(pointer)
}
/**
 * 喂狗指定通道
 * @param {*} chan 通道id,必填
 * @param {string} id 句柄id,非必填(需保持和init中的id一致)
 * @returns true/false
 */
watchdog.restart = function (chan, id) {
    let pointer = dxCommon.handleId("watchdog", id)
    return watchdogObj.restart(pointer, chan)
}
/**
 * 关闭看门狗总定时器
 * @param {string} id 句柄id,非必填(需保持和init中的id一致)
 * @returns true/false
 */
watchdog.stop = function (id) {
    let pointer = dxCommon.handleId("watchdog", id)
    return watchdogObj.stop(pointer)
}
/**
 * 关闭看门狗设备
 * @param {string} id 句柄id,非必填(需保持和init中的id一致)
 * @returns true/false
 */
watchdog.close = function (id) {
    let pointer = dxCommon.handleId("watchdog", id)
    return watchdogObj.close(pointer)
}
/**
 * 循环检查每个线程的喂狗情况,任何一个线程没有喂狗,则不启动restart
 * @param {number} chan 通道id,必填
 * @param {string} id 句柄id,非必填(需保持和init中的id一致)
 */
watchdog.loop = function (chan, id) {
    const now = new Date().getTime()
    const minus = now - watchdog.last
    if (minus > 3000 || minus < 0) {//每3秒检查一次或者小于0代表操作了往前改时间
        watchdog.last = now
        let keys = map.keys()
        let check = true
        for (let i = 0; i < keys.length; i++) {
            let key = keys[i]
            let value = map.get(key)
            const temp = now - value.now
            if (temp > value.timeout * 1000 && temp < 1700000000) {
                logger.error(`The worker ${key} did not feed the dog in time.`, temp)
                check = false
                break
            }
        }
        if (check) {
            this.restart(chan, id)
        }
    }
}
/**
 * 不同的线程喂狗
 * @param {string} flag 线程的标识,必填不能为空 
 * @param {number} timeout 线程可以多长时间不喂狗(秒),缺省是10秒
 */
watchdog.feed = function (flag, timeout = 10) {
    if (!flag || flag.length <= 0) {
        return
    }
    map.put(flag, { now: new Date().getTime(), timeout: timeout })
}
 
export default watchdog;