看门狗的详细介绍(重点:喂狗操作应该在主循环或其他正常运行的代码段中执行,而不是在中断服务函数中进行)

1.看门狗的作用是:当单片机因为软硬件问题或者外界干扰导致死机时,可以自动复位单片机,使系统重新正常工作。

当电脑的系统死机了,我们可以人为手动的进行重启,使电脑重新正常工作。但当火星的单片机系统死机了,我们没办法人为的去重启,只能靠这只看门狗来程序启动系统。

2.看门狗工作原理:

假设计数值为1000,计数间隔时间为1ms,定时时间就为1s,看门狗就会在1s后执行单片机复位(计数值递减到0)。如果在计时结束前,执行喂狗操作,看门狗就会程序开始计时,比如在计数值300的位置执行喂狗,看门狗的计数值就会在1000和300间循环变化,不会导致系统复位。但当系统死机时,将无法执行正常的喂狗操作,看门狗的计数值就会一直递减到0,使系统复位,程序正常工作。

3.看门狗的使用原则:

看门狗的使用原则是系统正常工作时不复位,系统死机时尽快复位。如果做不到这两点,说明看门狗的使用是不正确的。

4.关于STM32F4 独立看门狗IWDG的配置

配置看门狗主要关注的是看门狗的超时复位时间,需要配置时钟分频系数和12位定时器重载值

例如我们将分频系数的寄存器配置为8,将定时器重载值的寄存器配置为4095,rc振荡器的时钟位32kHZ,32kHZ八分频等于4kHZ,4kHZ的周期是0.25ms,然后0.25*(4095+1)=1024ms,1024ms就是看门狗的超时复位时间。我们要注意的是独立看门狗的时钟是由独立RC振荡器提供,它是不精确的

看门狗的启动和喂狗主要操作的是key寄存器。看门狗的启动可分为软件启动和硬件启动,其中软件启动更加常用,只需要将key寄存器设为0xCCCC,硬件启动可以通过STM32cube programmer来修改option bytes的选项即可,不选中WDG_SW就可以是单片机上电后自动硬件启动看门狗。

看门狗的默认时钟分频系数是4,重载值是4095,复位时间大约为0.5s。硬件启动后我们依然可以通过修改分频系数和重载值寄存器来修改复位时间,硬件启动可以避免软件启动看门狗前系统死机,因此硬件启动更加可靠。

无论是硬件启动还是软件启动看门狗,看门狗在启动后都不能关闭看门狗的喂狗操作,看门狗的喂狗操作只需要将key寄存器的值修改为0xAAAA

5.关于看门狗的三个注意问题

(1)看门狗的复位时间

STM32 F4看门狗的复位时间约为0.5~32秒,一般设置为1~2秒,可以根据项目需要设置为其他值

(2)不要在定时器中断服务函数中喂狗

        喂狗操作应该在主循环或其他正常运行的代码段中执行,而不是在中断服务函数中进行。中断服务函数应尽可能短暂且高效,以确保系统响应性能。如果系统在主循环或其他正常运行的代码段中停止响应,看门狗将在超过设置的超时时间后触发复位,以重新启动系统。

        如果系统发生死机了,即使喂狗操作在定时器中断服务函数中,依然无法正常喂狗,因为如果系统发生死机,整个程序的执行都会停止,包括中断的触发和执行。

(3)如何暂停看门狗

6.关于三个问题中第二个问题的补充

STM32系统在main函数的while(1)中死机会导致所有中断事件无法相应吗?

        当STM32系统发生死机时,其中断处理机制会受到影响,导致所有中断事件无法得到正常响应。

        在STM32中,中断处理是通过向量表(Vector Table)和中断优先级配置来完成的。当一个中断事件发生时,处理器会跳转到相应的中断服务函数执行相应的处理操作。然而,当系统发生死机时,主循环无法正常运行,处理器也无法执行到中断服务函数所在的代码。

        由于死机意味着系统处于无响应状态,处理器无法继续执行任何代码,包括中断服务函数。因此,即使有中断事件触发,也无法得到相应的处理。

        为了确保中断的正常响应,在编写STM32应用程序时,需要注意避免导致死机的问题,如死循环、内存溢出、资源竞争等。当出现异常情况时,可以利用看门狗定时器或其他机制来进行系统复位,以恢复系统的正常运行。

  • 8
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在FreeRTOS,可以使用软件看门狗(Software Watchdog)来实现在程序运行过程的软件重新初始化。具体步骤如下: 1. 初始化软件看门狗定时器,设置定时时间。 2. 在任务循环定期喂狗(Feed the dog),即重置定时器,确保软件看门狗不会超时。 3. 在需要进行软件重新初始化的情况下(例如程序崩溃、任务卡死等),停止喂狗,等待软件看门狗超时,触发软件重新初始化。 以下是一个示例代码,演示如何在FreeRTOS使用软件看门狗进行软件重新初始化: ``` #include "FreeRTOS.h" #include "task.h" /* 定义软件看门狗定时时间为10秒 */ #define WDT_TIMEOUT_MS 10000 /* 定义软件看门狗定时器句柄 */ static TimerHandle_t wdt_timer_handle = NULL; /* 初始化软件看门狗 */ void wdt_init(void) { /* 创建定时器,定时时间为WDT_TIMEOUT_MS毫秒 */ wdt_timer_handle = xTimerCreate("WDT", pdMS_TO_TICKS(WDT_TIMEOUT_MS), pdTRUE, NULL, NULL); /* 启动定时器 */ xTimerStart(wdt_timer_handle, 0); } /* 喂狗函数 */ void wdt_feed(void) { /* 重置定时器,避免软件看门狗超时 */ xTimerReset(wdt_timer_handle, 0); } /* 停止喂狗函数 */ void wdt_stop(void) { /* 停止定时器,等待软件看门狗超时 */ xTimerStop(wdt_timer_handle, 0); } /* 软件重新初始化函数 */ void sw_reset(void) { /* 关闭所有任务 */ vTaskSuspendAll(); /* 关闭硬件中断 */ taskDISABLE_INTERRUPTS(); /* 软件重新初始化代码 */ /* 重新启动任务调度器 */ vTaskStartScheduler(); } void task_func(void *pvParameters) { /* 初始化软件看门狗 */ wdt_init(); while(1) { /* 执行任务代码 */ /* 喂狗 */ wdt_feed(); /* 延时一时间 */ vTaskDelay(pdMS_TO_TICKS(1000)); } } int main(void) { /* 创建任务 */ xTaskCreate(task_func, "Task1", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL); /* 启动任务调度器 */ vTaskStartScheduler(); /* 不会执行到这里 */ return 0; } ``` 在需要进行软件重新初始化的情况下,可以调用wdt_stop()函数停止喂狗,等待软件看门狗超时,触发软件重新初始化。例如: ``` void error_handler(void) { /* 停止喂狗 */ wdt_stop(); /* 执行错误处理代码 */ /* 软件重新初始化 */ sw_reset(); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

竹烟淮雨

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

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

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

打赏作者

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

抵扣说明:

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

余额充值