[SOLVED] latest git-snapshot causes freezes
-
-
@tekka, the versions are:
Mysensors is development branch, I didn't pay attention while cloning, it's set to default to development:
commit 8cacb4825b256f63aa2fc51468fd11a90bb19678 Merge: 75a100f 8ccb1ca Author: Patrick Fallberg <patrick@fallberg.net> Date: Thu Sep 22 19:02:11 2016 +0200Arduino IDE is 1.6.4
$ rpm -qa arduino* arduino-core-1.6.4-8.fc24.noarch arduino-doc-1.6.4-8.fc24.noarch arduino-1.6.4-8.fc24.noarchMy IDE board manager shows Arduino AVR boards version 1.6.7, and it seems there is newer one available, 1.6.14. I will update that.
Mysensors AVR board definition for Micro version is 1.0.1
-
so far, on my side, using custom sleep() and other mix, my ints are still working..i'm using latest snap' now, and still in 1.6.8..
but that's not the same usecase as i'm not using mys sleep for this node..
I will try your case; at least mine is working well :) . it could be sort of race..always a dilemma somewhere.. -
I got suspecious about the code working with the manual adding of
sei()before calling the i2cread-function.So I changed the end of
hwPowerDownto include a serial output with a flush.// restore saved WDT settings WDTCSR = WDTsave; Serial.println("sei()"); Serial.flush(); sei(); // enable ADC ADCSRA |= (1 << ADEN); }Now have a close look at how
sei()-output is missing just before the freeze:57114 MCO:SLP:TPD<\n> sei()<\r><\n> 57147 MCO:SLP:WUP=-1<\n> | 57180<\r><\n> 57180 TSF:MSG:READ,0-0-14,s=0,c=1,t=16,pt=2,l=2,sg=0:0<\n> 57245 TSF:MSG:ACK<\n> 157262 TSF:MSG:SEND,14-14-0-0,s=0,c=1,t=16,pt=2,l=2,sg=0,ft=0,st=OK:0<\n> readI2cgot # from slave: 1<\r><\n> r57376 MCO:SLP:MS=16,SMS=0,I1=1,M1=3,I2=255,M2=255<\n> 57442 MCO:SLP:TPD<\n> sei()<\r><\n> 57475 MCO:SLP:WUP=-1<\n> | 57491<\r><\n> 57507 TSF:MSG:READ,0-0-14,s=0,c=1,t=16,pt=2,l=2,sg=0:0<\n> 57573 TSF:MSG:ACK<\n> 157589 TSF:MSG:SEND,14-14-0-0,s=0,c=1,t=16,pt=2,l=2,sg=0,ft=0,st=OK:0<\n> readI2cgot # from slave: 1<\r><\n> r57704 MCO:SLP:MS=16,SMS=0,I1=1,M1=3,I2=255,M2=255<\n> 57769 MCO:SLP:TPD<\n> 57786 MCO:SLP:WUP=1<\n> | 57786<\r><\n> 57786 TSF:MSG:READ,0-0-14,s=0,c=1,t=16,pt=2,l=2,sg=0:0<\n> 57786 TSF:MSG:ACK<\n> 157786 TSF:MSG:SEND,14-14-0-0,s=0,c=1,t=16,pt=2,l=2,sg=0,ft=0,st=OK:0<\n> readI2cJust after "57769 MCO:SLP:TPD<\n>" the sei()-output is missing. Thus I suspect that interrupts are not enabled when the readI2c-function is called .. and as i2c is depending on interrupts the code gets stuck there.
Still no idea why the
sei()is "sometimes" not called ...Notice how the "millis" interrupt is not called after the missing sei .. thus all timestamps are the same:
57786 MCO:SLP:WUP=1<\n> | 57786<\r><\n> 57786 TSF:MSG:READ,0-0-14,s=0,c=1,t=16,pt=2,l=2,sg=0:0<\n> 57786 TSF:MSG:ACK<\n> 157786 TSF:MSG:SEND,14-14-0-0,s=0,c=1,t=16,pt=2,l=2,sg=0,ft=0,st=OK:0<\n> readI2c -
Comparing the code to the atmel documentation here:
http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__sleep.html
mysensors explicit disables interrupts after wake from sleep:
sei(); // Directly sleep CPU, to prevent race conditions! (see chapter 7.7 of ATMega328P datasheet) sleep_cpu(); sleep_disable(); // restore previous WDT settings cli();whereas the atmel documentation enables interrupts
#include <avr/interrupt.h> #include <avr/sleep.h> ... set_sleep_mode(<mode>); cli(); if (some_condition) { sleep_enable(); sleep_bod_disable(); sei(); sleep_cpu(); sleep_disable(); } sei();Might not be totally related as the code did not change from last stable .. except one line:
WDTCSR |= (1 << WDIE); // set the WDIE flag to enable interrupt callback function.is now missing in the snapshot ..
Adding an extra sei() after the sleep_disable() is not the solution .. still thought it might be noteworthy
-
Comparing the code to the atmel documentation here:
http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__sleep.html
mysensors explicit disables interrupts after wake from sleep:
sei(); // Directly sleep CPU, to prevent race conditions! (see chapter 7.7 of ATMega328P datasheet) sleep_cpu(); sleep_disable(); // restore previous WDT settings cli();whereas the atmel documentation enables interrupts
#include <avr/interrupt.h> #include <avr/sleep.h> ... set_sleep_mode(<mode>); cli(); if (some_condition) { sleep_enable(); sleep_bod_disable(); sei(); sleep_cpu(); sleep_disable(); } sei();Might not be totally related as the code did not change from last stable .. except one line:
WDTCSR |= (1 << WDIE); // set the WDIE flag to enable interrupt callback function.is now missing in the snapshot ..
Adding an extra sei() after the sleep_disable() is not the solution .. still thought it might be noteworthy
@cimba007 said:
WDTCSR |= (1 << WDIE); // set the WDIE flag to enable interrupt callback function.
is now missing in the snapshot ..Can you indicate where this change is located?
I compared 2.0.0 (master) to 2.0.1beta (development) and WDTCSR is only touched in MyHwATMega328.cpp
The watchdog related parts seem identical between both versions...Futhermore, is it the library located at https://github.com/FaBoPlatform/FaBo3Axis-ADXL345-Library/blob/master/src/FaBo3Axis_ADXL345.cpp that you are using?
-
Jep, this is the library.
https://github.com/mysensors/MySensors/blob/development/core/MyHwATMega328.cpp#L86
https://github.com/mysensors/MySensors/blob/master/core/MyHwATMega328.cpp#L75well .. I have no idea but on my code it is there:
Seems to be neither in the stable nor the developement branch .. but I most gotten it somewhere .. lets check
I think I added it for some reason on latest stable. Otherwise pinchage-interrupt was not working with mysensors-library .. I will try to remove it on stable to see if I get stuck there too and add in snapshot to see if it helps in some way.
EDIT1: Adding in the latest snapshot doesn't change a thing
EDIT2: Removing it in the latest stable doesn't change a thingI might have added it from another testsketch .. but it would be better located in that sketch right after the sleep function .. so just ignore it for now - my bad ;_(
-
Jep, this is the library.
https://github.com/mysensors/MySensors/blob/development/core/MyHwATMega328.cpp#L86
https://github.com/mysensors/MySensors/blob/master/core/MyHwATMega328.cpp#L75well .. I have no idea but on my code it is there:
Seems to be neither in the stable nor the developement branch .. but I most gotten it somewhere .. lets check
I think I added it for some reason on latest stable. Otherwise pinchage-interrupt was not working with mysensors-library .. I will try to remove it on stable to see if I get stuck there too and add in snapshot to see if it helps in some way.
EDIT1: Adding in the latest snapshot doesn't change a thing
EDIT2: Removing it in the latest stable doesn't change a thingI might have added it from another testsketch .. but it would be better located in that sketch right after the sleep function .. so just ignore it for now - my bad ;_(
@cimba007 Well, I filed (https://github.com/mysensors/MySensors/issues/598) and fixed (https://github.com/mysensors/MySensors/pull/599) and issue with interrupts not being detached correctly in all cases when using hwSleep().
This might be causing your issue, but is hard to say without actually debugging the code.
Once the PR is merged, could you try getting the latest development branch and see if it fixes the issue? (please use the development branch, without any local modifications) -
Just copy'pasted your fix and .. voila
Problems seems to be solved - although I do not unterstand why?!
- _wakeUp2Interrupt should be totally unrelated as it is never set
- detach should happen in the ISR
.. even if the interrupt is not detached correctly .. how should it lead to the total skip of these code:
cli(); wdt_reset(); // enable WDT changes WDTCSR |= (1 << WDCE) | (1 << WDE); // restore saved WDT settings WDTCSR = WDTsave; Serial.println("sei()"); Serial.flush(); sei(); // enable ADC ADCSRA |= (1 << ADEN); //WDTCSR |= (1 << WDIE); // set the WDIE flag to enable interrupt callback function.As this code-snipped is skipped sei() gets never called in my case .. and the subsequent call to i2c freezes the node ... as i2c depends on interrupts ..
Anyway thanks Yveaux .. althour your fix is simple .. i don't know why it is working ...
EDIT: Furthermore .. even if the interrupt is not detached in the isr .. there should be no further interrupt if the interrupt register is not read via i2c .. and that in fact doesn't happen >:>
-
Just copy'pasted your fix and .. voila
Problems seems to be solved - although I do not unterstand why?!
- _wakeUp2Interrupt should be totally unrelated as it is never set
- detach should happen in the ISR
.. even if the interrupt is not detached correctly .. how should it lead to the total skip of these code:
cli(); wdt_reset(); // enable WDT changes WDTCSR |= (1 << WDCE) | (1 << WDE); // restore saved WDT settings WDTCSR = WDTsave; Serial.println("sei()"); Serial.flush(); sei(); // enable ADC ADCSRA |= (1 << ADEN); //WDTCSR |= (1 << WDIE); // set the WDIE flag to enable interrupt callback function.As this code-snipped is skipped sei() gets never called in my case .. and the subsequent call to i2c freezes the node ... as i2c depends on interrupts ..
Anyway thanks Yveaux .. althour your fix is simple .. i don't know why it is working ...
EDIT: Furthermore .. even if the interrupt is not detached in the isr .. there should be no further interrupt if the interrupt register is not read via i2c .. and that in fact doesn't happen >:>
@cimba007 Great to hear it solves your problem!
Regarding the serial print not showing: you call it from withing a section with interrupts disabled; I don't know if this will work at all, or maybe even cause a hang... I would toggle some IO pins instead and use an oscilloscope to verify program flow.
Sleeping an AVR using the watchdog and pin interrupts is some tricky stuff, which is very susceptible to race conditions and almost impossible to debug without a decent hardware debugger.
Having a compiler that woes every now and then also isn't helping... -
I only used the pin change interrupt in another sketch. I was doubting Serial in sections without isr too! But they are clever. Serial output depends on polling in sections where interrupts are disabled ;-)
-
@cimba007 said:
Serial output depends on polling in sections where interrupts are disabled
Ok, learned something today ;-)
The PR has now been merged to development btw.
@Yveaux While we are at this topic .. any chance to let the user-code know what caused the wakeup during sleep() ??
For example .. if there was a wakeup at all or which of the two interrupt sources was the cause.
Unforunatly the "cause" gets cleaned up at the end of hwSleep:
bool interruptWakeUp() { return _wokeUpByInterrupt != INVALID_INTERRUPT_NUM; }Calling this from user-code will always return 0 as the end of hwSleep does this:
_wokeUpByInterrupt = INVALID_INTERRUPT_NUM;Not clearing the "last interrupt source" would be nice.
-
@Yveaux While we are at this topic .. any chance to let the user-code know what caused the wakeup during sleep() ??
For example .. if there was a wakeup at all or which of the two interrupt sources was the cause.
Unforunatly the "cause" gets cleaned up at the end of hwSleep:
bool interruptWakeUp() { return _wokeUpByInterrupt != INVALID_INTERRUPT_NUM; }Calling this from user-code will always return 0 as the end of hwSleep does this:
_wokeUpByInterrupt = INVALID_INTERRUPT_NUM;Not clearing the "last interrupt source" would be nice.
-
@cimba007 The return value of sleep() indicates the wake-up cause: irq (nr) or timer (=MY_WAKE_UP_BY_TIMER).
See here: https://github.com/mysensors/MySensors/blob/development/core/MyHwATMega328.cpp#L146-L147 -
@cimba007 said:
Serial output depends on polling in sections where interrupts are disabled
Ok, learned something today ;-)
The PR has now been merged to development btw.