MCU看门狗使用注意事项
前言
最近因为项目产品硬件设计有问题,导致设计的一款产品把硬件电源开关以及硬件系统复位功能去掉了。更严重的是,这产品已经开始生产了,硬件已经无法修改,所以软件必须上看门狗,否则设备死机或是异常后就只能拆设备拔电池复位了。
我们使用的MCU是普冉的PY32F030,这颗芯片在低功耗应用场景下,使用看门狗会有很多的问题和缺陷,需要非常注意,稍有不慎,就会出问题。
关于看门狗在低功耗场景下的应用,几个问题点可以提前思考一下:
- 看门狗是在中断中喂狗还是在主程序中喂狗比较好?
- 看门狗初始化可以放到时钟初始化之前么?
- 如果时钟死掉了,看门狗还能正常工作么?
- 低功耗深度休眠后还需要喂狗么?如果需要,要怎么设计?使用什么唤醒设备喂狗?
- 软件独立看门狗与硬件独立看门狗它们有什么区别?
- 在看门狗初始化之前系统异常了会怎样?
- 选项字节里开启硬件看门狗与软件代码开启有什么区别?
- 如果异常不可避免,有没一个地方可以缓存设备状态,系统异常复位后状态不被清除
(一)看门狗分类
看门狗的分类,根据实现方式的不同,可以分为软件看门狗和硬件看门狗:
- 软件看门狗:通过软件实现的一种机制,通常由系统中的软件来设置和管理
- 硬件看门狗: 嵌入在处理器或芯片中的专用硬件模块
根据使用方式的不同,又可以区分为独立看门狗和窗口看门狗
独立看门狗: 独立看门狗通常用于监控整个系统的运行状态,而不特定于某个任务或进程,当系统故障,死锁,无响应的时候,应用程序无法进行正常喂狗,看门狗超时从而产生复位。
窗口看门狗: 窗口看门狗更专注于监控特定任务或进程的运行状态,并在特定的时间窗口内完成。比如在某个任务中,它的执行时间要求非常高,可以使用窗口看门狗,它有一个时间窗口,如果太早喂狗和太晚喂狗,都会产生异常,正因为它喂狗时间有个时间窗口,所以才叫窗口看门狗。
我使用的普冉PY32F030系列MCU,它是32位Cortex-M0+的内核,里面带有一个独立看门狗IWDG和一个窗口看门狗WWDG。
其中,独立看门狗和窗口看门狗,还有软件和硬件的区别,主要差异是在看门狗的启动方式上不同。下面我们的介绍,主要针对独立看门狗。

