EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

[cross-post] g21k and non-interruptible functions

Started by Alessandro Basili January 10, 2012
On 01/10/2012 09:58 PM, Tim Wescott wrote:

>>> I have the need to define some functions as "non-interruptible" and I >>> remember some #pragma at least for C51 which would do this. I looked for >>> similar #pragmas for the g21k but apparently I haven't found any hint. >>> >>> Does anyone out there know how to reliably define a function as >>> non-interruptible? I understand that I could disable all interrupts and >>> enable them once the function has completed - which will potentially >>> cause to loose an interrupt, unless level-sensitive - but I believed >>> there are some "utilities" to do that at compilation level. >>> >>> Some additional info: the non-interruptable function is a function which >>> returns system time, therefore if interrupted while the value is being >>> read it may return a wrong value. >>> >>> Al >> >> If your application supports it you could write an inline asm which >> would mask all the interupts. Atleast on the 21[234]xx the sequencer >> willl respond to the latched interrupt when they are unmasked. > > The word that I would use to refer to interrupt hardware that did not > interrupt in such situations would be "broken".
Note that some architectures do not tolerate glitches on the interrupt line. Glitches could be created when disabling the interrupt through a peripheral interrupt mask, instead of the CPU interrupt flag/level. If you disable an interrupt just after it occurs, the glitch that the CPU receives may be long enough that it triggers some portion of the interrupt handling, but too short to complete it.
On 11.01.2012 00:13, Arlet Ottens wrote:
> On 01/10/2012 09:58 PM, Tim Wescott wrote:
[...]
>> The word that I would use to refer to interrupt hardware that did not >> interrupt in such situations would be "broken".
> Note that some architectures do not tolerate glitches on the interrupt > line. Glitches could be created when disabling the interrupt through a > peripheral interrupt mask, instead of the CPU interrupt flag/level. If > you disable an interrupt just after it occurs, the glitch that the CPU > receives may be long enough that it triggers some portion of the > interrupt handling, but too short to complete it.
Such behaviour would deserve to have the aforementioned word upped from "broken" to "FUBAR". I mean, come on: _not_ losing track of events (before they repeat themselves) is the one job that interrupt hardware is charged with. If it can't do that job, it might as well give up its floorspace to something useful.

Alessandro Basili wrote:

