|
|
View previous topic :: View next topic |
Author |
Message |
picprogrammer
Joined: 10 Sep 2003 Posts: 35
|
Lost interrupts |
Posted: Tue Feb 15, 2011 6:54 am |
|
|
Hi,
I have made a (PIC18F) dual motor controller with H bridge and the motor has an AB encoder. The A signal is connected to the IRQ input and is counting the rotation using rising and falling edge direction from the B signal. The problem is sometimes the calibrated zero point moves. Zero is not counted zero.
Now i see the compiler messages: irq's disabled during.... The HIGH priority irq's are enabled but no difference. Any way i can not have the irq disable from the compiler?
Gr, |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Tue Feb 15, 2011 8:50 am |
|
|
Sounds like you're trying to call an ISR from withing another ISR which is not allowed or the same ISR inside the orginal ISR.
Posting your program would confirm or deny this. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Tue Feb 15, 2011 8:53 am |
|
|
The warning message will also tell you _what function_ this applies to.
Normal reasons are silly things like using delays inside interrupts, arithmetic, etc..
Follow the adage _make all IRQ handlers as short as possible_. If you want to have delays/functions etc., triggered 'by' the interrupts, then set a flag in the interrupt handler, and do the work outside. Generally, if you do this, you will find the warning vanished.
However, if not, then with the function name, you will (hopefully) then know what operation is causing it. If this is 'unavoidable', then it comes down (depending on what function is involved), to either writing a duplicate version, or 'tricking' the compiler to produce separate code for theh two versions (tell us what function, and we can probably help on this).
Best Wishes |
|
|
picprogrammer
Joined: 10 Sep 2003 Posts: 35
|
|
Posted: Tue Feb 15, 2011 12:06 pm |
|
|
The program is 14049 lines in 10 sub programs. The message from the compiler:
Quote: |
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@DIV3232)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@I2C_WRITE_1)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@I2C_READ_1)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@MULFF)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@FTOSD)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@DIV88)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (Gettime)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (CALC)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (WRITE_SINT32_EEPROM)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@PSTRINGC_38400_31766_31767)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@PSTRINGCN_38400_31766_31767)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (READ_SINT32_EEPROM)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@ITOF)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@DIVFF)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@DIV1616)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@FLT)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@SDTOF)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@ADDFF)
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (vector)
|
I already disabled all calculations when the motor is powered. But you cannot be sure the axle will not move when in calculations. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 15, 2011 5:56 pm |
|
|
Quote: |
>>> Warning 216 "apekool.c" Line 1443(0,1): Interrupts disabled during call to prevent re-entrancy: (@DIV3232)
|
See this previous thread on the topic (and the links in it):
http://www.ccsinfo.com/forum/viewtopic.php?t=42118 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Wed Feb 16, 2011 3:16 am |
|
|
But simply go back to the comment about what to do in an interrupt. Seriously, _several orders of magnitude_ too much.
1) 32 bit multiplication. Though you can get a separate maths library to load, will take 222 machine cycles. Already 'upper limit' of the time you would want to spend in an interrupt handler.
2) I2C reads and writes. Even at 400KHz, again _too long_.
3) MULFF even worse. Up to 359 machine cycles.
4) Gettime. Guessing this is from a clock chip, probably several mSec....
5) AArgh. Write to EEPROM. Ouch. Typically 4mSec/byte.
6) Looks as if you have a trying print function being called in both the main, and the interrupt. Don't...
Stop here, but similar comments apply to every line.
This looks as if you are actually not really understanding what an interrupt is for. A bit like the old joke about the lady driver pulling out the choke, and hanging her [spam] on it, then being surprised that the engine runs rough.
You need to structure your code, and write the body of it in the main external area, not in the interrupts. Then set flags in the interrupt to say what this should be doing.
If you want to print from inside the interrupt, then use an interrupt driven serial, with bputc/bgetc routines, and duplicate just these routines, with an 'ibputc', which is designed to call inside the interrupt, and a 'bputc', which disables the interrupts itself, around the actual buffer handling, then just write the data to the buffer with ibputc in the interrupt.
Best Wishes |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Wed Feb 16, 2011 6:16 am |
|
|
If you're worried about losing your position 'zero',offload the job to a US Digital LS7166 chip. Directly interfaces to encoder and includes 24bit counter.I've used them for decades in ultra precise robotic equipment.
Full PID control system in a 16F877,with realtime control from PC. |
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Wed Feb 16, 2011 8:41 am |
|
|
Use the 18fxx31, and handle your quadrature encoder directly on the chip. the only interrupts you need to deal with are rollovers of your quadrature count.
The LS7166 is obsolete, and designing with obsolete components carries its own concerns, depending on how your project needs to scale. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Wed Feb 16, 2011 8:58 am |
|
|
The LS7166 has been a great chip that I've used for over a decade, still in production and with thousands of my products out there worldwide I'm not concerned about it being 'obsolete'! It's been and still is an easy use 'glue' chip that 'offloaded' code from the 16F877.
Even the 18fxx31 is obsolete by some standards! There is a falicy that the latest chip is the greatest,but I've seen first hand that going with that you know is a proven ,reliable product makes you more money than retooling yet again for the newest chip on the block.'Time costs money' as the saying goes,especially in the fast paced global economy. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Wed Feb 16, 2011 9:46 am |
|
|
Yes, there can actually be a 'reverse' argument, that designing with a new chip, has no guarantee that this particular part is going to prove 'popular', and that production will continue for a long time, while using 'well known' parts, brings with it a large user base, and can in some cases almost guarantee second sourcing....
I've had experience of being told to use a newer release part during design, and then having this one dropped in only a couple of years, while the 'old' part I was going to use was still in common manufacture...
In fact there are several revisions of LS7166, and while the 'plain' variant is long gone, the 'E' variant, is 'in production', and has 'second source' manufacturers.
Best Wishes |
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Wed Feb 16, 2011 9:47 am |
|
|
temtronic wrote: | The LS7166 has been a great chip that I've used for over a decade, still in production and with thousands of my products out there worldwide I'm not concerned about it being 'obsolete'! It's been and still is an easy use 'glue' chip that 'offloaded' code from the 16F877.
Even the 18fxx31 is obsolete by some standards! There is a falicy that the latest chip is the greatest,but I've seen first hand that going with that you know is a proven ,reliable product makes you more money than retooling yet again for the newest chip on the block.'Time costs money' as the saying goes,especially in the fast paced global economy. |
That's what I meant by "how you project needs to scale", but thanks for the clarification. It does look like a nice chip. I thought it was obsolete because all the vendors I found were obsolete IC brokers, and Allied, Newark, Digikey and Jameco didn't stock it, but the manufacturer doesn't have it listed as out of production (which is what I meant by "obsolete"), and one of their US distributors, US Digital, does have it available at $11.20 in quantities of 10.
Again, how the project scales is important. If I were planning a large production run, at more than $10/unit it might make more sense to move to a purpose-designed motor controller uController. Having worked with a similar chip in the past (HCTL2020 if memory serves), there were more lines of code involving communication with the support chip than implementing the QE right on the 18Fxx31. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Wed Feb 16, 2011 10:51 am |
|
|
I think you will find that the newer versions are all SMD. The DIL versions seem to be 'fading'.
However the SMD versions LS7166E-s, are 'current'.
Best Wishes |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Wed Feb 16, 2011 12:10 pm |
|
|
Also, please consider the R&D, engineering, testing, etc. costs...all 'manhours' or 'dayze' spent on a project. Saving nickels and dimes on parts is usually is not cost effective in the big picture when weighed against the cost of time to get that new product to market.
Also, if you can utilize the same components for several products you do save. Sure, maybe a 40 pinner like the 16F877 for a PID servo controller is 'overkill' when an 8 pinner will work, but the time and effort probably will cost more than the bigger part. Sometimes the learning curve is tough, especially on newer parts with so many 'quirks' (ie: clocks on 18 series !) |
|
|
picprogrammer
Joined: 10 Sep 2003 Posts: 35
|
|
Posted: Thu Feb 17, 2011 2:39 am |
|
|
To come back on the subject:
The main program runs not in irq's but: for debugging purpose I use the receive rs232 irq and there get the time (i2c) and print it. (and a lot more calculations) Normally this irq is never used.
Is it possible due to this construction in the 'gettime' the irq are always disabled?
It's easy to poll for incoming chars instead of this. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Thu Feb 17, 2011 3:08 am |
|
|
Seriously, just make your ISR's as short as possible.
If (for instance), you call an I2C function inside an ISR, and also outside, then interrupts will be disabled in the external I2C function.
Now, your list contains a huge number of things that should never be in an ISR. You have 32bit multiplication, floating point maths, the time function, the I2C functions etc. etc.. _One_ warning, for a small routine that takes a few uSec, may well be acceptable (this is why they are warnings, not "this won't work"), but a list like you have, implies that program function _will_ be destroyed.
Now, interrupts won't be permanently disabled, but some things could make them behave as if they are:
1) If you have a long 'print', inside a serial receive ISR. If this takes more than a couple of character times, and serial data is still arriving, then you could overflow the receive UART buffer. If this happens, and there is not an 'ERRORS' statement in the RS232 definition (or you have your own error handling/recovery code), the UART _will_ be hung.
2) If you accidentally have a 'getc' in the main code, while having a serial receive interrupt. Then if you call this getc in the main, and no data arrives, the chip _will_ be hung. Problem here is that since the getc is used both inside and outside the interrupt, interrupts will be disabled while waiting for the character to arrive.
3) Similar for thing like I2C functions. However provided you are the master, the hang here will be short. For a slave though, the hang could be indefinite.
As already said, you _need_ (compulsory, not optional!....), to rethink your code. Make the ISR handlers do just "what is says on the tin", and handle the ISR event _only_. Make your main code sit in a loop, possibly with a state machine. If you want delays, use a hardware timer tick to provide these. Have the interrupts just set flags to say 'do this' to the main code.
Best Wishes |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|