nRF52832看门狗WDT使用(SDK17.1.0)

陈拓 2022/10/29-2022/10/31

1. 开发环境

  • 操作系统: Window10、WSL
  • 编译环境: ARM GCC
  • IDE: VSCode
  • SDK版本: SDK_17.1.0
  • 硬件开发板: 定制
  • 开发环境构建

《WSL构建nRF5 SDK + ARM GCC开发环境》

https://blog.csdn.net/chentuo2000/article/details/125933307?spm=1001.2014.3001.5502

《WSL构建nRF5 SDK + ARM GCC开发环境 – RTT打印调试日志》

https://blog.csdn.net/chentuo2000/article/details/126104346?spm=1001.2014.3001.5502

2. 看门狗WDT概述

  • 硬件的看门狗,防止应用程序锁定。
  • 使用32.768kHz低频时钟源(LFCLK)

看门狗启动后,若芯片外部没有焊接32.768kHz的晶体,芯片会自动启动内部RC振荡器。

  • CRV寄存器指定计数值
  • 看门狗启动后加载 CRV 寄存器中的值
  • 倒计时,向下计数器到0后,会溢出产生 TIMEOUT 事件。看门狗 TIMEOUT 事件会导致系统复位 或者 TIMEOUT 中断。
  • 在程序正常运行时,应该在向下计数器数还未到0时重置计数器(喂狗)
  • 当CPU在低功耗模式处于睡眠状态时,或调试过程中暂停CPU运行时,看门狗可以暂停
  • 看门狗的超时时间由以下公式给出

timeout [s] = ( CRV + 1 ) / 32768

3. 看门狗WDT使用

3.1 sdk_config.h设置

~/nrf/nRF5_SDK_17.1.0_ddde560/examples/peripheral/wdt/pca10040/blank/config/sdk_config.h

// <e> NRFX_WDT_ENABLED - nrfx_wdt - WDT 外设驱动
//==========================================================
#ifndef NRFX_WDT_ENABLED
#define NRFX_WDT_ENABLED 1
#endif
// <o> NRFX_WDT_CONFIG_BEHAVIOUR  - CPU SLEEP或HALT模式下的WDT行为 
// <1=> 在睡眠状态下运行,在挂起状态下暂停 
// <8=> 在睡眠状态下暂停,在挂起状态下运行 
// <9=> 在睡眠和挂起状态下运行
// <0=> 在睡眠和挂起状态下暂停

#ifndef NRFX_WDT_CONFIG_BEHAVIOUR
#define NRFX_WDT_CONFIG_BEHAVIOUR 0
#endif

// <o> NRFX_WDT_CONFIG_RELOAD_VALUE - 重新加载值(毫秒) ms <1-131072000> 

#ifndef NRFX_WDT_CONFIG_RELOAD_VALUE
#define NRFX_WDT_CONFIG_RELOAD_VALUE 2000
#endif

// <o> NRFX_WDT_CONFIG_NO_IRQ  - 从WDT驱动中删除WDT IRQ处理
 
// <0=> 包括WDT IRQ中断处理 
// <1=> 删除WDT IRQ中断处理 

#ifndef NRFX_WDT_CONFIG_NO_IRQ
#define NRFX_WDT_CONFIG_NO_IRQ 0
#endif

// <o> NRFX_WDT_CONFIG_IRQ_PRIORITY  - 中断优先级
 
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef NRFX_WDT_CONFIG_IRQ_PRIORITY
#define NRFX_WDT_CONFIG_IRQ_PRIORITY 6
#endif

// <e> NRFX_WDT_CONFIG_LOG_ENABLED - 启用模块中的日志记录。
//==========================================================
#ifndef NRFX_WDT_CONFIG_LOG_ENABLED
#define NRFX_WDT_CONFIG_LOG_ENABLED 0
#endif
// <o> NRFX_WDT_CONFIG_LOG_LEVEL  - 默认日志级别
 
// <0=> Off 
// <1=> Error 
// <2=> Warning 
// <3=> Info 
// <4=> Debug 

#ifndef NRFX_WDT_CONFIG_LOG_LEVEL
#define NRFX_WDT_CONFIG_LOG_LEVEL 3
#endif

