I have several places where I implement a wait for some event with a timeout. I do this using a while loop similar to the following:
unsigned long t = pRTC->TickCnt + 100;
while (!digitalRead(SOMEPIN) && (pRTC->TickCnt < t))
;
pRTC is a pointer to an object I created which uses a hardware timer to, among MANY other things, create a 1mSec counter called "TickCnt". This object is functioning perfectly., and has been for years But, the above code seems to randomly hang, unless I put something, almost anything, into the body of the while loop. For example, this works perfectly:
unsigned long t = pRTC->TickCnt + 100;
while (!digitalRead(SOMEPIN) && (pRTC->TickCnt < t))
delay(1) ;
As does this:
unsigned long t = pRTC->TickCnt + 100;
while (!digitalRead(SOMEPIN) && (pRTC->TickCnt < t))
Serial.println("x");
I can't for the life of me understand why putting something inside the loop should make any difference at all.
Each of the things you put in the while body take some (minimal) time to execute. Perhaps the issue is with how often you call access pRTC->TickCnt.
What makes pRTC->TickCnt change while the while loop is running? How does the hardware timer know which instance of the mystery class to update TickCnt for?
PaulS:
Each of the things you put in the while body take some (minimal) time to execute. Perhaps the issue is with how often you call access pRTC->TickCnt.
What makes pRTC->TickCnt change while the while loop is running? How does the hardware timer know which instance of the mystery class to update TickCnt for?
TickCnt is updated every mSec by a timer overflow interrupt. There is one, and only one RTC object, using Timer8 on the Due, and Timer 2 on AVR-based Arduinos. As I said, that object has been working perfectly for years. TickCount IS updating correctly, and the while loops are running in the foreground.
Is there any reason for the compiler to believe that
pRTC->TickCnt
will ever change? Did you mark this as being volatile? NOTE: You cannot just mark pRTC as volatile. I am not sure how to do it, but the TickCnt field itself must be marked as volatile.
Could be an optimization issue. If the compiler can't foresee this value changing, it may cache the value in a register or even treat part of the while as an "if". volatile tells the compiler to foresee the independent change. Calling a function could possibly also change the value.