热度 22
2016-3-14 19:02
1697 次阅读|
1 个评论
I have written extensively about designing ultra-low power systems that operate from coin cells. Unfortunately, a lot of vendor information is gilded with marketing malarkey; we engineers have to separate fact from aspiration and design using worst-case analysis. Quite a few people have written asking about using watchdog timers (WDT) in battery-operated systems that achieve years-long life by snoozing 99+ percent of the time. The system may be dead to the world for hours – how does one service a WDT when the code isn’t running? Why would you want to? How can the software crash when it’s not running? The answer is that the code can fail while awake and accidently enter a sleep state. Running the WDT during sleep ensures the system will recover. One could wake up once a minute or so and tickle the watchdog. Generally that only requires a handful of instructions. Even when running from a 32 kHz clock (typical for ultra-low power sleep modes) the tickle will only need a ms or so of awake time. If the MCU consumes 50 uA while servicing the WDT that’s just 7.5 uAh per year of operation. Given that a CR2032 coin cell has about 220 mAh of capacity, the energy needed for managing the WDT is insignificant. But the reality is a bit more complex. We have to work with real parts, not idealized devices. I looked at a typical microcontroller from Microchip, picked at random from their incredibly diverse selection of “XLP” (extremely low power) devices. The PIC16LF1704/8 is a nice 8 bitter with gobs on on-board I/O, including a watchdog timer. In the low-power sleep mode the WDT consumes 14-17 uA. I started engineering when a microprocessor needed a huge honking power supply, so this is an incredibly small number. But it’s too much for long-lived coin cell operation. That compendium I referenced demonstrates that for 10 years of life from a coin cell the average current consumed can’t exceed 2.5 uA. That watchdog is unusable in this environment. (I didn’t do an exhaustive search; possibly other MCUs from Microchip have lower-current WDTs. And I commend them for publishing these worst-case numbers; too many other vendors don’t.) A competing MCU from TI, the MSP430F11x1a, takes only 1 to 3.4 uA in the lowest-power sleep that still has an oscillator running (to support the WDT). Nice, but 3.4 uA is far too much for these applications. The better figures assume Vdd is 2.2 volts and it’s not hot. No incremental current is listed for turning on the watchdog, which suggests that is included in these figures. However, the user’s guide reads “When the watchdog timer is not required, the WDTHOLD bit can be used to hold the WDTCNT, reducing power consumption.” That sounds like there is some undocumented hit for using that peripheral. Is it a nanoamp or do you have to run jumper cables to a car battery? Sans data, engineers are left adrift. Other vendors are equally vague. Since the code can’t crash while sleeping, leave the WDT turned off during those long periods. Enable it while awake. Running, a crash will be mediated by the operating WDT. The upside of this approach is that, since the MCU is awake for such short periods, the current consumed by the WDT is insignificant and won’t drain the battery. While awake, of course, a crash could vector to the code that disables the watchdog before going to sleep. Instead, structure the code to initialize a variable to a known value, and add offsets to it while running. That could be done in functions that are always called. Before executing the SLEEP instruction check to see if that variable contains a value that indicates the code executed correctly. Take recovery action if the variable is not correct. Or, if basically the same code runs during each awake cycle, use a timer to measure execution time; error if it deviates much from nominal. There are other failure modes. The firmware could be perfect, but an external event – EMI or a cosmic ray impact – may scramble the MCU’s neurons. Perhaps the program counter gets altered. When the MCU wakes up it will resume operation at a random address without re-enabling the WDT. Or maybe the event flips a bit in the sleep logic so the microcontroller never wakes up. Essentially, one would need a watchdog that operates during sleep times to counter these threats. Internal WDTs use too much current. I can’t come up with a circuit that would consume the microamp or less one can budget to a watchdog. Some of you are building long-lived battery-operated devices that sleep most of the time. For high-reliability applications, how do you implement a watchdog timer?