What has been interrupted?

Hello,
Once in a while, enet related code take long or forever to execute. Trying to understand what's going on, I'd need to add to the wd isr means to show where precisely has the interrupt occurred (preferably c code line). Can someone tell how to proceed?
Thank you!

Hi @guy_c. If I understood correctly what you are trying to accomplish, maybe you will find this useful:

@ptillisch - Thanks! Very interesting. They say ill need to backtrace the assembly to the source. How do i do that?

You are welcome. I found it very useful some years back when I was experiencing intermittent hangs in sketches using the Ethernet library.

Please quote the exact text in the library documentation you are referring to so I can be sure I understand what you are asking.

The description states

"by saving the program address where the timeout occurred. This program address can be used with a disassembly of the compiled code to identify the location of the problem in your sketch.
"

So it suposes that i have a disassembled code with enough bacannotation to the source. E.g. c source line # preceding each assembler code chunk. Is there such a disassembler?

Yes. You use avr-objdump to obtain the disassembly listing as explained in the readme:

https://github.com/per1234/WatchdogLog#disassembly

avr-objdump is part of the avr-gcc toolchain that is installed with any of the AVR boards platforms (e.g., "Arduino AVR Boards"), so you already have it on your computer.

I see there is some information in the readme that is specific to Arduino IDE 1.x:

This is accomplished by using the avr-objdump program included with the Arduino IDE in the Arduino\hardware\tools\avr\bin folder

avr-objdump is not located at that path if you are using Arduino IDE 2.x. You can find the location by doing the following:

  1. Select File > Preferences... from the Arduino IDE menus.
    The "Preferences" dialog will open.
  2. Check the box next to "Show verbose output during: ☐ compilation" in the "Preferences" dialog.
  3. Click the OK button.
  4. Select Sketch > Verify/Compile from the Arduino IDE menus.
  5. Wait for the compilation to finish.

Now examine the contents of the "Output" panel at the bottom of the Arduino IDE window. You will see several commands that were ran using various avr-gcc tools (e.g., avr-g++, avr-objcopy,. avr-size). For example:

"C:\\Users\\per\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-size" -A "C:\\Users\\per\\AppData\\Local\\Temp\\arduino\\sketches\\F75FE89D6696B9F9DF10D21BDA05FB09/gbdsdfgh.ino.elf"

avr-objdump will be in the same folder as those other tools. In my example, I can see that it will be at this path:

C:\Users\per\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\7.3.0-atmel3.6.1-arduino7\bin\avr-objdump
1 Like

Thanks ptillisch for this detailed explanation. Indeed, looking for "Arduino disassembler" i discovered the avr-objdump utility and the .elf file. I was not aware of them before!

Can you please tell me some more about the hungs you talked about eatlier? I already faced an issue that has never been clarified - that the starment client=server.available can have a variable duration and could lock ti the short or the long one. Regarding the wd interrupted instruction, i was really looking only for a mean for an isr to pinpoint what instruction has been interrupted, tu tell the value of the stacked program counter. I am already satisfied with my wd management but currently it only logs to eeprom the interrupted main "loop" function and doesn't tell precisely where in this function nor in functions called by this root one

The problem was that for some reason a network communication process (I don't recall exactly which one) would fail periodically. The code was set up to handle such a failure, but the problem was that the Ethernet library has a default timeout duration for that process that was ridiculously long (1600 ms). So my program execution (which had a completely non-blocking design in my own code) would be blocked for 1.6 s every time that network communication failure occurred.

These are my notes about configuring the timeouts in the Ethernet library:

The key to the most responsive, reliable Ethernet communication is setting appropriate timeout values. The default values are very conservative. Setting the timeout values too high can lead to long blocking delays if an Ethernet process is unsuccessful. If you have a watchdog timeout of less than the timeout duration then it may cause your Arduino to reset. Setting the timeout values too low can cause frequent communication failures. The optimal values are different for each network configuration so you will need to do some experimentation to find them.

These are the functions that can be used to configure the timeouts in your Arduino sketch:

The default retransmission count setting is 8. The default retransmission timeout is 200 ms. 8 retries with 200 ms timeout means the W5x00 chip will take 1600 ms to timeout with the default configuration.

I'm actually remembering more details now (this was over 8 years ago). The long default timeouts were a problem I encountered, but I think I actually had a problem of the code hanging permanently (until the watchdog reset the microcontroller). With the help of the "WatchdogLog" library, I traced the hang to this code in EthernetClient::connect:

Note that the function will never return until status() returns the expected values. I added a timeout to that code, configurable via EthernetClient.setClientTimeout() and the problem was solved.

Originally I just hosted that fix in my own fork of the Ethernet library, but Paul Stoffregen somehow noticed it and added it to the official Ethernet library as part of the big renovation they did for the 2.0.0 release of the library.

I use ethernt2 lib because it allows me to use Blake Foster's icmp ping that I use at start-up to check connectivity with the router and then to the Inet. I conceed I have no knowledge of c++ and dont feel like, at my age😸, diving into it and porting ping to library 2.0.0

OK, the "Ethernet2" library still has the bug that was fixed in the "Ethernet" library years ago:

It is also missing the EthernetClient.setClientTimeout(), Ethernet.setRetransmissionTimeout(), and Ethernet.setRetransmissionCount() timeout configuration functions I mentioned above. However, you can still configure the latter two using a lower level API:

You must add #include <utility/w5100.h> after the line #include <Ethernet.h> in your code to make these functions available.

  • W5100.setRetransmissionTime(): Set the timeout for the W5x00 module. The initial value is 200ms.
  • W5100.setRetransmissionCount(): 1 is the minimum value. The initial value is 8.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.