3
\$\begingroup\$

I am using Atmel AVR ATmega8 in my monitoring project, which measures three phase voltage and sends data through a uart. It works great in 1 or 2 days. But after that amount of time, it is not working as expected, and no response comes from the uart and heartbeat led, which indicates uc is alive or not. And sometimes heartbeat led blinks and no response comes from uart. But after a hardware reset, it works again, then crashes again until hardware reset. I implemented a watchdog in it, but it seems not working. I reset the watchdog counter in 8 bit timer interrupt routine. Should I reset it in my main code, not in an interrupt routine?

I assume it is getting out of SRAM. ATmage8 SRAM is 1 kb, and my static data is using 71,2% of it. And I am not using any heap allocation. My question is: Is it possible to stack and static data collide?

\$\endgroup\$
4
  • 3
    \$\begingroup\$ You should definitely reset the watchdog in your main loop, because this is what it is for. The watchdog is supposed to check that the program is processing the main loop regularly (because you reset the watchdog timer each time go through the beginning of the loop). In your case, if the program get stuck in some infinite loop, the watchdog won't trigger because it is still regularly reset by your timer interrupt routine. \$\endgroup\$
    – Edesign
    Aug 12, 2016 at 8:04
  • \$\begingroup\$ Yes i thought the same, and i assumed it was lack of sram. I made that assumption from 1 or 2 days program working as expected. \$\endgroup\$
    – LetMe
    Aug 12, 2016 at 8:19
  • 1
    \$\begingroup\$ Overall it sounds like you are making some classic beginner mistakes. You should let an experienced programmer have a look at your project. Regarding the stack, read this. \$\endgroup\$
    – Lundin
    Aug 12, 2016 at 13:40
  • \$\begingroup\$ @LetMe - "I assume it is getting out of SRAM" Although there is not enough info to exclude that possibility, I would not make that assumption - at least, not on the info given so far. I see other possible options which fit the story. Depending on what testing you have done and those test results (especially testing on a workbench etc.) then that info may help to confirm/deny other hypotheses. I cannot force you to consider other possibilities ( :-) ) but if you provide details of your other testing and those results (edit your question and add them at the bottom), that info would be helpful. \$\endgroup\$
    – SamGibson
    Aug 12, 2016 at 15:14

3 Answers 3

8
\$\begingroup\$

Is it possible to stack and static data collide?

Yes, that is entirely possible. Atmega has no dedicated stack space, so if you use too much of it, you will overflow and crash your static data.

Try to reduce your memory consumption (use the smallest suitable data types for variables, reduce your array sizes etc.) Make sure you don't have any recursion or unusually long call trees under certain conditions.

If you can get your hands on better hardware, try running your program on a 2K version of the controller. If it runs without issues, you can confirm it's an insufficient memory problem without having any extra programming effort to do.

PS. As @Edesign says, servicing the watchdog from a timer interrupt is useless: doing so would protect against timer failures, not code failures. You should service the watchdog from your main loop, ideally from a sanity check function:

//main loop
while(1) {
  uart_task();
  sensor_task();
  wdg_task();
}

void wdg_task(void) {
  if(uart_ok() && sensor_ok()) do_wdg_reset();
}

Note that the watchdog is supposed to help with errors which cannot be accounted for programmatically, like power glitches. Using a watchdog to reset a buggy program instead of fixing the bug is not the way to go.

\$\endgroup\$
0
1
\$\begingroup\$

Where you reset the watchdog depends on your application, but the essential point is to reset it somewhere immediately before or after your critical or risky functionality.

This way, if your code never finishes, the watchdog times out.

Your stack can collide with the static data, but unless you have recursive function calls with very slowly increasing depth that seems unlikely here.

Is it always "1 or 2 days"? Often slow crashes are related to time variable overflows, but then the period would be very stable.

Otherwise, your main logic might get stuck in some odd, rare corner case. Look at your code. Is there really no way for the thing to get stuck?

P.S: One last thing: If the thing at the end monitoring your UART is doing so through windows, windows has notoriously crashy serial port handling. If your "hardware reset" also toggles power to your serial adapter or involves resetting your terminal this may actually be what solves the problem.

\$\endgroup\$
0
\$\begingroup\$

Do you check that the UART is ready to send (TXC, transmit complete) before sending out the character? Does that "transmit complete bit" need resetting by softare? If so, do you also reset it before sending out the character? If you start sending the character first and reset the ready bit after, an interrupt handled in between might delay the software so that you end up clearing the TXC bit after the character has already been sent. That would halt the UART operation because nothing would ever set TXC again.

\$\endgroup\$
1
  • \$\begingroup\$ Yes i checked it, and it worked few days. I think it is related to lack of memory. Thanks for your concern. \$\endgroup\$
    – LetMe
    Aug 12, 2016 at 9:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.