芯片选型
Ciga Device — GD32F470系列
看门狗通俗解释
看门狗字面意思理解就是用来看门的。我们设置一个看门狗,它可以帮我们发现软件和芯片的故障,我们需要定时喂这个狗,,如果超过规定的时间没喂它或者提前喂它,它就会认为你有问题了,就会咬你一口让芯片系统复位重启。
看门狗类型
看门狗有两种。
- 独立看门狗FWDGT:在某个时间必须喂,如果超过该时间内没喂狗就会咬你让芯片系统复位重启。
- 窗口看门狗WWDGT:在一个窗口时间范围内必须喂狗,早于该时间范围(喂狗时间小于最小值)或超过该时间范围(喂狗时间大于最大值)喂狗都将咬人让芯片系统复位重启。
看门狗专业解释
看门狗(Watchdog)是一种用于监视系统运行情况的硬件设备,本质就是一个倒计时计数器。它能定时检测系统是否正常运行,并在系统出现故障或者卡死时自动重启系统,从而保证系统的稳定性和可靠性。
其基本原理是定期接收来自主控芯片的"喂狗信号",如果在规定的时间内没有接收到信号,硬件看门狗将会触发系统复位,重新启动整个系统。
看门狗作用
硬件看门狗特别适合用于远程或无人值守的系统设备中,它能确保系统在出现故障时及时自动重启减少停机时间并提高系统的可用性。这在一些关键的嵌入式系统、服务器、网络设备等领域非常重要。
看门狗(Watchdog)在嵌入式系统中起着至关重要的作用,它通常是一种硬件计时器或计数器,用于监控系统的运行情况。其作用和重要性包括以下几个方面:
- 系统健壮性和稳定性: 看门狗能够监控系统的运行状态,一旦系统出现故障、死锁或意外情况,可以通过重启系统来恢复正常运行,确保系统的稳定性和可靠性。
- 防止死锁和程序错误: 当程序发生死循环、意外暂停或其他异常情况时,看门狗可以检测到系统无响应的状态并执行重启操作,从而防止系统永久性死锁。
- 系统保护和数据完整性: 通过定期喂狗操作,可以确保系统在正常运行期间不会因软件或硬件故障而丢失关键数据,从而保护系统的数据完整性和稳定性。
- 实时系统保障: 对于实时系统而言,看门狗可以帮助确保系统在规定的时间内完成任务,若任务未能及时完成,可以执行重启操作以确保系统的实时性能。
看门狗在嵌入式系统中的作用和重要性体现在提高系统的稳定性、保护数据完整性、预防死锁和程序错误、保障实时系统性能等方面。它是确保嵌入式系统安全可靠运行的重要保障手段之一。
独立看门狗FWDGT
介绍
有独立时钟源(IRC32K)。即使主时钟失效,FWDGT依然能保持正常工作状态,适用于需要独立环境且对计时精度要求不高的场合。
当内部向下计数器的计数值达到0,独立看门狗会产生一个系统复位。使能独立看门狗的寄存器写保护功能可以避免寄存器的值被意外的配置篡改。
代码实现
void FWDGT_Init_Config(){
//独立电路的看门狗
//不需要rcu
//配置看门狗的计数值,预分频系数参数
//reload_value:12位向下递减计数器(0x0000 - 0x0FFF),初始值4096
//prescaler_div:预分频系数,将32KHZ进行降频
//计算目标时间:32000/32=1000HZ,即1秒数1000下,数一下需要1ms
//目标重启时间,2000ms,
fwdgt_config(2000, FWDGT_PSC_DIV32);
fwdgt_enable();
}
int main(void)
{
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
systick_config();
USART0_init();
printf("Init Complete!\n");
// 配置独立看门狗
FWDGT_Init_Config();
uint32_t cnt = 0;
while(1) {
delay_1ms(1990);
//重装载计数器(发送喂狗信号)
fwdgt_counter_reload();
printf("喂狗了 %d\n",cnt++);
}
}
窗口看门狗WWDGT
介绍
用来监测由软件故障导致的系统故障。窗口看门狗定时器开启后,7位向下递减计数器值逐渐减小。计数值达到0x3F时会产生系统复位(CNT[6]位被清0)。在计数器计数值达到窗口寄存器值之前,计数器的更新也会产生复位。因此软件需要在给定的区间内更新计数器。窗口看门狗定时器在计数器计数值达到0x40会产生一个提前唤醒标志,如果使能中断将会产生中断。窗口看门狗定时器时钟是由APB1时钟预分频而来。窗口看门狗定时器适用于需要精确计时的场合。
代码实现
void WWDGT_init_config(){
uint32_t apb1_freq = rcu_clock_freq_get(CK_APB1);
printf("apb1_freq: %d\n", apb1_freq);
// 窗口看门狗
// 1. 开启rcu
rcu_periph_clock_enable(RCU_WWDGT);
// 2. 配置wwdgt
wwdgt_deinit();
/* configure counter value, window value, and prescaler divider value
counter: 计数器的初始器 0x00 - 0x7F Max: 127
window: 窗口值(最早) 0x00 - 0x7F Max: 127
prescaler:分频系数 ,eg.WWDGT_CFG_PSC_DIV4
PCLK1 = 60MHz
counter = (PCLK1/4096)/4 每秒计数次数Hz
counter = 3662Hz
-------------------------------------------------------------------
求窗口的时间范围:
1/4分频系数: 1次计数耗时 = 1000ms / 3662Hz = 0.273ms
窗口开始时间-> (counter - window) * 1次计数耗时 = (127 - 80) * 0.273ms = 12.831ms
窗口结束时间-> (counter - 0x3F) * 1次计数耗时 = (127 - 63) * 0.273ms = 17.472ms
需要在窗口时间内喂狗, 否则会触发重启
12.831ms < duration < 17.472ms
1/8分频系数: 1次计数耗时 = 1000ms / xxx = xxx
...
*/
wwdgt_config(COUNTER, WINDOW, WWDGT_CFG_PSC_DIV4);
/* 3. 启用wwdgt start the window watchdog timer counter */
wwdgt_enable();
}
int main(void)
{
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
systick_config();
USART0_init();
printf("Init Complete!\n");
// 配置窗口看门狗
WWDGT_init_config();
uint32_t cnt = 0;
while(1) {
// 12.831ms < 安全期 < 17.472ms
// delay_1ms(12);
delay_1ms(15); // 可以
// delay_1ms(18);
/* configure the window watchdog timer counter value */
wwdgt_counter_update(COUNTER);
// 在循环里定期喂狗
printf("嘿喂狗! %d\n", cnt++);
}
}