Interrupt documentation

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Interrupt documentation

Post by dhylands » Mon Nov 30, 2015 4:55 pm

Overall - I think that this is excellent.

Under "Creation of Python Objects", it says "This is not permitted in an interrupt handler because it would interfere with a process of heap management known as garbage collection."

That isn't quite correct. The problem is that the heap allocation functions are not reentrant. For example, the main code could be in the middle of allocating an object when an ISR comes along and also wants to allocate an object. No garbage collection involved in that scenario.

It might also be worth mentioning array.array (which can hold things which are not bytes) and might be more appropriate in some cases over bytearray.

Its probably worth mentioning someplace that the filesystem functions are also not reentrant.

In the Critical Section section, I often use the terminology read-modify-write as being something that should cause immediate red-flags when writing ISRs, and things like t_counter += 1 is a classic example of read-modify-write (rather than just calling a race condition).

User avatar
dbc
Posts: 89
Joined: Fri Aug 28, 2015 11:02 pm
Location: Sunnyvale, CA

Re: Interrupt documentation

Post by dbc » Mon Nov 30, 2015 10:02 pm

Overall this is a great write-up and pitched at exactly the right level. For beginners, it includes enough Google-able keywords to hook them into further resources. For the most part, as I was reading it, any comment that came to mind was addressed further on. I just have a couple of quick comments:
if a situation arises where an ISR takes so long... that a second interrupt occurs. This is known as reentrancy...
This mashes a number of things together. If an ISR takes too long, the same interrupt might occur again, or some other interrupt might come in. If the same interrupt comes in, it will be held off until the ISR completes, and then will fire (delayed). If the ISR were to re-enable the interrupt before completing, and the interrupt fired again, *then* we have the reentrant situation. It is my understanding that the reentrant situation won't normally happen with Micro Python unless you start diving into inline asm to twiddle interrupt masks. In the third case, if the ISR takes so long that the same interrupt fires a third time before the original ISR completes, then an interrupt has gone down the bit bucket. There are another batch of cases associated with a *different* interrupt firing while an ISR is in progress. If the ISR has a higher priority than the second interrupt, the second interrupt is delayed, or if the ISR runs long enough that the second interrupt fires a second time, it may be lost. If the ISR has a lower priority than the second interrupt, then second interrupt might actually start a second callback ISR.

So I'm not sure how to address all of that without it becoming too much confusing clutter -- this is supposed to be a "beginners" section, after all. Perhaps: "If an ISR takes too long, the same or another interrupt of higher, lower, or same priority may occur. The processing of all but higher priority interrupts will be delayed, and if delayed enough, an interrupt may be lost. If an interrupt of higher priority comes in during an ISR, the first ISR may be interrupted by a second ISR, so beware of critical sections *among* ISRs."

Overall this is an excellent write-up. Thanks for taking the time to put it together.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Interrupt documentation

Post by dhylands » Mon Nov 30, 2015 10:14 pm

I would argue that reentrancy problems can occur with just a single interrupt.

If the main thread call function A, and an interrupt comes along and interrupts it in the middle and also calls function A, then function A will be called in a reentrant manner. Whether it will work properly or not depends on the nature of the function.

Generally this is abstracted to data structures as well. If function A is manipulating a data structure and an interrupt calls function B which also wants to manipulate the same data structure.

Arc
Posts: 5
Joined: Tue Oct 14, 2014 3:44 am

Re: Interrupt documentation

Post by Arc » Mon Nov 30, 2015 11:22 pm

As a beginner I found dbc's first version clearer. Pythoncoder I sent you a PM so as to keep the thread clear for those who know what they're about.

As well as describing the interrupt behaviour can this article mention where it's implemented and documented, for resolving any finer points. Is interrupt priority, queuing and callback storage handled by MicroPython firmware or by the SOC itself? Sorry if I'm missing the obvious.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Interrupt documentation

Post by dhylands » Mon Nov 30, 2015 11:50 pm

