|
If you use up
all available processing power, which can happen very quickly if you use frequent library
calls, strange things often happen in your code.
Sometimes
what appears to be a "crash" might just be a big backlog of processing stuff that never gets
cleared out and prevents the console or other operations from running.
It is often a
good idea to set an I/O line low during your idle "process" and high otherwise and use a scope
to figure out how many spare cycles you have available before all heck breaks
loose.
Howard
FWIW, I just noticed that my #defined constants
for "ONE_K" and "TEN_K" were #defined as longs ... so the problem I saw may have been
with modulus-for-longs. I've run for 5-8 minutes at a time just now with ushorts ... will try overnight.
Rick Corey
-----Original Message----- From: Corey, Rick Sent: Wednesday, April 07, 2004 3:20 PM To: 'Yochum, William';
'm...@yahoogroups.com' Cc: Corey, Rick Subject: RE: [motoroladsp] RE: modulus (%)
affects interrupts?I tried throwing ISR protection around my "modulus code" but that didn't help much. It still died, but maybe took a little longer than it used to.
I
used the P.E. macros : #define __EI0() { asm(bfclr #0x0300,SR); } /*
Enable interrupts of level 0,1,2,3 */ #define __EI3() { asm(bfset #0x0300,SR);
} /* Enable interrupts of level 3 only (NMI) */
I
_think_ that this rules out the theory that the only problem with modulus is that it
isn't interrupt-safe ... but what is left?Rick Corey
-----Original Message----- From: Yochum, William [mailto:w...@microwavedata.com] Sent: Wednesday, April 07, 2004
11:00 AM To: 'm...@yahoogroups.com' Cc: Corey, Rick Subject: [motoroladsp] RE:
modulus (%) affects interrupts?I've seen something even worse in an earlier version of Code
Warrior.
I was also attempting to do "simple" math in an ISR.
The math in
my ISR was written as a standard C expression, but the compiler implemented this as a call
to a run-time library function. So far, so good ... but the run-time library
function was NOT INTERRUPT SAFE! It corrupted registers which manifested itself as
random failures in background code. This was a VERY insidious problem and took quite a
while to find.
William C.
Yochum
Microwave Data Systems Inc. Principal
Eng./Software 175 Science Parkway Phone: (585)
242-8319 Rochester, NY 14620 FAX: (585) 241-5590
USA-----Original Message----- From: Corey, Rick [mailto:r...@dpconline.com] Sent:
Monday, April 05, 2004 5:51 PM To: 'm...@yahoogroups.com' Subject: [Bulk E-Mail]
[motoroladsp] modulus (%) affects interrupts?Hi
Can anyone imagine a way that a
modulus operator (%) in the main loop could slow down an ISR? I'm stumped.
There's a lot of "div"s in the library function, and two "rtsd"s . I'm using
the 6.0.2 CW for 56800E (568357). I turned on Processor Expert to create the
project, then turned PE off. Any suggestions or speculation would be appreciated,
even if derived from experience with CW 5.1.
I had some durable FlexCAN code that
broke when I added a modulus operator to my main loop. I just wanted to blink some
LEDs so I could see fast TX and RX occur without a scope.
The symptom seems to
be partial or intermittent blocking of the FlexCAN mailbox interrupt - or possibly slowing
down the servicing of that interrupt. If it was only slowing down the main loop, I
should never see this symptom. It acts as if it is preventing the FlexCAN ISR from
being serviced promptly.
I can see a few packets (around 8, instead of
96) go out after a one-second delay that should have fully restored the pool, but despite
waiting long enough to TX 7,000 packets, I only find that 8 or so have been clocked out.It
seems as if, once this "bad thing" happens, CAN TX is permanently slowed down by a very
large factor - maybe around 1,000 times too slow - but not stopped entirely.
I
normally set up to send almost as fast as the packets can go over the wire. Then I
blink an LED every 100 messages (every 300 CAN packets) - in some tests, I also blink
other LEDs every 1,000 or 10,000 messages.
The symptom is running low on TX packet
buffers - as if the ISR is being prevented from running as soon as it should, or as fast
as it should. (If the TX ISR ran normally, all the packet buffers would be restored
to the pool before I took another 30 buffers out.)
Strangely, adding a
one-second delay every time I detect "low buffer pool" does not return the chip to
full-speed sending, as it should once the pool is full again. Further, the
lengths of time it takes to exhaust the pool will be consistent for each test case, but
range from 20 seconds to several minutes to overnight.
I normally send 30
packets, wait 4 milliseconds, then send another 30. The 4 mSec plus the main loop
itself is long enough for the packets to go out - if I count the number of times my
ToTxList goes empty, it is equal to the number of batches of packets, so the pool normally
gets empty every 4 milliseconds. The test also fails if I run with 10 mSec delays,
or 50 mSec - it just takes longer to fail. With the 4 mSec delay and no "%"s, it
runs over a weekend.
I read the error counters every few packets, and they
never exceed "1". I trigger an interrupt and trap on any FCSTATUS error bit.
None seen.
CODE SAMPLES:
Worst case code, with unsigned long, breaks in
20 seconds: &nb
sp; if (!(NumMsgsSent % 100)) &nb
sp; { &nb
sp; LED1_Toggle(); &nb
sp; if (!(NumMsgsSent % ONE_K)) &nb
sp; { &nb
sp; LED2_Toggle(); &nb
sp; if (!(NumMsgsSent %
TEN_K)) &nb
sp;
LED3_Toggle(); &nb
sp; } &nb
sp; }
Bad-enough case, even with an
unsigned short, it breaks overnight: It also breaks if I use if ( 0 == (NumMsgsSent % 100)
), instead of if (!(NumMsgsSent % 100)) . // not OK with an
ushort, either, but it runs for much longer before dying &nb
sp; if (!(NumMsgsSent %
100))
&nb
sp; LED1_Toggle();
This runs fine
overnight, without any "%" modulus: if
(NumMsgsSent >= 256) &nb
sp; { &nb
sp; NumMsgsSent = 0; &nb
sp; LED2_Toggle(); &nb
sp; }Note that instances of (var % 256) get turned by the
compiler into (var & 256), so those don't do any messy math. I've
used that for months without problems.
LIBRARY CODE, from "mixed source"
screen:
Here's the asm library function that is JSRed to for if
(!(NumMsgsSent % 100)) . I notice that different code is used for % 1,000
or %10,000, but the problem occurs even when I only do % 100 :
if (!(NumMsgsSent % 100)) jsr
01238 ARTREMU16Z.asm support/runtime56800E/math_support
tst.w
y1 ; Check on
high bit, should be zero . . .
P:00001238:
8F07
tst.w Y1 &nb
sp; &n
bsp; ; Required carry bit is cleard too!
blt High_bit_present ;
If bit 15 on, result is either 1 or 0 P:00001239:
A51B
blt @DummyFn1+0x1d (0x1255) ; 0x000938 P:0000123A:
E700
nop
lsr16
y0,b ; Copy dividend to b0 no
sign extension P:0000123B:
7CD7
lsr16 Y0,B ;;;;;;;;;;;;;;;; 4-bit division ;;;;;;;;;;;;;;;;
div
y1,b ; form quotient in b0 P:0000123C:
78FF
div Y1,B
div y1,b P:0000123D:
78FF
div Y1,B
div y1,b P:0000123E:
78FF
div Y1,B
div y1,b P:0000123F:
78FF
div Y1,B ;;;;;;;;;;;;;;;; 4-bit division ;;;;;;;;;;;;;;;;
div
y1,b ; form quotient in b0
P:00001240:
78FF
div Y1,B
div
y1,b &
nbsp;
P:00001241:
78FF
div Y1,B
div y1,b P:00001242:
78FF
div Y1,B
div
y1,b &
nbsp;
P:00001243:
78FF
div Y1,B ;;;;;;;;;;;;;;;; 4-bit division ;;;;;;;;;;;;;;;;
div
y1,b ; form quotient in b0 P:00001244:
78FF
div Y1,B
div y1,b P:00001245:
78FF
div Y1,B
div y1,b P:00001246:
78FF
div Y1,B
div y1,b P:00001247:
78FF
div Y1,B ;;;;;;;;;;;;;;;; 4-bit division ;;;;;;;;;;;;;;;;
div
y1,b ; form quotient in b0 P:00001248:
78FF
div Y1,B
div y1,b P:00001249:
78FF
div Y1,B
div y1,b P:0000124A:
78FF
div Y1,B
div y1,b P:0000124B:
78FF
div Y1,B ;;;;;;;;;;;;;;;; check sign of quotient and adjust accordingly
tst
b ; Result
sign in N bit of SR P:0000124C:
70BB
tst B
bge
Positive_rem ; if remainder is positive, ok P:0000124D:
A403
bge @DummyFn1+0x19 (0x1251) ; 0x00092a P:0000124E:
E700
nop Fix_required_remainder:
add
y1,b ; restored remainder, b
is negative P:0000124F:
78F0
add Y1,B P:00001250:
E700
nop &n
bsp; &
nbsp; ; y1-b Positive_rem:
rtsd &
nbsp; ; delay return after
nxt 3 instr P:00001251:
E70C
rtsd
move.w
b1,y0 ; move result value into
return register P:00001252:
8511
move.w B1,Y0
nop &n
bsp; ; filler P:00001253:
E700
nop
nop &n
bsp; ; filler P:00001254:
E700
nop ;;;;;;;;;;;;;;; Quotient result is either be 1
(REM = y0-y1) or 0 (REM = y0) High_bit_present:
move.w
y0,b ; set REM to dividend,
y0, for quotient = 0 P:00001255:
8105
move.w Y0,B
sub
y1,y0 ; REM valid if y0 >= y1
(quotient = 1) P:00001256:
7AF1
sub Y1,Y0
tcc
y0,b ; if quotient = 1, REM =
y0-y1 P:00001257:
709F
tcc Y0,B
rtsd &
nbsp; ; delay return after
nxt 3 instr P:00001258:
E70C
rtsd
move.w
b1,y0 ; move REM value into return
register P:00001259:
8511
move.w B1,Y0
nop &n
bsp; ; filler P:0000125A:
E700
nop
nop &n
bsp; ; filler P:0000125B:
E700
nop
FWIW, here's what I use for LEDs, borrowed from P.E.: #define LED6_Toggle()
(changeRegBits(*GPIO_D_DR,128)) #define LED1_Off()
(clrRegBits(*GPIO_C_DR,1))
The inner loop of my delay function reads the timers as
often as it can, but does 32-bit arithmetic: while ( NowTick <
DoneTick )
TMRD3D2_TICKS_LONG ( NowTick );
where the macro is: #define TMRD3D2_TICKS_LONG( LongVar ) { \ LongVar =
(*TMR_D2_CNTR); \ LongVar <<=
16; &n
bsp; \ LongVar +=
(*TMR_D3_HOLD); }
Is it conceivable that reading a timer too frequently is somehow
stalling an ISR? The HOLD register? Long arithmetic??
Rick Corey Senior Software Engineer DPC Instrument Systems Division _____________________________________ /groups.php3 <http://www.dsprelated.com/groups.php3
_____
> .
_____________________________________ /groups.php3
Yahoo! Groups
Links
_____________________________________ /groups.php3
|