使用看门狗功能,一如既往地需要先使用ENV工具,打开看门狗功能,如下图

开启后重新编译工程,

然后当我开开心心地去粘贴官方的demo(WATCHDOG设备 (rt-thread.org))(文章最后会放出我稍微改动的代码) 并编译运行才发现有问题!

在keil工程中检索错误码发现:

这里是一个判断传入的设置喂狗时间的值的大小,如果不在 g_wdt_dev.min_threshold_s和 g_wdt_dev.max_threshold_s之间时候会报错invalid param@%u.,那么我就debug一下看看这个max_threshold_s和min_threshold_s是多少,结果是0

浏览了一下,在这个函数的上面有一个初始化函数 :

static rt_err_t gd32_wdt_init(rt_watchdog_t *wdt)
{rcu_osci_on(RCU_IRC40K);if (ERROR == rcu_osci_stab_wait(RCU_IRC40K)){LOG_E("failed init IRC40K clock for free watchdog.");return -RT_EINVAL;}g_wdt_dev.min_threshold_s = 1;g_wdt_dev.max_threshold_s = (0xfff << 8) / 40000;LOG_I("threshold section [%u, %d]", \g_wdt_dev.min_threshold_s, g_wdt_dev.max_threshold_s);fwdgt_write_enable();fwdgt_config(0xfff, FWDGT_PSC_DIV256);fwdgt_enable();return 0;
}

由此看来,是因为没有执行到这个初始化函数,所以min_threshold_s和max_threshold_s是0,而如果初始化的话,值应该是上面代码中的。然而gd32_wdt_init这个函数需要用户去调用的吗?这个是我的疑问,为了方便,我直接对gd32_wdt_control函数中那两个变量赋值了,发现能正常使用。


static rt_err_t gd32_wdt_control(rt_watchdog_t *wdt, int cmd, void *arg)
{rt_uint32_t param;g_wdt_dev.min_threshold_s = 1;g_wdt_dev.max_threshold_s = (0xfff << 8) / 40000;switch (cmd){case RT_DEVICE_CTRL_WDT_KEEPALIVE:fwdgt_counter_reload();break;case RT_DEVICE_CTRL_WDT_SET_TIMEOUT:param = *(rt_uint32_t *) arg;if ((param > g_wdt_dev.max_threshold_s) || \(param < g_wdt_dev.min_threshold_s)){LOG_E("invalid param@%u.", param);return -RT_EINVAL;}else{g_wdt_dev.current_threshold_s = param;}fwdgt_write_enable();fwdgt_config(param * 40000 >> 8, FWDGT_PSC_DIV256);fwdgt_write_disable();break;case RT_DEVICE_CTRL_WDT_GET_TIMEOUT:*(rt_uint32_t *)arg = g_wdt_dev.current_threshold_s;break;case RT_DEVICE_CTRL_WDT_START:fwdgt_enable();break;default:LOG_W("This command is not supported.");return -RT_ERROR;}return RT_EOK;
}

稍作修改的demo,改动如下:将原本空闲线程改成了一个自己建立的优先级较高的线程,同时避免了空闲时反复执行喂狗(只要在设置的2秒内喂狗一次就可以了),如下,设置了1.5s喂狗一次:

/** 程序清单:这是一个独立看门狗设备使用例程* 例程导出了 wdt_sample 命令到控制终端* 命令调用格式:wdt_sample wdt* 命令解释:命令第二个参数是要使用的看门狗设备名称,为空则使用例程默认的看门狗设备。* 程序功能:程序通过设备名称查找看门狗设备,然后初始化设备并设置看门狗设备溢出时间。*           然后设置空闲线程回调函数,在回调函数里会喂狗。
*/#include <rtthread.h>
#include <rtdevice.h>#define WDT_DEVICE_NAME    "wdt"    /* 看门狗设备名称 */static rt_device_t wdg_dev;         /* 看门狗设备句柄 */
rt_thread_t FeedDog = NULL; //创建一个喂狗的线程句柄
static void fd_entry(void *parameter)
{while(1){rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);rt_kprintf("feed the dog!\n ");rt_thread_mdelay(1500);//这里是实现了1.5s喂狗一次,如果此值大于2s会导致重启}
}static int wdt_sample(int argc, char *argv[])
{rt_err_t ret = RT_EOK;rt_uint32_t timeout = 2;        /* 溢出时间,单位:秒,也就是要在这个值内喂狗一次 */char device_name[RT_NAME_MAX];/* 判断命令行参数是否给定了设备名称 */if (argc == 2){rt_strncpy(device_name, argv[1], RT_NAME_MAX);}else{rt_strncpy(device_name, WDT_DEVICE_NAME, RT_NAME_MAX);}/* 根据设备名称查找看门狗设备,获取设备句柄 */wdg_dev = rt_device_find(device_name);if (!wdg_dev){rt_kprintf("find %s failed!\n", device_name);return RT_ERROR;}/* 设置看门狗溢出时间 */ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);if (ret != RT_EOK){rt_kprintf("set %s timeout failed!\n", device_name);return RT_ERROR;}/* 启动看门狗 */ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL);if (ret != RT_EOK){rt_kprintf("start %s failed!\n", device_name);return -RT_ERROR;}FeedDog = rt_thread_create("fd",fd_entry,NULL,512,1,5);rt_thread_startup(FeedDog);return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(wdt_sample, wdt sample);

(PS:这个代码无需放到main函数中执行,只需在命令行调用即可,方法见前面两章)

当设置大于2s喂狗(2.5s):

static void fd_entry(void *parameter)
{while(1){rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);rt_kprintf("feed the dog!\n ");rt_thread_mdelay(2500);}
}

系统被狗重启了。说明看门狗是有效的。

最后,那个gd32_wdt_init为什么没有执行呢?有没有人能告诉我,或者这个就是个BUG?

最后的最后,贴上一个我改成了无需命令行开启的看门狗:


#include <stdio.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>/* defined the LED2 pin: PF0 */
#define LED2_PIN GET_PIN(F, 0)
#include <rtdevice.h>
#define WDT_DEVICE_NAME    "wdt"    /* 看门狗设备名称 */
static rt_device_t wdg_dev;         /* 看门狗设备句柄 */
rt_thread_t FeedDog = NULL; //创建一个喂狗的线程句柄static void fd_entry(void *parameter)
{while(1){rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);rt_kprintf("feed the dog!\n ");rt_thread_mdelay(1500);}
}static int wdt_sample()
{rt_err_t ret = RT_EOK;rt_uint32_t timeout = 2;        /* 溢出时间,单位:秒 */char device_name[RT_NAME_MAX];rt_strncpy(device_name, WDT_DEVICE_NAME, RT_NAME_MAX);/* 根据设备名称查找看门狗设备,获取设备句柄 */wdg_dev = rt_device_find(device_name);if (!wdg_dev){rt_kprintf("find %s failed!\n", device_name);return RT_ERROR;}/* 设置看门狗溢出时间 */ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);if (ret != RT_EOK){rt_kprintf("set %s timeout failed!\n", device_name);return RT_ERROR;}/* 启动看门狗 */ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL);if (ret != RT_EOK){rt_kprintf("start %s failed!\n", device_name);return -RT_ERROR;}FeedDog = rt_thread_create("fd",fd_entry,NULL,512,1,5);rt_thread_startup(FeedDog);return ret;
}
//extern int wdt_sample();
int main(void)
{int count = 1;/* set LED2 pin mode to output */rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT);wdt_sample();while (count++){rt_pin_write(LED2_PIN, PIN_HIGH);rt_thread_mdelay(500);rt_pin_write(LED2_PIN, PIN_LOW);rt_thread_mdelay(500);}return RT_EOK;
}