> Dear all, > > I have the need to define some functions as "non-interruptible" and I > remember some #pragma at least for C51 which would do this. > I looked for similar #pragmas for the g21k but apparently I haven't > found any hint. > Does anyone out there know how to reliably define a function as > non-interruptible?
Link with thread-safe libraries. Vladimir Vassilevsky DSP and Mixed Signal Design Consultant http://www.abvolt.com
On 01/11/2012 01:28 AM, Hans-Bernhard Bröker wrote:
> On 11.01.2012 00:13, Arlet Ottens wrote: >> On 01/10/2012 09:58 PM, Tim Wescott wrote: > > [...] >>> The word that I would use to refer to interrupt hardware that did not >>> interrupt in such situations would be "broken". > >> Note that some architectures do not tolerate glitches on the interrupt >> line. Glitches could be created when disabling the interrupt through a >> peripheral interrupt mask, instead of the CPU interrupt flag/level. If >> you disable an interrupt just after it occurs, the glitch that the CPU >> receives may be long enough that it triggers some portion of the >> interrupt handling, but too short to complete it. > > Such behaviour would deserve to have the aforementioned word upped from > "broken" to "FUBAR". > > I mean, come on: _not_ losing track of events (before they repeat > themselves) is the one job that interrupt hardware is charged with. If > it can't do that job, it might as well give up its floorspace to > something useful.
It depends. The manufacturer could also say it's broken/fubar behavior to withdraw an interrupt before it's properly handled by the CPU, and there's some logic in that claim. Anyway, I discovered this behavior the painful way on an ARM-7. A short glitch on the FIQ line can cause an interrupt, but if you deassert it right away, the CPU can actually make a jump to the IRQ vector. No matter how you'd like to call that behavior, it's good to be cautious.
On 10/01/2012 23:45, Jerry Avins wrote:
> On 1/10/2012 3:41 PM, David Brown wrote: >> On 10/01/12 19:04, Tim Wescott wrote: >>> On Tue, 10 Jan 2012 15:17:26 +0100, Alessandro Basili wrote: >>> >>>> Dear all, >>>> >>>> I have the need to define some functions as "non-interruptible" and I >>>> remember some #pragma at least for C51 which would do this. I looked >>>> for >>>> similar #pragmas for the g21k but apparently I haven't found any hint. >>>> >>>> Does anyone out there know how to reliably define a function as >>>> non-interruptible? I understand that I could disable all interrupts and >>>> enable them once the function has completed - which will potentially >>>> cause to loose an interrupt, unless level-sensitive - but I believed >>>> there are some "utilities" to do that at compilation level. >>>> >>>> Some additional info: the non-interruptable function is a function >>>> which >>>> returns system time, therefore if interrupted while the value is being >>>> read it may return a wrong value. >>> >>> Such #pragmas are exceedingly non-portable. Besides, all they're going >>> to do "under the hood" is disable interrupts for the duration of the >>> function. >>> >>> If your interrupt hardware is decent then you won't miss an interrupt: >>> either the interrupt is level sensitive and the hardware that generates >>> it won't give up until it is explicitly serviced, or the interrupt is >>> edge sensitive and the interrupt controller takes care of remembering. >>> In either case, it's your job to make sure that the interrupt will >>> persist and be serviced as soon as you come out of the protected section >>> of your function. >>> >>> So -- bite the bullet and do it the grown-up way. You want to save >>> interrupt status (because interrupts may already be turned off going >>> into >>> your function), do your interrupt-sensitive stuff as quickly as can be, >>> restore interrupts to their former state, then exit. >>> >> >> Obviously Tim is right if you need non-interruptable code. >> >> But there are other ways of doing the job in hand - sometimes disabling >> interrupts is not the only solution. For something like system timers >> like this, you can get correct results by reading repeatedly until you >> have two successive identical reads (and often you can do it with only >> partial duplicate reads). Most of the time you only need the two reads - >> but if you are unlucky and a timer rollover occurs during a read, >> perhaps because of an interrupt, then you will need an extra read. >> >> You'll have to think carefully about the possible interactions between >> the code, the hardware, and interrupts - but it is typically quite >> possible without disabling interrupts. > > That can lead to once-every-two-days kind of failure. A debugging > nightmare. >
It will only lead to such problems if you have a badly designed system. You are right to be sceptical - after all, we are talking about an unbounded loop. But if the circumstances are right, you can determine the maximum time for the function. In particular, you need to know your interrupt functions' maximum run times and rates, and how they relate to timer overflows (which can lead to a new run round the loop). If you know that these can never lead to a second overflow, your loop is clearly bounded. (And if you don't have that information about your interrupt functions, you'd better get it - otherwise you have no control about the rest of your scheduling.) As with all such things, it is vital to think through the possibilities, and the circumstances that could lock up or delay the code. You want to be confident that the once-every-two-days failure will not occur. Note also that while you don't want a one-every-two-days risk, some risks /are/ acceptable. Maybe a one in a million chance is too much - but if a failure occurs with two coincidental uncorrelated one in a million chances, then it might be fine. Risk management, reliability, and secure programming is not about being sure that everything will always work. It's about being sure the chances of failure, and the consequences of them, are low enough to be acceptable.
On Wed, 11 Jan 2012 09:00:10 +0100, David Brown
<david@westcontrol.removethisbit.com> wrote:

