RT_thread 独立看门狗 watchdog 不断自动复位的解决方法

  记录一下,这个问题把我坑惨了,搞了3天都没有解决,甚至都有点怀疑人生了。本着学习的态度跑一遍官网给的各种案例,再慢慢学习用到项目上,结果上来就闷头一棒。

   可能是这点坑了自己,我并没有直接从官网上去下载最新源码。我用了之前RT_thread来重庆培训的时候拷贝给我的源码。我一看 这不有个 v4.0.1 版本的吗,一想现在不也就最高 v4.0.2。从这里开始我就入坑了,之前利用的那些串口、IIC、SPI都没出现过问题,就唯独看门狗启动不了,还不断自动复位。注意这里我选用了rt-thread-v4.01里面的文件。

    

  使用平台:  STM32F103ZET6核心板

   编译器   :  MDK5    

  直接复制RT_thread的官网文档资料上的源码。如下所示

/*
 * 程序清单:这是一个独立看门狗设备使用例程
 * 例程导出了 wdt_sample 命令到控制终端
 * 命令调用格式:wdt_sample wdt
 * 命令解释:命令第二个参数是要使用的看门狗设备名称,为空则使用例程默认的看门狗设备。
 * 程序功能:程序通过设备名称查找看门狗设备,然后初始化设备并设置看门狗设备溢出时间。
 *           然后设置空闲线程回调函数,在回调函数里会喂狗。
*/

#include <rtthread.h>
#include <rtdevice.h>

#define WDT_DEVICE_NAME    "wdt"    /* 看门狗设备名称 */

static rt_device_t wdg_dev;         /* 看门狗设备句柄 */

static void idle_hook(void)
{
    /* 在空闲线程的回调函数里喂狗 */
    rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
    rt_kprintf("feed the dog!\n ");
}

static int wdt_sample(int argc, char *argv[])
{
    rt_err_t ret = RT_EOK;
    rt_uint32_t timeout = 1;        /* 溢出时间,单位:秒 */
    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_init(wdg_dev);
    if (ret != RT_EOK)
    {
        rt_kprintf("initialize %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;
    }
    /* 设置空闲线程回调函数 */
    rt_thread_idle_sethook(idle_hook);

    return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(wdt_sample, wdt sample);

源码上导出到msh命令行列表中,通过命令行启动这个例子。

  • 通过CubeMX开启IWDG

  • 在env图形配置工具中开启watcdog

  • 直接测试代码

   开始的时候,看门狗复位时间设置为1s,看不到错误输出信息就复位了。加长看门狗复位时间,会看到里面是看门狗启动失败。

  • 继续DUG调试
    /* 启动看门狗 */
    ret = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL);

 发现输入命令参数的宏定义是 5 启动看门狗

#define RT_DEVICE_CTRL_WDT_START          (5) /* start watchdog */

 但是继续单步调试下去,发现在内部一个switch case 语句中 并没有5这个选项导致错误。

然后我就。。。。

 

  • 解决方法,下载最新的RT_thread ,比如我使用第一个图中的 rtthread-rt-thread-master 文件夹的内容 ,完美运行。

引用论坛一位网友的原话:

"你的HAL Driver的版本太老了,上github下载最新的RTThread就好了 https://github.com/RT-Thread/rt-threa ."

我也进去看了 两个文件中的 drv_wdt.c 确实有一些不同,不过我困惑的是既然是 v4.0.1 ,为什么还会这样,具体等论坛中网友回复吧。留下一个论坛网址 https://www.rt-thread.org/qa/thread-423347-1-1.html

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的Rt-thread看门狗程序的示例: ``` #include <rtthread.h> #define WATCHDOG_TIMEOUT (5000) // 5秒超时时间 /* 定义看门狗设备对象 */ static rt_device_t watchdog_dev; /* 定义看门狗线程 */ static rt_thread_t watchdog_thread = RT_NULL; static void watchdog_thread_entry(void* parameter) { rt_uint32_t timeout; while (1) { /* 表示没有任务需要看门狗保护 */ if (rt_thread_self()->stat == RT_THREAD_CLOSE) { rt_kprintf("No task to watch!\n"); break; } /* 看门狗开始计时 */ timeout = rt_device_control(watchdog_dev, RT_DEVICE_CTRL_WDT_START, (void*)WATCHDOG_TIMEOUT); /* 如果返回0,则表示看门狗时间到达 */ if (timeout == 0) { rt_kprintf("Watchdog timeout\n"); rt_hw_reset(); // 通过硬件复位系统 } rt_thread_mdelay(WATCHDOG_TIMEOUT / 2); // 线程等待WATCHDOG_TIMEOUT / 2毫秒 } } int watchdog_init(void) { watchdog_dev = rt_device_find("wdt"); // 找到看门狗设备 /* 如果找不到看门狗设备,则返回错误 */ if (watchdog_dev == RT_NULL) { rt_kprintf("Watchdog device not found!\n"); return -1; } /* 控制看门狗的设备注册为看门狗模式 */ rt_device_control(watchdog_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, (void*)WATCHDOG_TIMEOUT); rt_device_control(watchdog_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL); // 看门狗计时开始 /* 创建看门狗线程 */ watchdog_thread = rt_thread_create("watchdog", watchdog_thread_entry, RT_NULL, 1024, 25, 10); if (watchdog_thread != RT_NULL) { rt_thread_startup(watchdog_thread); rt_kprintf("Watchdog thread create success!\n"); return 0; } rt_kprintf("Watchdog thread create fail!\n"); return -1; } /* 注册看门狗初始化函数到Rt-thread */ INIT_APP_EXPORT(watchdog_init); ``` 这个看门狗程序中,我们使用了Rt-thread提供的看门狗接口来实现计时功能并防止系统因为某个线程的执行超时而崩溃的情况发生。当超时时间到达时,看门狗会向外部硬件发送一个复位信号,从而复位整个系统。这个看门狗程序需要在初始化的时候调用 watchdog_init() 函数来完成注册到Rt-thread内核的初始化过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值