Re: Making a function safe for use in an ISR



On Thu, 25 Jan 2007 23:07:25 -0600, "Gary Pace" <xxx@yyy> wrote:


"joshc" <josh.curtz@xxxxxxxxx> wrote in message
news:1169696689.897046.166960@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

int iterative_factorial(int i) {
int f;
f = 1;

while (i != 0) {
f = i * f;
i--;
}
return(f);
}


This function can not be a stand-alone ISR (with register save
preamble), since ISRs do not in general have input parameters or
return any function results, so apparently this example function is
called from some higher level interrupt service code.

As written the function is "unsafe" in many contexts within an embedded app
(particularly so in an ISR where "get in and out quickly" is often important
to maintain system timing) :
- i is signed, int may be 8,16,32 (maybe 64?) bits in size

If this is supposed to be standard C, then int can not be 8 bits.

Someone pointed out that the ISR could execute for a very long time.
However, in this case this would not be a critical thing for legal
values.

7! = 0x13B0 Legal 16 bit signed int
8! = 0x9D80 Legal 16 bit only as unsigned
9! = 0x58980 Does not fit into 16 bit

12! = 0x1C8CFC00 Legal 32 bit signed int
13! = 0x17328CC00 Does not fit into 32 bits

So for 16 bit int, at most 7 iterations would have to be performed,
while the result f fits into int and with 32 bit int, 12 iterations
are required and with 64 bit int, 20 iterations would be performed at
most.

However, multiplications and divisions should be avoided in ISRs,
especially if these are implemented in software or implemented as
microcode with execution times several times larger than ordinary
instructions.

Floating point instructions should be avoided even if the instruction
set implements these instructions, since saving and restoring the
floating point control/status and actual data registers would take a
huge time.

While the 8087 style floating point processor (used in most x86
processors) contains an internal stack for internal values, this is
practically useless for ISRs, since it contains only 8 slots and could
be used to 7-8 slots already when the ISR occurs, so executing
floating point operations in the ISR without first saving the stack
could easily overflow the stack.

On later Pentium models, the FPU stack is used as MMX data registers
and the processor might be in MMX mode when the interrupt occurs,
switching it to floating point mode in the ISR takes a very long time
as well as restoring the MMX state after the interrupt execution.

Paul

.



Relevant Pages

  • Re: Making a function safe for use in an ISR
    ... Floating point instructions should be avoided even if the instruction ... floating point operations in the ISR without first saving the stack ... On later Pentium models, the FPU stack is used as MMX data registers ...
    (comp.arch.embedded)
  • Memory allocation modifications in ibm_newemac driver
    ... The problem is this - when I enable a large MTU and run data through the EMAC and also am reading and writing data to a disk, memory becomes so fragmented that allocating a new SKB fails. ... static int emac_reset ... goto bail; ... if (isr & EMAC4_ISR_TXPE) ...
    (Linux-Kernel)
  • Re: Why ISR contains no arguments and return type is void
    ... If an interrupt can be caused by 3 causes, A, B, or C then the condition ... In addition, when you write an ISR, ... Check Ralph Brown's INT list. ... > in a register before returning from your ISR. ...
    (sci.electronics.design)
  • Re: Why ISR contains no arguments and return type is void
    ... you may have to check flags while in the ISR to ... You place a value like which sector to read in the ax or eax ... Check Ralph Brown's INT list. ... in a register before returning from your ISR. ...
    (sci.electronics.design)
  • Re: Why ISR contains no arguments and return type is void
    ... In addition, when you write an ISR, you ... 99.97% of the 8086's) of a software "interrupt" or break ... Check Ralph Brown's INT list. ... >in a register before returning from your ISR. ...
    (sci.electronics.design)