(3)看门狗 WDT:基于GD32F303RCT6单片机在RT-Thread下的零基础学习记录相关推荐

  1. c语言看门狗指令pic,PIC单片机的窗口看门狗定时器.PDF

    PIC单片机的窗口看门狗定时器 TB3123 PIC® 单片机的窗口看门狗定时器 作者: Ashutosh Tiwari Microchip Technology Inc. 简介 窗口看门狗定时器(W ...

  2. 瑞萨e2studio(18)----看门狗WDT

    瑞萨e2studio.18--看门狗WDT 概述 硬件准备 新建工程 工程模板 保存工程路径 芯片配置 工程模板选择 WDT配置 WDT属性配置 RTC配置 RTC属性配置 设置e2studio堆栈 ...

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

    陈拓 2022/10/29-2022/10/31 1. 开发环境 操作系统: Window10.WSL 编译环境: ARM GCC IDE: VSCode SDK版本: SDK_17.1.0 硬件开发 ...

  4. STM32f429独立看门狗配置--基于HAL库

    STM32f429独立看门狗配置–基于HAL库 独立看门狗IWDG由专用的低速时钟LSI驱动,即使主时钟发生故障他仍然有效,但由于时钟LSI并不精确所以他适用于对时间精度要求低的场合,在喂狗的时候尽量 ...

  5. 基于STM32的最小系统电路设计(手把手零基础教学)

    文章目录 前言 一.复位电路 二.晶振电路 三.电源转换电路 四.SWD下载电路 五.LED测试电路 六.芯片外扩引脚 七.STM32微控制电路 总结 前言    在上篇介绍完<STM32的核心 ...

  6. 零基础学习单片机切记这四点要求,少走弯路

    零基础学习单片机切记这四点要求,少走弯路 其中一种,其它的都能够触类旁通,快捷上手了.假如你这些条件都没有,那就跟着我学吧,我建议你进修51单片机. 为什么要进修51单片机: 虽然此时单片机品种和型号 ...

  7. 零基础学习51单片机

    零基础学习51单片机 前言 51单片机是一款非常经典的8位单片机,广泛应用于各种嵌入式系统和电子产品中.本文将从零开始,以简明易懂的方式介绍51单片机的基本原理.基本语法和应用. 什么是单片机 单片机 ...

  8. FPGA零基础学习:基于FPGA的多路选择器设计(附代码)

    FPGA零基础学习:基于FPGA的多路选择器设计(附代码) 大侠好,欢迎来到FPGA技术江湖.本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的& ...

  9. FPGA零基础学习:基于FPGA的二进制转BCD设计(附代码)

    FPGA零基础学习:基于FPGA的二进制转BCD设计(附代码) 本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的"傻瓜式"讲 ...

最新文章

  1. 【Git】git系统学习(一):常用指令
  2. 网线传输速度测试_高效的以太网测试仪应该具备哪些功能?
  3. python turtle画熊-Python使用turtle库绘制小猪佩奇(实例代码)
  4. 在数据库恢复之前将数据库置为单用户模式
  5. verilog基础-状态机之FPGA独立按键消抖设计与验证(熟练testbench的写法)
  6. Why is it recommended to create clusters with odd number of nodes? | 为什么集群节点建议奇数个?
  7. 别人总结的一些git教程大全
  8. 在这里总结一些iOS开发中的小技巧,能大大方便我们的开发,持续更新。
  9. vmw6.5安装Freebsd8.1桌面gnome
  10. 学习BIOS与CMOS区别
  11. 查询计算机ip地址的方法,计算机的ip地址查询的几种简单方法介绍
  12. 在终端下调用IGV进行截图
  13. 资深行业专家王煜全的演讲:“移动互联网中的产品创新机会”
  14. win10 锁屏时间无法设置 解决方法
  15. js编程中常用术语-中英对照
  16. MySQL及同类产品的技术调研报告
  17. 搭建3款远程开发环境:Pycharm、Jupyter notebook以及code-server
  18. 什么是SSL双向认证,与单向认证证书有什么区别?
  19. ARP-attrack ARP内网毒化/欺骗攻击
  20. python骂人代码大全_边看chromium的代码,边想骂人...

热门文章

  1. 神舟电脑LOT码查询(SN码)
  2. 工具篇 之 解决希捷硬盘在 Mac 上只读情况
  3. 认识,保罗·克鲁格曼
  4. NodeJS SSR服务端渲染:公共代码区分客户端和服务端
  5. 虚幻引擎之使用LoadClass加载蓝图类
  6. 虚幻编程准备之-宏定义的语法
  7. 清华大学最早的计算机设计人,厉害了,我的清华简!原来最早的十进制计算器设计得如此巧妙……...
  8. 2021-2027全球与中国新冠肺炎安全和防护产品市场现状及未来发展趋势
  9. python 人脸提取_Python 自动提取电影中所有人脸
  10. Go:You-Get 简介