我怎样才能避免Soft WDT reset这个循环中的错误。当达到数字 3190 时,错误始终发生。
unsigned long TimeFrame = 10000;
void setup() {
Serial.begin(9600);
}
void loop() {
unsigned long StartTime = millis();
while (millis() - StartTime <= TimeFrame){
Serial.println(millis() - StartTime);
}
}
Run Code Online (Sandbox Code Playgroud)
我可以数到 2500 次 4 次,但这是否是解决此错误的正确方法?
感谢您的解释。我delay(10)在代码中添加了一个,它可以工作。
void setup() {
Serial.begin(9600);
}
void loop() {
unsigned long StartTime = millis();
while (millis() - StartTime <= TimeFrame){
Serial.println(millis() - StartTime);
delay(10);
}
}
Run Code Online (Sandbox Code Playgroud)
WDT 是“看门狗定时器”。看门狗定时器用于在系统出现问题时重新获得控制权 - 例如,无限循环或其他一些意外情况。当底层系统重新获得控制权时,它会重置这些计时器,以便它们再次从零开始计数。当它们达到最大值时,它们会触发芯片上的硬件复位。
您的代码测量 ESP8266 软件看门狗定时器的持续时间 - 在本例中为 3.19 秒。
ESP8266 具有硬件和软件看门狗定时器。loop()不打算无限期地运行 - 它打算做少量工作然后返回。当它返回时,ESP8266 SDK 会重置看门狗定时器。
无论是delay()与yield()功能给SDK机会说:“有些事好吗?”和复位定时器。如果您需要长时间运行代码,loop()您应该偶尔调用其中之一,让系统的其余部分有机会运行。
保持loop()简短也不仅仅是关于看门狗定时器。它还为网络堆栈提供了运行和处理它需要做的处理的机会。
您应该始终设计您的程序,以便loop()执行一小批重复处理然后返回。它不应该包含无限循环或长循环的代码。
例如,假设您需要每 20 秒执行一次操作。这是错误的做法:
void loop() {
unsigned long start = millis();
while(millis() - start < 20*1000) ;
do_something();
}
Run Code Online (Sandbox Code Playgroud)
这打破了软件设计的工作方式——loop()简单地执行。它不允许任何其他软件在等待时运行。看门狗定时器将触发并重置您的 CPU。
这个更好:
void loop() {
delay(20*1000);
do_something();
}
Run Code Online (Sandbox Code Playgroud)
因为delay()让底层系统重新获得控制权,重置看门狗定时器并进行与网络相关的处理。
在我看来,这是最好的:
static unsigned long start_time;
void setup() {
start_time = millis();
}
void loop() {
if(millis() - start_time > 20*1000) {
do_something();
start_time = millis();
}
}
Run Code Online (Sandbox Code Playgroud)
因为它在内部loop()做的工作最少,只有在该做的时候才做。
| 归档时间: |
|
| 查看次数: |
661 次 |
| 最近记录: |