>On 10/01/2012 23:45, Jerry Avins wrote: >> On 1/10/2012 3:41 PM, David Brown wrote: >>> On 10/01/12 19:04, Tim Wescott wrote: >>>> On Tue, 10 Jan 2012 15:17:26 +0100, Alessandro Basili wrote: >>>> >>>>> Dear all, >>>>> >>>>> I have the need to define some functions as "non-interruptible" and I >>>>> remember some #pragma at least for C51 which would do this. I looked >>>>> for >>>>> similar #pragmas for the g21k but apparently I haven't found any hint. >>>>> >>>>> Does anyone out there know how to reliably define a function as >>>>> non-interruptible? I understand that I could disable all interrupts and >>>>> enable them once the function has completed - which will potentially >>>>> cause to loose an interrupt, unless level-sensitive - but I believed >>>>> there are some "utilities" to do that at compilation level. >>>>> >>>>> Some additional info: the non-interruptable function is a function >>>>> which >>>>> returns system time, therefore if interrupted while the value is being >>>>> read it may return a wrong value. >>>> >>>> Such #pragmas are exceedingly non-portable. Besides, all they're going >>>> to do "under the hood" is disable interrupts for the duration of the >>>> function. >>>> >>>> If your interrupt hardware is decent then you won't miss an interrupt: >>>> either the interrupt is level sensitive and the hardware that generates >>>> it won't give up until it is explicitly serviced, or the interrupt is >>>> edge sensitive and the interrupt controller takes care of remembering. >>>> In either case, it's your job to make sure that the interrupt will >>>> persist and be serviced as soon as you come out of the protected section >>>> of your function. >>>> >>>> So -- bite the bullet and do it the grown-up way. You want to save >>>> interrupt status (because interrupts may already be turned off going >>>> into >>>> your function), do your interrupt-sensitive stuff as quickly as can be, >>>> restore interrupts to their former state, then exit. >>>> >>> >>> Obviously Tim is right if you need non-interruptable code. >>> >>> But there are other ways of doing the job in hand - sometimes disabling >>> interrupts is not the only solution. For something like system timers >>> like this, you can get correct results by reading repeatedly until you >>> have two successive identical reads (and often you can do it with only >>> partial duplicate reads). Most of the time you only need the two reads - >>> but if you are unlucky and a timer rollover occurs during a read, >>> perhaps because of an interrupt, then you will need an extra read. >>> >>> You'll have to think carefully about the possible interactions between >>> the code, the hardware, and interrupts - but it is typically quite >>> possible without disabling interrupts. >> >> That can lead to once-every-two-days kind of failure. A debugging >> nightmare. >> > >It will only lead to such problems if you have a badly designed system. > You are right to be sceptical - after all, we are talking about an >unbounded loop. > >But if the circumstances are right, you can determine the maximum time >for the function. In particular, you need to know your interrupt >functions' maximum run times and rates, and how they relate to timer >overflows (which can lead to a new run round the loop). If you know >that these can never lead to a second overflow, your loop is clearly >bounded. (And if you don't have that information about your interrupt >functions, you'd better get it - otherwise you have no control about the >rest of your scheduling.) > >As with all such things, it is vital to think through the possibilities, >and the circumstances that could lock up or delay the code. You want to >be confident that the once-every-two-days failure will not occur. > > >Note also that while you don't want a one-every-two-days risk, some >risks /are/ acceptable. Maybe a one in a million chance is too much - >but if a failure occurs with two coincidental uncorrelated one in a >million chances, then it might be fine. Risk management, reliability, >and secure programming is not about being sure that everything will >always work. It's about being sure the chances of failure, and the >consequences of them, are low enough to be acceptable. >
Well, all of this deviates from the fact that YES the analog devices sequencer can deal with masking interrupts the way OP requires. All he has to do is set the registers correctly for his needs. The sequencer has a direct connection to the Interrupt controller on most AD parts as far as I can tell. Masking is done in the sequencer before it vectors. It took me one whole minute to look at three Analog Devices manuals to see this. It takes two clock cycles no matter what for delay in doing this and two clocks to undo it. Since he never expanded on his actual implementation I guess that is up to him. Of course his ISR-masked routine better not run for more than two edge-interrupts minus the time to run for the ISR of his peripheral otherwise what is the point of masking it. PS. Well I can think of a lot of reasons against the previous statement. But they are not relevant to what I work on. Mark DeArman
On Wed, 11 Jan 2012 00:13:01 +0100, Arlet Ottens <usenet+5@c-scape.nl>
wrote:

