using C code doing basic arithmetic in ISR causing unstability and system crash

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

using C code doing basic arithmetic in ISR causing unstability and system crash

2,036 Views
onder_arik
Contributor I
Hi,
 
I am new at Freescale HC(S)08 series microcontrollers. I have a big problem of using the C code that performs some basic integer arithmetic operations (32 bit division or multiplication) inside an ISR. The system crashes most of the time. I think the default C library for arithmetic operations is not re-entrant and if you use them both in main loop and inside the ISRs causing system crashes. Can you share your experience on this issue? Should I create my own re-entrant integer math library in assembler? (I have written a few of arithmetic operation functions and used them in ISR. They work OK but I am too lazy for writing a lot of them in assembler.) Is there some off-the-shelf re-entrant libraries around? What is the exact problem with the default library?
 
Thanx from now...
 
Labels (1)
0 Kudos
4 Replies

555 Views
bigmac
Specialist III
Hello,
 
As a general rule, the code within an ISR is best kept as short as possible to avoid interrupt priority problems, and delayed servicing of other interrupts.  If possible, avoid placing lengthy operations such as 32 bit multiply and divide operations within the ISR.  It is usually better for the ISR to communicate with the "main" code using flags and global variables, and do the lengthy processing within the latter.
 
Having said that, a function should be re-entrant provided only local variables are used.  I assume the calculations you refer to simply do multiply and divide using long values.
 
You will need to define what you mean by "system crash".  The usual cause of unexpected MCU resets is the COP timer.  This may need to be reset at the start of your lengthy functions, to avoid the possibility of timeout occurring part way through the function.
 
If the results of your calculations are being corrupted, particularly if global variables are unexpectedly changing, a likely cause could be that you are exceeding the allocated stack size - you may need to increase this size.  You do not mention the MCU type your are using.  If a "low end" type, it might not have sufficient RAM resources for what you are trying to achieve.
 
Regards,
Mac
 
0 Kudos

556 Views
onder_arik
Contributor I
Hi Bigmac,
 
Thanx for your comments.
 
I am working on MC9S08LC60. Currently, I do not use COP timer. I am using the ADC to get a few samples every 500us. I have to at least "basic-process" the samples before next sample comes. The basic process includes a 16 bit multiplication and 32 bit addition. However,  I have a lot of secondary lengthy background tasks running in the main loop. This prevents me from doing the basic-processing of samples in the main loop! That's why I need them in the ISR. The background tasks are not time critical and I do not want to divide them into smaller units, which totally fits the remaining time of the 500 us which is around 300us.
 
The main problem is when I use the default C language arithmetic operations (c = a * b; c = a / b:smileywink:  both in the main loop and ISR, system crashes. System crash manifests itself sometimes by trashing the globals but by mostly jumping to random places in the code. My guess id the ISR somehow trashing the stack and therefore trashing the return address. I have replaced the arithmetic operations with my own assembler written functions (instead of a = a * b; I use UMulU16ByU16(&a, b) function) now it works OK but I still want to know why the default C library crashes. I will try to increase the stack size. But I will more than glad to hear some explanations from experienced programmers.
0 Kudos

556 Views
bigmac
Specialist III
Hello,
 
Does the ISR in question handle a timer interrupt each 500us, or is it for something else?  If my understanding is correct, you seem to be implying that the ISR takes 200us to complete within each 500us.
 
One further thought - do you allow nested interrupts within your ISR?  If so, multiple interrupts can consume a lot of extra stack space.
 
Regards,
Mac
 
0 Kudos

556 Views
Alban
Senior Contributor II
Hello,
 
I also share your idea of the stack overflow.
If you want to be certain, you can configure a break point READ on ADDRESS between the high part of variables and low part of stack in RAM.
If the break triggers, you have stack corruption. The interruption will warn the user before a reset or system shutdown, for instance.
That is a good general way to use the debug and break modules for code integrity check, even in a single core MCU without second redundancy MCU.
 
Also you can declare the stack by its size in the prm file to warn of any potential clash at linkage.
This means you made sure of what your code requires, and this can be delicate.
 
Cheers,
Alban.
 
0 Kudos