(二)启动看门狗
看门狗的启动有多种方式:
- 通过接口设置启动
- 直接设置寄存器启动
- 设置选项字节启动
(1)通过接口设置
这里可以直接参考官方sample进行初始化:
IWDG_HandleTypeDef IwdgHandle;
HAL_Init();
/*##-3- Configure & Start the IWDG peripheral #########################################*/
IwdgHandle.Instance = IWDG;
IwdgHandle.Init.Prescaler = IWDG_PRESCALER_32;//T=1MS
IwdgHandle.Init.Reload = (1000); //1ms*1000=1s
IwdgHandle.Init.Window = IWDG_WINDOW_DISABLE;
if(HAL_IWDG_Init(&IwdgHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
这里需要特别注意,因为IWDG是依赖于LSI时钟的,也就是在HAL_IWDG_Init 函数调用之前,必须先打开LSI时钟。
官方给的sample中,是在HAL_Init()中把LSI时钟打开了。当你把上面这段代码移植到你自己工程上,如果你LSI没有开启,或者是在HAL_IWDG_Init后面才开LSI时钟,你调用HAL_IWDG_Init就会一直失败,系统一直ERROR,整个MCU会启动不了。
(2)通过寄存器直接设置
直接往 IWDG_SR,IWDG_RLR,IWDG_KR三个寄存器地址写入对应的参数,使能IWDG
void init_wtd(void)
{
volatileu int32_t *IWDG_KR_ADDR = (volatileuint32_t *)0x40003000UL;
volatileu int32_t *IWDG_PR_ADDR = (volatileuint32_t *)0x40003004UL;
volatileu int32_t *IWDG_RLR_ADDR = (volatileuint32_t *)0x40003008UL;
*IWDG_KR_ADDR = 0x5555;
*IWDG_PR_ADDR = 0x03;
*IWDG_RLR_ADDR = 0xF40;
}
实际IWDG是有四个寄存器,还有一个IWDG_PR,它与前面一样,如果不初始化时钟,看门狗会启动不了,就算是设置了,看门狗也是不会启动。
如果要使能时钟,可以添加时钟设置语句:
SET_BIT(RCC->CSR, RCC_CSR_LSION);
直接设置寄存器有一个好处,就是在boot中, 因为对代码量要求比较高,可以比较精简的实现功能
(3)通过选项字节配置
MCU上内部有一个小的flash,里面有个FLASH user option,在这里面可以设置MCU的一些配置参数

这个参数是可以通过烧录器在烧录的时候就把参数配置进去,对于已经烧录的设备,可以通过写选项字节的方式把IWDG_SW置位或是清零。
void Option_config_NRST_to_gpio_hwwdg(void)
{
FLASH_OBProgramInitTypeDef OBInitCfg;
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
/* 初始化flash擦写时间参数 */
HAL_FLASH_Init(FLASH_PROGRAM_ERASE_CLOCK_8MHZ);
/* 获取option bytes数据 */
HAL_FLASHEx_OBGetConfig(&OBInitCfg);
//配置Nreset为GPIO
if(((OBInitCfg.USERConfig & OB_RESET_MODE_GPIO) != OB_RESET_MODE_GPIO)||((OBInitCfg.USERConfig & OB_IWDG_SW) == OB_IWDG_SW))
{
/* 修改 USER(RESET , WWDG, IWDG) 配置值 , 注意一定要3个一起配置*/
OBInitCfg.OptionType = OPTIONBYTE_USER;
MODIFY_REG(OBInitCfg.USERConfig, (OB_RESET_MODE_GPIO|OB_WWDG_SW|OB_IWDG_SW), (OB_RESET_MODE_GPIO | OB_WWDG_SW | OB_IWDG_HW));
/* 启动option byte编程 */
HAL_FLASHEx_OBProgram(&OBInitCfg);
/* 产生一个复位,option byte装载 */
HAL_FLASH_OB_Launch();
}
}
通过选项字节配置了硬件看门狗之后,芯片会自动开启LSI时钟,这个时候,软件要关闭LSI时钟是关闭不了的。
软件独立看门狗与硬件独立看门狗的区别:
- 软件独立看门狗通过软件初始化,可以通过关闭时钟的方式把它关闭了
- 如果在设备上电到看门狗初始化之前系统异常了,看门狗是不生效的,这种情况比较多的出现在软件初始化的时候异常卡死。
- 硬件独立看门狗通过烧录器烧录的时候配置,或者是通过软件程序,修改选项字节里面参数进行修改
- 硬件独立看门狗一但配置上,它从上电的时候就会开始生效,停止不了,除非重新修改配置项参数。
- 硬件独立看门狗开启之后,LSI时钟会自动开启,并且关闭不了。
(三)休眠唤醒喂狗
在低功耗设备中,MCU更加多的时候是在深度睡眠的模式,以达到省功耗的目的。在深度休眠模式下,看门狗还是在正常运行的。
也就是说,在深度休眠模式下,还是需要定时唤醒设备进行喂狗,喂完狗之后,设备再重新进入休眠。
(1)常规方式
官方补充文档上有介绍,在PY32F030、PY32F003、PY32F002A系列上,在休眠前,需要进行下面几个操作:
- 关闭非唤醒源中断
- 关闭系统滴答 HAL_SuspendTick();
- 保证RTC稳定 while(RTC->DIVL<2);
实际在使用的时候,我们比较常用的方式是,使用RTC的秒中断,在休眠的时候,每秒唤醒一下设备,然后进行喂狗操作,最后再休眠下去。
(2)异常情况
实际测试的时候发现,在普冉030使用RTC唤醒喂狗的方式,随着时间的推移,设备会出现异常导致看门狗复位。
我们升级五百台设备,24小时内,会有几台设备偶尔出现该问题,36小时后,大部分的设备基本上都会出现这个异常。
普冉官方的解释是,它们RTC作为唤醒源确实是会存在这个问题,没有好的解决方案,只能是改用LPTIM来做唤醒源。出现这类问题的根本原因是如果休眠的stop指令与唤醒源中断同一时间触发,那么他们芯片就会挂死。
实际使用的时候,使用LPTIM的方式,还是会存在上面的内容,只是出现的概率会比较低而已。
(3)补救方案
上面的异常情况,是设备在产线上才发现的,那要怎么解?客户肯定也是接受不了这种频繁重启的情况,特别是在低功耗设备上。
最后的方式是将RAM进行分区,分出一个IRAM2区,将一些状态位保存在IRAM2区,该区启动的时候不进行初始化,看门狗复位的时候,该区的数据也不会被清除掉。
如果是检测到看门狗异常导致的复位,可以通过保存在状态位信息恢复到复位前的状态。

使用IRAM2区不初始化的方式需要注意一点:如果程序分为boot和app两个部分,需要在boot和app上同时设置该区域,否则可能在boot运行阶段,IRAM2区的数据就被清除掉了。
结尾
针对普冉PY32F030 MCU,如果要使用独立看门狗,需要注意几点:
- 最好是在烧录的时候就直接配置启动硬件看门狗
- 不要使用RTC作为休眠唤醒源进行喂狗
- 最好预留一个IRAM分区,以备不时之需
有些坑,没踩之前并不知道这是一个坑,对于做嵌入式应用软件的工程师而言,他并不知道芯片设计上会存在什么样的缺陷。
如果一颗芯片,价格比别人便宜很多倍,那么在使用的时候就需要特别注意了,为啥它可以做到这么便宜?是不是哪里有坑我们不清楚?就算时间再紧急,最好也要小批量试产之后才能批量使用。
---------------------------End---------------------------如需获取更多内容请关注 liwen01 公众号
MCU看门狗使用注意事项的更多相关文章
- stm32独立看门狗实验
//ALIENTEK Mini STM32开发板V1.9范例代码5//独立看门狗实验//正点原子@ALIENTEK//技术论坛:www.openedv.com STM32F103RBT6属于中容量版本 ...
- 关于Arduino MEGA2560 看门狗对bootloader的依赖
bootloader在Arduino中起着至关重要的位置,arduino-1.5.6-r2版本中的bootloader对看门狗(watchdog)的bug进行了修复:mega2560其实就是使用的AV ...
- 痞子衡嵌入式:聊聊系统看门狗WDOG1在i.MXRT1xxx系统启动中的应用及影响
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是系统看门狗WDOG1在i.MXRT1xxx系统启动中的应用及影响. 软件看门狗模块(WDOG)在 MCU 应用里可以说是非常基础的功能模 ...
- STM32之看门狗(独立与窗口)
广大的互联网网友们,大家早上中午晚上好,我是某某某..对于狗..看过<忠犬八公>的我.无不深深的被狗的义气与灵气所震撼..我也觉得在所有mcu中用看门狗来形容让系统复位的功能是很恰当的.也 ...
- STM32之独立看门狗与窗口看门狗总结
一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...
- MSP430常见问题之看门狗及定时器类
Q1. 定时器两个中断TAIE 和CCIE,有什么区别?两个中断的中断向量一样吗?A1:TAIE 和CCIE指的是不同事件.TAIE指TAR 计数器溢出,从65535 到0 的变化,由TAIFG 引起 ...
- STM32之------独立看门狗(IWDG)和窗体看门狗(WWDG)
一 前沿废语: 之前有很风靡的游戏,名字叫<看门狗>.该游戏用了很新的引擎技术,打造出了一个辽阔庞大的世界,内容是玩家Aiden·Pearce(主角)是一名精通黑客技术的高手,当时 ...
- 看门狗芯片--SP706SEN--调试记录
一.前因后果 工程中,设备为了稳定可靠,会增加外部看门狗,但是外部看门狗一旦启动,就停不下来,必须在固定的时间范围内进行喂狗,不然看门狗芯片就会产生一个复位信号复位MCU.以前大家都认为看门狗一旦工作 ...
- 【转】STM32 独立看门狗简介
STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路就是为了避免这种 ...
- 【iCore4 双核心板_ARM】例程六:IWDG看门狗实验——复位ARM
实验原理: STM32内部包含独立看门狗,通过看门狗可以监控程序远行,程序运行错误时, 未在规定时间内喂狗,自动复位ARM.本实验通过按键按下,停止喂狗,制造程序运行 错误,从而产生复位. 核心代码: ...
随机推荐
- 天地图三维帮助文档(Cesium)
https://blog.csdn.net/Tmraz/article/details/114977652
- 《深入理解Java虚拟机》读书笔记:HotSpot虚拟机对象探秘
基于实用优先的原则,以常用的虚拟机HotSpot和常用的内存区域Java堆为例,深入探讨HotSpot虚拟机在Java堆中对象分配.布局和访问的全过程.以下是本节内容的脑图. HotSpot虚拟机对象 ...
- 免费拥有自己的 Github 资源加速器
TurboHub 是一个免费的 Github 资源加速下载站点,可以帮助你快速下载 Github 上的资源.其核心逻辑是通过 Azure Static Web Apps 服务和 Azure Funct ...
- JaCoCo助您毁灭线上僵尸代码
一. 现状·问题 随着需求不断迭代,业务系统的业务代码突飞猛进,在你自豪于自己的代码量产出很高时,有没有回头看看线上真正的客户使用量又有多少呢? 费事费力耗费大量人力成本上线的功能,可能一年没人使用, ...
- ThreadLocal:线程中的全局变量
最近接了一个新需求,业务场景上需要在原有基础上新增2个字段,接口新增参数意味着很多类和方法的逻辑都需要改变,需要先判断是否属于该业务场景,再做对应的逻辑.原本的打算是在入口处新增变量,在操作数据的时候 ...
- WPF 自定义窗体(一)
.Net默认的窗体样式只有四种:None.SingleBorderWindow.ThreeDBorderWindow.ToolWindow,都比较"丑".而很多时候,我们希望自定义 ...
- 在微服务环境下,远程调用feign和异步线程存在请求数据丢失问题
一.无异步线程得情况下feign远程调用: 0.登录拦截器: @Component public class LoginUserInterceptor implements HandlerInterc ...
- Solution -「洛谷 P3773」「CTSC 2017」吉夫特
Description Link. 求满足 \[\prod _{i=2}^{k} \binom{a_{b_{i-1}}}{a_{b_i}} \mod 2 = \binom{a_{b_1}}{a_{b_ ...
- Thinking in Java 4th Edition Source Code
Thinking in Java 4th Edition Source Code Instructions for downloading, installing and testing the so ...
- Chrome Extensions v3 迁移清单
一.前置问题 1.1为什么需要迁移 v3? Chrome 计划完全停止 v2 版本维护,后续 v2 版本将无法上架谷歌插件商店,除此之外,未来新版本 Chrome 对于 v2 版本插件的限制会越来越大 ...