// <o> NRFX_WDT_CONFIG_INFO_COLOR  - ANSI转义代码前缀。
 
// <0=> Default 
// <1=> Black 
// <2=> Red 
// <3=> Green 
// <4=> Yellow 
// <5=> Blue 
// <6=> Magenta 
// <7=> Cyan 
// <8=> White 

#ifndef NRFX_WDT_CONFIG_INFO_COLOR
#define NRFX_WDT_CONFIG_INFO_COLOR 0
#endif

// <o> NRFX_WDT_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.
 
// <0=> Default 
// <1=> Black 
// <2=> Red 
// <3=> Green 
// <4=> Yellow 
// <5=> Blue 
// <6=> Magenta 
// <7=> Cyan 
// <8=> White 

#ifndef NRFX_WDT_CONFIG_DEBUG_COLOR
#define NRFX_WDT_CONFIG_DEBUG_COLOR 0
#endif

3.2 头文件

#include "nrf_drv_wdt.h"
#include "nrf_drv_clock.h"

在nrfx_wdt.h中有头文件nrf_wdt.h的引用:

#include <hal/nrf_wdt.h>
  • Makefile文件添加
  $(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_wdt.c \

3.3 官方例程

  • 使用sdk_config.h设置的默认值初始化
    //Configure WDT.
    nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG;
    err_code = nrf_drv_wdt_init(&config, wdt_event_handler);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_wdt_channel_alloc(&m_channel_id);
    APP_ERROR_CHECK(err_code);
    nrf_drv_wdt_enable();
  • wdt_event_handler是事件触发回调处理函数

看门狗计数器溢出时触发。

/**
 * @brief WDT events handler.
 */
void wdt_event_handler(void)
{
    bsp_board_leds_off();

    //NOTE: The max amount of time we can spend in WDT interrupt is two cycles of 32768[Hz] clock - after that, reset occurs
}
  • 喂狗nrf_drv_wdt_channel_feed(m_channel_id);

在BSP事件触发回调处理函数中:

nrf_drv_wdt_channel_id m_channel_id;

/**
 * @brief BSP events callback.
 */
void bsp_event_callback(bsp_event_t event)
{
    switch (event)
    {
        case BSP_EVENT_KEY_0:
            nrf_drv_wdt_channel_feed(m_channel_id);
            break;

        default :
            //Do nothing.
            break;
    }
}
  • BSP事件触发回调处理函数注册
    err_code = bsp_init(BSP_INIT_BUTTONS, bsp_event_callback);
    APP_ERROR_CHECK(err_code);

3.4 非官方例程

可以在初始化时修改某些sdk_config.h的设置。

    //Configure WDT.
    NRF_LOG_DEBUG("main Configure WDT.");
    nrf_drv_wdt_config_t config = {
        .behaviour          = NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT,
        .reload_value       = 60000,
        .interrupt_priority = 7,
    };
    nrf_drv_wdt_config_t wdt_config = config;
    err_code = nrf_drv_wdt_init(&wdt_config, NULL);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_wdt_channel_alloc(&m_channel_id);
    APP_ERROR_CHECK(err_code);
    nrf_drv_wdt_enable();

其中:

  • 函数f_drv_wdt_init(&wdt_config, NULL);

NULL表示不使用事件触发回调处理函数。

  • 宏RF_WDT_BEHAVIOUR_RUN_SLEEP_HALT

在nrf_wdt.h中定义:

/** @brief WDT behavior in the SLEEP or HALT CPU modes. */
typedef enum
{
    NRF_WDT_BEHAVIOUR_RUN_SLEEP        = WDT_CONFIG_SLEEP_Msk,                       /**< WDT will run when CPU is in SLEEP mode. */
    NRF_WDT_BEHAVIOUR_RUN_HALT         = WDT_CONFIG_HALT_Msk,                        /**< WDT will run when CPU is in HALT mode. */
    NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT   = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */
    NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0,                                          /**< WDT will be paused when CPU is in SLEEP or HALT mode. */
} nrf_wdt_behaviour_t;
  • 喂狗

在主循环中喂狗

    NRF_LOG_INFO("main loop..........");
    for (;;) {
        nrf_drv_wdt_channel_feed(m_channel_id);

参考文档

nRF52832 Product Specification v1.3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晨之清风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值