Arc wrote:As well as describing the interrupt behaviour can this article mention where it's implemented and documented, for resolving any finer points. Is interrupt priority, queuing and callback storage handled by MicroPython firmware or by the SOC itself? Sorry if I'm missing the obvious.
Interrupt dispatch (or queuing) (i.e. determining exactly which interrupt handler to run and when) is done by a block inside the Cortex-M4 processor called the NVIC (Nested vectored interrupt controller). The NVIC and the peripherals have various configuration registers which control whether an interrupt is enabled or not. The NVIC has incoming interrupt lines from all of the peripherals and things that can generate interrupts and it decides which interrupt gets dispatched. The CPU decides when an interrupt is allowed to run. The NVIC controls which interrupt vector gets to run.

Normally, the dispatch table is written in assembler, and in the case of the STM32 each interrupt vector contains the address of a routine to execute.

The assembler code provides a default implementation which is setup using a weak reference.
https://github.com/micropython/micropyt ... m32.S#L172
https://github.com/micropython/micropyt ... #L325-L326

The C code can then provide a function of the same name, which overrides the weak reference:
https://github.com/micropython/micropyt ... #L390-L392

The C code (which is part of the MicroPython firmware) is then responsible for storing any callbacks into python code and invoking those in an appropriate manner.
https://github.com/micropython/micropyt ... #L365-L390
and this is where it calls the python callback:
https://github.com/micropython/micropyt ... int.c#L377

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Interrupt documentation

Post by pythoncoder » Tue Dec 01, 2015 9:14 am

@Arc I've not received a PM from you

I've made an attempt at tackling the points raised and would welcome further comments.

One or two issues have been raised which I'd regard as advanced topics. In my revision I've taken the approach of explaining the issue or hazard but avoided the level of detail which would be required for a detailed description of how it might be addressed. I'm open to persuasion if the team thinks I should go into more detail but on certain topics I might need a little help ;)

@dbc I was aware that I'd ducked the issue of interrupt priorities owing to my limited grasp of this aspect of the chip's architecture. In the light of your comments I've written something on this, but do please fact-check it ;) I've mentioned the subject of critical sections shared between ISR's later in the document (after I introduce the concept of critical sections) but I feel it's in my "advanced" category.

@dhylands I've addressed your comments and included something on the subject of reentrant functions. I could expand on the subject but again my judgement is that it's "advanced". I did mention arrays in a number of places, but I've introduced a para at the start suggesting datatypes which are best suited for sharing between ISR's and main code: this gives a better pointer to the array module for beginners. I've noticed in the forum that many seem to miss this useful module.
Peter Hinch
Index to my micropython libraries.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Interrupt documentation

Post by dhylands » Tue Dec 01, 2015 9:21 am

I know I used to think arrays and lists were the same thing for quite a while.

User avatar
dbc
Posts: 89
Joined: Fri Aug 28, 2015 11:02 pm
Location: Sunnyvale, CA

Re: Interrupt documentation

Post by dbc » Tue Dec 01, 2015 3:56 pm

dhylands wrote:I
If the main thread call function A, and an interrupt comes along and interrupts it in the middle and also calls function A, then function A will be called in a reentrant manner. Whether it will work properly or not depends on the nature of the function.
Yup, you caught me.

User avatar
dbc
Posts: 89
Joined: Fri Aug 28, 2015 11:02 pm
Location: Sunnyvale, CA

Re: Interrupt documentation

Post by dbc » Tue Dec 01, 2015 4:13 pm

pythoncoder wrote: I've made an attempt at tackling the points raised and would welcome further comments.
Excellent. IMHO you can declare victory at this point.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Interrupt documentation

Post by pythoncoder » Sat Dec 05, 2015 8:03 am

I've reviewed the text and hopefully cleared up the typos. Further comments are, of course, welcome.

How to progress this? My grasp of rst is limited. My attempts to create a link from the tutorial section haven't worked. Would it be possible to offer the rst file for someone to patch in?
Peter Hinch
Index to my micropython libraries.

Post Reply