>On 01/10/2012 09:58 PM, Tim Wescott wrote: > >>>> I have the need to define some functions as "non-interruptible" and I >>>> remember some #pragma at least for C51 which would do this. I looked for >>>> similar #pragmas for the g21k but apparently I haven't found any hint. >>>> >>>> Does anyone out there know how to reliably define a function as >>>> non-interruptible? I understand that I could disable all interrupts and >>>> enable them once the function has completed - which will potentially >>>> cause to loose an interrupt, unless level-sensitive - but I believed >>>> there are some "utilities" to do that at compilation level. >>>> >>>> Some additional info: the non-interruptable function is a function which >>>> returns system time, therefore if interrupted while the value is being >>>> read it may return a wrong value. >>>> >>>> Al >>> >>> If your application supports it you could write an inline asm which >>> would mask all the interupts. Atleast on the 21[234]xx the sequencer >>> willl respond to the latched interrupt when they are unmasked. >> >> The word that I would use to refer to interrupt hardware that did not >> interrupt in such situations would be "broken". > >Note that some architectures do not tolerate glitches on the interrupt >line. Glitches could be created when disabling the interrupt through a >peripheral interrupt mask, instead of the CPU interrupt flag/level. If >you disable an interrupt just after it occurs, the glitch that the CPU >receives may be long enough that it triggers some portion of the >interrupt handling, but too short to complete it.
In the AD processors as far as I know (Do not quote me on this as I have never verified the timing&#4294967295;) take the flag from the interrupt processor and then evaluate the int against the mask. If it is masked they do nothing. This is a normal part of the sequencer delay and does not affect timing at all. Mark DeArman
On 1/11/2012 9:52 AM, Mac Decman wrote:
[...]
> > Well, all of this deviates from the fact that YES the analog devices > sequencer can deal with masking interrupts the way OP requires. All > he has to do is set the registers correctly for his needs. The > sequencer has a direct connection to the Interrupt controller on most > AD parts as far as I can tell. Masking is done in the sequencer > before it vectors. It took me one whole minute to look at three > Analog Devices manuals to see this. It takes two clock cycles no > matter what for delay in doing this and two clocks to undo it.
It's not clear yet to me whether the interrupt are latched (IRPTL updated) if interrupts are disabled (IRPTEN=0). By the way, the target is an ADSP21020.
> Since > he never expanded on his actual implementation I guess that is up to > him. Of course his ISR-masked routine better not run for more than > two edge-interrupts minus the time to run for the ISR of his > peripheral otherwise what is the point of masking it.
Did you mean "...not run for _less_ than two edge-interrupts..."? Otherwise I think I missed the point.
> PS. Well I can > think of a lot of reasons against the previous statement. But they > are not relevant to what I work on.
Given the fact that all external interrupts (4) are completely asynchronous it is not possible to determine the time between interrupts. But I will be more than happy to listen to other reasons "against the previous statement" you mentioned.
> > Mark DeArman
On 1/11/2012 3:32 AM, Vladimir Vassilevsky wrote:
> > > Alessandro Basili wrote: > >> Dear all, >> >> I have the need to define some functions as "non-interruptible" and I >> remember some #pragma at least for C51 which would do this. >> I looked for similar #pragmas for the g21k but apparently I haven't >> found any hint. >> Does anyone out there know how to reliably define a function as >> non-interruptible? > > Link with thread-safe libraries.
They do not exist, to my knowledge, for this architecture. As of now the only C library I have is the one ADI distributed along with their development suite (VisualDSP or the like). Unfortunately the device is old enough and unpopular enough to have very limited support. But I'll be more than happy to find out that I'm wrong.
On 1/10/2012 11:00 PM, glen herrmannsfeldt wrote:
[snip]
> >> If your interrupt hardware is decent then you won't miss an interrupt: >> either the interrupt is level sensitive and the hardware that generates >> it won't give up until it is explicitly serviced, or the interrupt is >> edge sensitive and the interrupt controller takes care of remembering. > > But if you wait too long, you will miss an interrupt. Maybe there > are interrupt controllers that can remember that, though the usual > solution is that the interrupt routine should take care of everything > that needs to be done, emptying any I/O FIFO's, for example. >
While all the interrupts are asynchronous, every one has a limit on the maximum frequency it can run at. Therefore I know that as long as the ISR-masked routine is faster than two of the fastest interrupts I should be on the safe side. I do not have any wired-OR interrupts and all external interrupts have their own dedicated bit in the interrupt vector.

The 2024 Embedded Online Conference