Using floating point within ISR

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are there any known problems with using floating point maths inside an ISR?

My Goertzel routine, that works perfectly in the foreground, produces rubbish when I move the calculations to the ISR.

And yes, I know it's heresy to write ISRs that take longer than a few femtoseconds, but I'd like to get to the bottom of this. Also, if I could do the calculations in the ISR it would save me around 2K of RAM that's otherwise used for two buffers.

This is using Studio 5.1 and an XMega256A3U, BTW.

Four legs good, two legs bad, three legs stable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can see no great problem with f-p inside an ISR().
The compiler should preserve registers etc.

OTOH, if you have a scratch memory / register that is used in both ISR() and foreground, you can get problems.

How complex are your f-p calculations?

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There might be an issue of re-entrancy in math.h functions. Are you using FP in both main() and ISR or just the ISR?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I can see no great problem with f-p inside an ISR().
The compiler should preserve registers etc.

OTOH, if you have a scratch memory / register that is used in both ISR() and foreground, you can get problems.

How complex are your f-p calculations?

David.

This complex:

	q0 = coeff * q1 - q2 + (double)value;
	q2 = q1;
	q1 = q0;
	
	BufPtr++;
	if(BufPtr >= LB_SIZE)
		{
			
		// Calculate the result			
		result = q1 * q1 + q2 * q2 - q1 * q2 * coeff;				
		q1 = 0.0;
		q2 = 0.0;

Where q0, q1, q2 and coeff are all doubles.

Four legs good, two legs bad, three legs stable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
There might be an issue of re-entrancy in math.h functions. Are you using FP in both main() and ISR or just the ISR?

Hard to say; I don't think I'm using any fp in main(), but I am using integer maths in a higher priority interrupt.

Four legs good, two legs bad, three legs stable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would be very surprised if the basic add / subtract / multiply f-p primitives are not re-entrant. OTOH, I am too idle to trawl through the source code.

I would re-compile with a different compiler to see if the problem is with your algorithm.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Floating point on an 8 bit microprocessor, inside an interrupt service routine

==

"Dr., it hurts when I do *this*."

"Well, don't do *that*."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

stevech wrote:
Floating point on an 8 bit microprocessor, inside an interrupt service routine

==

"Dr., it hurts when I do *this*."

"Well, don't do *that*."

Many thanks for the patronising, but totally useless reply.
Maybe I'd be better off with a Harvard architecture micro.

:D :D :D :D

John

Four legs good, two legs bad, three legs stable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

John,

I would guess that the f-p functions are re-entrant, and as such interrupt nesting and foreground should be no problem.

The obvious things to look for are global variables. And if you have timing / nesting depth issues.

I note that you are comparing BufPtr against a scalar value. You would commonly compare a ptr against an address, or an index against a size.

Can you post a minimal code that exhibits the problem?

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
John,

I would guess that the f-p functions are re-entrant, and as such interrupt nesting and foreground should be no problem.

The obvious things to look for are global variables. And if you have timing / nesting depth issues.

I note that you are comparing BufPtr against a scalar value. You would commonly compare a ptr against an address, or an index against a size.

Can you post a minimal code that exhibits the problem?

David.


David:
BufPtr is actually an array index, so I don't believe that is relevant.
Bad naming on my behalf, I accept.

As to posting a minimal code that exhibits the problem, I don't have the time right now, as I'm trying to get something working for a demo on Wednesday. This is not a new product, but rather an additional feature that I've been asked to shoehorn into an existing one. I have a working solution now, but at the expense of 2048 bytes of RAM, which, luckily, I can spare.

Thanks anyway for your suggestions. I have not found anything on the web to suggest that GCC maths functions are not re-entrant, BTW, so it's probably a stupid error on my part.

Four legs good, two legs bad, three legs stable.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

John_A_Brown wrote:
stevech wrote:
Floating point on an 8 bit microprocessor, inside an interrupt service routine

==

"Dr., it hurts when I do *this*."

"Well, don't do *that*."

Many thanks for the patronising, but totally useless reply.
Maybe I'd be better off with a Harvard architecture micro.

:D :D :D :D

John

Nothing to do with architecture... matters not. But using an 8 bit micro, need for speed in ISR, non-reentrant FP libraries. What more could you do wrong? Do you need to to transcendental functions and Fourier transforms in the ISR?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It depends on whether the output needs to be known fast. Sometimes there is no way around some lengthy processing if the result are also needed on-time.

I just would not use floating point but fixed point instead.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The T bit in SREG is used by some floating point functions. That may by getting overwritten somehow.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

stevech wrote:
John_A_Brown wrote:
stevech wrote:
Floating point on an 8 bit microprocessor, inside an interrupt service routine

==

"Dr., it hurts when I do *this*."

"Well, don't do *that*."

Many thanks for the patronising, but totally useless reply.
Maybe I'd be better off with a Harvard architecture micro.

:D :D :D :D

John

Nothing to do with architecture... matters not. But using an 8 bit micro, need for speed in ISR, non-reentrant FP libraries. What more could you do wrong? Do you need to to transcendental functions and Fourier transforms in the ISR?

So far, I have found nothing to indicate that the f-p libraries are not re-entrant. If you have any information to the contrary, maybe you could let me know, instead of unhelpful sniping.

The iterative calculation actually only takes around 20uS at 32MHz, the ADC reading, via an I2C device(which I also hate to do in an ISR) takes way longer.
And no, I don't have to do these calulations in the ISR, but doing so saves time and memory.

I do not wholeheartedly subscribe to the dogma re. keeping ISRs as short as possible etc. Horses for courses.

In an ideal universe, I'd have the hardware redesigned so that I could use the on-board ADC, and DMA the samples into memory, or use a micro with DSP capabilities, but I don't live in an ideal universe.

Lastly, I know that the architecture is not an issue, that was a childish snipe at you, for getting the Harvard and V.N. 180 degrees out of phase - the implication being why should I take notice of anything you say, when you obviously don't know what you're talking about.
I've been writing code for over 35 years, with reasonable success( I once made an LED flash, for example), I asked a simple question about f-p in an ISR. If you don't know the answer, you don't have to join in with the classic Irish joke response of "Well, I wouldn't start from here".

I currently have a solution that works well, but wastes time and memory, and I will investigate further when time allows.

Thanks to those who made helpful comments.

John

Four legs good, two legs bad, three legs stable.