[TriEmbed] ESP8266 Programming tip

Peter Soper pete at soper.us
Wed Jan 27 15:14:58 CST 2021


John,

Waiting until millis() or the like gets to a target count is absolutely 
safe and there can be no hazard to do with reentrancy, stack overflow, 
corrupted variables, etc: that's all impossible with this strategy.

Now I'm interested in what Ticker is.  It's this, right? 
https://github.com/esp8266/Arduino/tree/master/libraries/Ticker 
<https://github.com/esp8266/Arduino/tree/master/libraries/Ticker>

If this is it, then on the one hand it is sort of kind of like a task 
that's "scheduled" to run along with your non-interrupt level app code. 
But as Mike said and you figured out empirically, if you do too much 
work the interrupt will fire again and again call your user code, 
nesting deeper and deeper until there is a "crash". Likewise, there are 
many things that are totally unsafe to do within interrupt code for the 
reasons Mike layed out. Atomic writes of word size or smaller variables 
not involving tricky instruction sequences in the non-interrupt code are 
the only safe thing to do if you aren't disabling/re-enablling interrupt 
to create "critical sections" and keep the interrupt from hosing you.

But you've figured all this stuff out, John. We were just torturing you 
by not understanding your workaround earlier.

But along with hazards Mike mentioned I should mention one other. Modern 
compilers can be very tricky and keep a variable's value "cached" in a 
machine register within a loop, "hiding" the updates of the variable's 
storage location in memory from other code (e.g. executing in your 
function called from the tick timer interrupt, or from another thread 
with an OS that supports threads). So the other code never sees an 
important change to the memory that one would think is happening 'cause 
the compiler is caching it to avoid the overhead of what it sees are 
"worthless" memory writes. That is, it optimizes out all but the "last" 
write to the var's memory location.

This scenario is a bottomless well of consternation for folks dealing 
with concurrency with interrupt handlers (as with Ticker) or multiple 
threads in an OS supporting them.

With C/C++ the solution is to declare the variable "volatile", telling 
the compiler it cannot defer updating the variable's storage location 
but every new assignment has to translate to a memory update.

For anything that can't be kept "atomic" (indivisible into multiple 
operations where an interrupt could happen in between them and corrupt 
state) disabling/re-enabling interrupts is simply a must for that cause 
while mutexes, semaphores, barriers and the like are the corresponding 
solutions with threading.

I have no idea how these hazards are dealt with in Python.

-Pete

On 1/27/21 3:33 PM, John Vaughters via TriEmbed wrote:
> Mike,
>
>> An example might be strcpy.  It's several assembly instructions long.  So when the timer runs out, we don't know the status of that copy.
> In the case of an interrupt, this example makes perfect sense. In the case of using millis() or micro() to schedule a turn, this is not clear to me. Maybe I am over-simplifying it and I certainly have not spent the time to review the library code. But if code is moving along, and the scheduled time frame passes to execute but the current action is progress, it would wait for that code to complete before moving to the next step. And so we are not dealing with any sort of context switch at all, just waiting our turn to execute once the program reaches our place in line. Hence my comment that we may be dealing with sequential programming. To me I am left wondering exactly what the Ticker lib does, but not so willing to take that time to figure it out. There are definitely conflicts to my simplified belief. Maybe one day I will investigate further. For sure your input has helped me understand the Watchdogs more.
>
> The new timer arrangement went about a day with zero communication errors and that is an improvement. I even reduced the response timeout to modbus comms and still no issue. that is better than when I was using the delay, which had a 3-5 errors a day with a longer modbus response timeout. That could also just be a fluke in good wifi connections, but it does seem better and the responsiveness of the code certainly was improved by taking out a guaranteed 25ms delay.
>
> I appreciate everyone's efforts in helping explain this ESP product, I learned alot in the past week or so on this little board. I really like it. So cheap relative to the capabilities. I wish I wouldn't have waited this long. `,~)
>
> Thanks,
>
> John Vaughters
>
> _______________________________________________
> Triangle, NC Embedded Computing mailing list
>
> To post message: TriEmbed at triembed.org
> List info: http://mail.triembed.org/mailman/listinfo/triembed_triembed.org
> TriEmbed web site: http://TriEmbed.org
> To unsubscribe, click link and send a blank message: mailto:unsubscribe-TriEmbed at bitser.net?subject=unsubscribe
>




More information about the TriEmbed mailing list