Driver: WatchDog¶
1 功能概述¶
该sample演示了watchdog的功能。
2 环境要求¶
PAN1080 EVB一块
Micro USB线一条(用于供电和查看串口打印Log)
硬件接线:
使用USB线,将PC USB与EVB MicroUSB(USB->UART)相连
使用杜邦线或跳线帽将EVB上的:
UART1 TX与P06相连
UART1 RX与P07相连
PC软件: 串口调试助手(UartAssist)或终端工具(SecureCRT),波特率921600
3 编译和烧录¶
例程位置:zephyr\samples_panchip\drivers\watchdog
目前可使用ZAL工具或quick build脚本进行编译和下载。
脚本位置:quick_build_samples\drivers\watchdog.bat
打开脚本后默认会编译项目,编译完成时,可输入字符进行后续下载等操作:
Input the keyword to continue:
'b' build 编译项目
'r' make clean and rebuild 重新编译项目
'f' flash download 下载
'e' erase chip 擦除芯片
'o' open project by VS Code 打开 `VS Code`,可查看源码,执行编译下载等
others exit 退出
wait input:
4 演示说明¶
sample在配置并启动watchdog后,每隔50ms进行一次喂狗操作,喂狗5次后,停止喂狗,这时系统会超时复位。
程序正确执行时,日志界面如下(系统因复位会持续打印如下日志):
5 开发说明¶
5.2 初始化watchdog¶
const struct device *wdt = device_get_binding("WDT");
if (!wdt) {
printk("Cannot get WDT device\n");
return;
}
5.3 watchdog配置¶
配置watchdog参数
配置的超时时间必须是宏定义中的值,其他值无效。时间计算公式为:例如宏定义WDT_TIMEOUT_MAX_2POW12,则超时时间为2 ^ 12 * WDT clocks。
struct wdt_timeout_cfg wdt_config = {
/* Reset SoC when watchdog timer expires. */
.flags = WDT_FLAG_RESET_SOC,
/* WDT timeout interrupt callback function. */
.wdt_config.callback = wdt_callback;
/* Expire watchdog after max window, min must be set to 0. */
.window.min = 0U,
.window.max = WDT_MAX_WINDOW,
};
/**
* @brief Install new timeout.
*
* This function must be used before wdt_setup(). Changes applied here
* have no effects until wdt_setup() is called.
*
* @param dev Pointer to the device structure for the driver instance.
* @param cfg Pointer to timeout configuration structure.
*
* @retval channel_id If successful, a non-negative value indicating the index
* of the channel to which the timeout was assigned. This
* value is supposed to be used as the parameter in calls to
* wdt_feed().
* @retval -EBUSY If timeout can not be installed while watchdog has already
* been setup.
* @retval -ENOMEM If no more timeouts can be installed.
* @retval -ENOTSUP If any of the set flags is not supported.
* @retval -EINVAL If any of the window timeout value is out of possible range.
* This value is also returned if watchdog supports only one
* timeout value for all timeouts and the supplied timeout
* window differs from windows for alarms installed so far.
*/
wdt_channel_id = wdt_install_timeout(wdt, &wdt_config);
if (err < 0) {
printk("Watchdog install error\n");
return;
}
5.4 创建watchdog¶
创建watchdog并开始运行
/**
* @brief Set up watchdog instance.
*
* This function is used for configuring global watchdog settings that
* affect all timeouts. It should be called after installing timeouts.
* After successful return, all installed timeouts are valid and must be
* serviced periodically by calling wdt_feed().
*
* @param dev Pointer to the device structure for the driver instance.
* @param options Configuration options as defined by the WDT_OPT_* constants
*
* @retval 0 If successful.
* @retval -ENOTSUP If any of the set options is not supported.
* @retval -EBUSY If watchdog instance has been already setup.
*/
err = wdt_setup(wdt, WDT_OPT_PAUSE_HALTED_BY_DBG);
if (err < 0) {
printk("Watchdog setup error\n");
return;
}
5.5 Feed watchdog¶
实现喂狗操作
/**
* @brief Feed specified watchdog timeout.
*
* @param dev Pointer to the device structure for the driver instance.
* @param channel_id Index of the fed channel.
*
* @retval 0 If successful.
* @retval -EAGAIN If completing the feed operation would stall the
* caller, for example due to an in-progress watchdog
* operation such as a previous @c wdt_feed().
* @retval -EINVAL If there is no installed timeout for supplied channel.
*/
wdt_feed(wdt, wdt_channel_id);
5.6 关闭watchdog¶
关闭watchdog功能
/**
* @brief Disable watchdog instance.
*
* This function disables the watchdog instance and automatically uninstalls all
* timeouts. To set up a new watchdog, install timeouts and call wdt_setup()
* again. Not all watchdogs can be restarted after they are disabled.
*
* @param dev Pointer to the device structure for the driver instance.
*
* @retval 0 If successful.
* @retval -EFAULT If watchdog instance is not enabled.
* @retval -EPERM If watchdog can not be disabled directly by application code.
*/
wdt_disable(wdt);