Jump to content
danmc77

16 Bit Division Not Re-entrant?

Recommended Posts

I finished chasing down a nasty bug that turned out to be due to doing a 16 bit division in the high priority interrupt, and also having another 16 bit division in the main body of the code, leading to bizzare calculation errors.

 

I finally noticed this line in the compiler output after many painful hours of debugging erratic behavior:

Serious Warning: Possible sw stack corruption, function '__div_16_16' called by more than one asynchronous thread....

 

This was easily fixed by temporariliy disabling the interrupt around the division in the main body.

 

I looked in the Sourceboost documentation and haven't found any comments in there regarding this. I think a bold note in there would be in order.

 

Is a non-reentrant division typical of a PIC environment? This is something I haven't encountered before.

 

Are there other functions that need special care??

 

Would it be reasonable for this warning to start out as an error that demands attention until it's overridden by a pragma to turn it into a warning?? Perhaps the error message could reference the pragma making it very easy to fix.

 

Thanks much,

 

Dan

Share this post


Link to post
Share on other sites

Hey Pavel & Dave,

 

Would you please respond to this question?

 

Is a 16-bit division re-entrant? It appears that it's not. I know that when compiled, a 16 bit, or long division in C will expand into a pretty significant amount of assembly code. If that code is interrupted and another division is done in the ISR, then the first division gets trashed.

 

I think this is a rather important issue, so it is worth some comments from you.

 

Thanks,

 

Dan

Share this post


Link to post
Share on other sites

I think the answer is no.

 

The PICs (16 & 18 series) have a small stack and probably no instruction that can manipulate it or index into it.

 

Software stacks using RAM space can be created and offered on some compilers. There is of course a performance penalty when using a software stack.

 

I think you can assume that most library functions are not re-entrant because they keep their working variables in global memory allocated by the linker. These memory locations may also be shared by other functions depending on the call tree results.

 

Top end PICs such as DSPs do have a stack pointer and lots of indexing modes where you can create a stack frame and stack base pointer etc.

 

Keep interrupt routines simple and not full of complex math.

 

If you see the stack warning, you know there may be trouble ahead and may have to start disabling interrupts at critical moments. Still no guarantee that you will not corrupt overlaid variables during interrupts.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites

danmc77,

Is a 16-bit division re-entrant? It appears that it's not. I know that when compiled, a 16 bit, or long division in C will expand into a pretty significant amount of assembly code. If that code is interrupted and another division is done in the ISR, then the first division gets trashed.

 

I think this is a rather important issue, so it is worth some comments from you.

When using the BoostC compiler no functions are re-enterant. This is because a fixed software stack is used as the hardware stack is so small and on PIC16 not even accessible.

 

The options for a function that is called in both interrupt service routine (ISR) and main code are therefore:

1) Disable interrupts before call the function and re-enable after calling the function from main code.

2) Duplicate the function so that an exact copy of the function exists, this can then be safely used from an ISR.

 

A general principle for interrupt service routines is to keep them short and sweet. Also its normally not great to disable interrupts for long periods of time in main code as this then increases the worse case interrupt latency. Depending on the exact application these principles may or may not be things to worry about.

 

Regards

Dave

Share this post


Link to post
Share on other sites
danmc77,
Is a 16-bit division re-entrant? It appears that it's not. I know that when compiled, a 16 bit, or long division in C will expand into a pretty significant amount of assembly code. If that code is interrupted and another division is done in the ISR, then the first division gets trashed.

 

I think this is a rather important issue, so it is worth some comments from you.

 

....

 

When using the BoostC compiler no functions are re-enterant. This is because a fixed software stack is used as the hardware stack is so small and on PIC16 not even accessible.

 

....

 

Regards

Dave

 

 

Oh, this is much bigger than I thought. :o

 

No functions are reentrant? ????? EEEEEEEWWWWWWW!!!! :(B):o

 

So I would imagine that any operator that's working on an int or a long would compile into a function in the assembly? Yes?

 

So would something as simple as an integer addition, or a shift in the ISR create a potential problem with calculations in the main body?

 

I have always done software work on much more powerful systems, so this is an aspect of programming with a PIC that I just was not aware of at all. I'll have to rethink what I'm doing in the ISR and how I can move the computations out without sacrificing the timing.

 

Dan

Share this post


Link to post
Share on other sites

Hi Dan,

 

Welcome to the world of the PIC and wave goodbye to the Pentium.

 

You could look at the 8051 cored microcontrollers. Keil 8051 compilers are re-entrant but cost a few more bob.

 

Simple stuff like integer add, subtract, shifting and logical operands should be OK to use in interrupts as they don't need to keep intermediate results and loop counters (sometimes). It is always good just to peek at the generated assembly code to see exactly what the compiler has done.

 

Enjoy the PICs versatility and its limitations.

 

Cheers

 

Reynard

Share this post


Link to post
Share on other sites
Hi Dan,

 

Welcome to the world of the PIC and wave goodbye to the Pentium.

 

You could look at the 8051 cored microcontrollers. Keil 8051 compilers are re-entrant but cost a few more bob.

 

Simple stuff like integer add, subtract, shifting and logical operands should be OK to use in interrupts as they don't need to keep intermediate results and loop counters (sometimes). It is always good just to peek at the generated assembly code to see exactly what the compiler has done.

 

Enjoy the PICs versatility and its limitations.

 

Cheers

 

Reynard

 

Oh, I do enjoy working with the PICs. I love the simplicity, but there are a few subtleties that can bite you now and then. This was one big one.

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...