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:
if (!(NumMsgsSent % 100))
{
LED1_Toggle();
if (!(NumMsgsSent % ONE_K))
{
LED2_Toggle();
if (!(NumMsgsSent % TEN_K))
LED3_Toggle();
}
}
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
if (!(NumMsgsSent %
100))
LED1_Toggle();
This runs fine overnight, without any "%" modulus:
if (NumMsgsSent >= 256)
{
NumMsgsSent = 0;
LED2_Toggle();
}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
; 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
P:00001241:
78FF
div Y1,B
div
y1,b P:00001242:
78FF
div Y1,B
div
y1,b
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
; y1-b Positive_rem:
rtsd
; 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
; filler P:00001253:
E700
nop
nop
; 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
; 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
; filler P:0000125A:
E700
nop
nop
; 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;
\ 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 _____________________________________ Note: If you do a
simple "reply" with your email client, only the author of this message will
receive your answer. You need to do a "reply all" if you want your
answer to be distributed to the entire group.
_____________________________________ About this discussion group:
To Join: m...@yahoogroups.com
To Post:
m...@yahoogroups.com
To Leave: m...@yahoogroups.com
Archives: http://www.yahoogroups.com/group/motoroladsp <http://www.yahoogroups.com/group/motoroladsp>
More Groups:
http://www.dsprelated.com/groups.php3 <http://www.dsprelated.com/groups.php3
_____
> .
_____________________________________ Note: If
you do a simple "reply" with your email client, only the author of this
message will receive your answer. You need to do a "reply all" if you want your answer to be distributed to the entire group.
_____________________________________ About this discussion group:
To Join: m...@yahoogroups.com
To Post:
m...@yahoogroups.com
To Leave: m...@yahoogroups.com
Archives: http://www.yahoogroups.com/group/motoroladsp
More Groups:
http://www.dsprelated.com/groups.php3
Yahoo! Groups Links
_____________________________________ Note: If you do a simple
"reply" with your email client, only the author of this message will receive
your answer. You need to do a "reply all" if you want your answer to be
distributed to the entire group.
_____________________________________ About this discussion group:
To Join: m...@yahoogroups.com
To Post:
m...@yahoogroups.com
To Leave: m...@yahoogroups.com
Archives: http://www.yahoogroups.com/group/motoroladsp
More Groups:
http://www.dsprelated.com/groups.php3
|