前言

最近因为项目产品硬件设计有问题,导致设计的一款产品把硬件电源开关以及硬件系统复位功能去掉了。更严重的是,这产品已经开始生产了,硬件已经无法修改,所以软件必须上看门狗,否则设备死机或是异常后就只能拆设备拔电池复位了。

我们使用的MCU是普冉的PY32F030,这颗芯片在低功耗应用场景下,使用看门狗会有很多的问题和缺陷,需要非常注意,稍有不慎,就会出问题。

关于看门狗在低功耗场景下的应用,几个问题点可以提前思考一下:

  1. 看门狗是在中断中喂狗还是在主程序中喂狗比较好?
  2. ​看门狗初始化可以放到时钟初始化之前么?
  3. 如果时钟死掉了,看门狗还能正常工作么?
  4. 低功耗深度休眠后还需要喂狗么?如果需要,要怎么设计?使用什么唤醒设备喂狗?
  5. 软件独立看门狗与硬件独立看门狗它们有什么区别?
  6. 在看门狗初始化之前系统异常了会怎样?
  7. 选项字节里开启硬件看门狗与软件代码开启有什么区别?
  8. 如果异常不可避免,有没一个地方可以缓存设备状态,系统异常复位后状态不被清除

(一)看门狗分类

看门狗的分类,根据实现方式的不同,可以分为软件看门狗和硬件看门狗:

  • 软件看门狗:通过软件实现的一种机制,通常由系统中的软件来设置和管理
  • 硬件看门狗: 嵌入在处理器或芯片中的专用硬件模块

根据使用方式的不同,又可以区分为独立看门狗和窗口看门狗

  • 独立看门狗: 独立看门狗通常用于监控整个系统的运行状态,而不特定于某个任务或进程,当系统故障,死锁,无响应的时候,应用程序无法进行正常喂狗,看门狗超时从而产生复位。

  • 窗口看门狗: 窗口看门狗更专注于监控特定任务或进程的运行状态,并在特定的时间窗口内完成。比如在某个任务中,它的执行时间要求非常高,可以使用窗口看门狗,它有一个时间窗口,如果太早喂狗和太晚喂狗,都会产生异常,正因为它喂狗时间有个时间窗口,所以才叫窗口看门狗。

我使用的普冉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时钟是关闭不了的。

软件独立看门狗与硬件独立看门狗的区别

  1. 软件独立看门狗通过软件初始化,可以通过关闭时钟的方式把它关闭了
  2. 如果在设备上电到看门狗初始化之前系统异常了,看门狗是不生效的,这种情况比较多的出现在软件初始化的时候异常卡死。
  3. 硬件独立看门狗通过烧录器烧录的时候配置,或者是通过软件程序,修改选项字节里面参数进行修改
  4. 硬件独立看门狗一但配置上,它从上电的时候就会开始生效,停止不了,除非重新修改配置项参数。
  5. 硬件独立看门狗开启之后,LSI时钟会自动开启,并且关闭不了。

(三)休眠唤醒喂狗

在低功耗设备中,MCU更加多的时候是在深度睡眠的模式,以达到省功耗的目的。在深度休眠模式下,看门狗还是在正常运行的。

也就是说,在深度休眠模式下,还是需要定时唤醒设备进行喂狗,喂完狗之后,设备再重新进入休眠。

(1)常规方式

官方补充文档上有介绍,在PY32F030、PY32F003、PY32F002A系列上,在休眠前,需要进行下面几个操作:

  1. 关闭非唤醒源中断
  2. 关闭系统滴答 HAL_SuspendTick();
  3. 保证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,如果要使用独立看门狗,需要注意几点:

  1. 最好是在烧录的时候就直接配置启动硬件看门狗
  2. 不要使用RTC作为休眠唤醒源进行喂狗
  3. 最好预留一个IRAM分区,以备不时之需

有些坑,没踩之前并不知道这是一个坑,对于做嵌入式应用软件的工程师而言,他并不知道芯片设计上会存在什么样的缺陷。

如果一颗芯片,价格比别人便宜很多倍,那么在使用的时候就需要特别注意了,为啥它可以做到这么便宜?是不是哪里有坑我们不清楚?就算时间再紧急,最好也要小批量试产之后才能批量使用。

---------------------------End---------------------------如需获取更多内容请关注 liwen01 公众号

MCU看门狗使用注意事项的更多相关文章

  1. stm32独立看门狗实验

    //ALIENTEK Mini STM32开发板V1.9范例代码5//独立看门狗实验//正点原子@ALIENTEK//技术论坛:www.openedv.com STM32F103RBT6属于中容量版本 ...

  2. 关于Arduino MEGA2560 看门狗对bootloader的依赖

    bootloader在Arduino中起着至关重要的位置,arduino-1.5.6-r2版本中的bootloader对看门狗(watchdog)的bug进行了修复:mega2560其实就是使用的AV ...

  3. 痞子衡嵌入式:聊聊系统看门狗WDOG1在i.MXRT1xxx系统启动中的应用及影响

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是系统看门狗WDOG1在i.MXRT1xxx系统启动中的应用及影响. 软件看门狗模块(WDOG)在 MCU 应用里可以说是非常基础的功能模 ...

  4. STM32之看门狗(独立与窗口)

    广大的互联网网友们,大家早上中午晚上好,我是某某某..对于狗..看过<忠犬八公>的我.无不深深的被狗的义气与灵气所震撼..我也觉得在所有mcu中用看门狗来形容让系统复位的功能是很恰当的.也 ...

  5. STM32之独立看门狗与窗口看门狗总结

    一.独立看门狗 STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路 ...

  6. MSP430常见问题之看门狗及定时器类

    Q1. 定时器两个中断TAIE 和CCIE,有什么区别?两个中断的中断向量一样吗?A1:TAIE 和CCIE指的是不同事件.TAIE指TAR 计数器溢出,从65535 到0 的变化,由TAIFG 引起 ...

  7. STM32之------独立看门狗(IWDG)和窗体看门狗(WWDG)

    一     前沿废语: 之前有很风靡的游戏,名字叫<看门狗>.该游戏用了很新的引擎技术,打造出了一个辽阔庞大的世界,内容是玩家Aiden·Pearce(主角)是一名精通黑客技术的高手,当时 ...

  8. 看门狗芯片--SP706SEN--调试记录

    一.前因后果 工程中,设备为了稳定可靠,会增加外部看门狗,但是外部看门狗一旦启动,就停不下来,必须在固定的时间范围内进行喂狗,不然看门狗芯片就会产生一个复位信号复位MCU.以前大家都认为看门狗一旦工作 ...

  9. 【转】STM32 独立看门狗简介

    STM32 的独立看门狗由内部专门的 40Khz 低速时钟驱动,即使主时钟发生故障,它也仍然有效. 看门狗的原理:单片机系统在外界的干扰下会出现程序跑飞的现象导致出现死循环,看门狗电路就是为了避免这种 ...

  10. 【iCore4 双核心板_ARM】例程六:IWDG看门狗实验——复位ARM

    实验原理: STM32内部包含独立看门狗,通过看门狗可以监控程序远行,程序运行错误时, 未在规定时间内喂狗,自动复位ARM.本实验通过按键按下,停止喂狗,制造程序运行 错误,从而产生复位. 核心代码: ...

随机推荐

  1. [selenium]相对定位器

    前言 Relative Locators,相对定位器,是Selenium 4引入的一个新的定位器,相对定位器根据源点元素去定位相对位置的其它元素. 相对定位方法其实是基于JavaScript的 get ...

  2. 使用logrotate定期切割nginx日志

    前言 默认情况下,nginx的日志都会写到access.log文件中,访问流量大的话,日志文件很快就会膨胀到几十G,不方便分析处理,也占用硬盘空间.借助linux自带的logrotate工具可以很方便 ...

  3. UI获取元素的几种方式

    通过浏览器驱动获取页面元素的8种方式. 定位方法: 通过webdriver对象的find_element方法 通过 id获取元素 el = driver.find_element(By.ID,'id' ...

  4. 《最新出炉》系列初窥篇-Python+Playwright自动化测试-14-playwright操作iframe-番外篇

    1.简介 通过前边三篇的学习,想必大家已经对iframe有了一定的认识和了解,今天这一篇主要是对iframe的一些特殊情况的介绍和讲解,主要从iframe的定位.监听事件和执行js脚本三个方面进行展开 ...

  5. 2.4 PE结构:节表详细解析

    节表(Section Table)是Windows PE/COFF格式的可执行文件中一个非常重要的数据结构,它记录了各个代码段.数据段.资源段.重定向表等在文件中的位置和大小信息,是操作系统加载文件时 ...

  6. Hadoop单击模式运行wordcount例子

    1.进入Hadoop安装目录 cd /zwy/soft/hadoop-2.7.1 2.创建文件夹input mkdir input 3.写一段文字到文件file.txt echo "hell ...

  7. 在 Net7.0 环境下使用 RestSharp 发送 Http(FromBody和FromForm)请求

    一.简介 最近,在做一个数据传输的服务,我在一个Worker Service里面需要访问 WebAPI 接口,并传输数据,也可以提交数据.由于第一次使用 RestSharp 发送请求,也遇到了很多问题 ...

  8. Springboot简单功能示例-4 自定义加密进行登录验证

    springboot-sample 介绍 springboot简单示例 跳转到发行版 查看发行版说明 软件架构(当前发行版使用) springboot hutool-all 非常好的常用java工具库 ...

  9. 前端框架——Vue2

    文章目录 初识Vue 模板语法 数据绑定 el与data的两种写法 理解MVVM 数据代理 事件处理 计算属性 监视属性 绑定样式 条件渲染 列表渲染 收集表单数据 过滤器 内置指令 自定义指令 生命 ...

  10. the solution of Mining Your Own Business

    the description of problem (我看的是 PDF 里面的原题所以这里描述会和题目不一样,但是大意一致) 给定一个未必连通的无向图,问最少在几个点设置出口,可以保证任意一个点坍塌 ...