Go to Post Don't rely on the field staff to get every ball to work with your machine....engineer a robot that makes the change not matter. - PayneTrain [more]
Home
Go Back   Chief Delphi > Technical > Programming
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
 
 
Thread Tools Rate Thread Display Modes
Prev Previous Post   Next Post Next
  #12   Spotlight this post!  
Unread 16-02-2006, 11:21
Mike Bortfeldt Mike Bortfeldt is offline
Registered User
FRC #1126 (& 1511)
Team Role: Mentor
 
Join Date: Oct 2004
Rookie Year: 2004
Location: Rochester, NY
Posts: 119
Mike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud ofMike Bortfeldt has much to be proud of
Re: Presence of function causes auton to fail???

Kyveck,

As you probably know, when an interrupt occurs, the processor pauses execution wherever it happens to be in the normal loop code and begins executing the interrupt code. In the case of the low priority interrupts, this is done by the InterruptHandlerLow routine. By default, the compiler saves the values most of the basic registers on the stack at the beginning of the interrupt and then restores these registers back to their original value at the end of the interrupt. This allows the processor to continue executing your normal loop code as if the interrupt never occurred (other than a time delay). However, there are several registers and data memory sections that are typically used by the normal loop code that are not saved. The most common register is the 16 bit PROD register. This register stores the result of 8 bit multiplies, 16 bit return values from functions and a host of other things. Normally, any code you will write in the ISR (interrupt service routine) will probably utilize the PROD register. This is why in the #pragma statement above the InterruptHandlerLow routine has the part about "save=PROD". This tells the compiler to save the value of the PROD register when beginning the interrupt, and restore it when exiting. There are also two data memory sections that are frequently used by the compiler. The first one is the ".tmpdata" section. This is a block of data memory (in the access data area) that is used by the compiler as a temporary data storage area. The compiler typically stores intermediary values from calculations in this area when a more complex statement is encountered in code. This area is used (and reused) all throughout your code. If the compiler has a value stored in this temporary data section and an interrupt occurs, this area can become corrupted if the interrupt code shares a common temporary data location. The result of this can sometimes be seen in code not seeming to execute correctly, odd jerkiness of your bot, or a host of other things and can appear to be quite random. The second data section is the "MATH_DATA". All the more complex integer math routines (other than addition/subtraction) and all floating point math use this section when passing arguments and returning values and as temporary storage during processing of the calculation. If your ISR uses any multiplies, divides, or floating point values, you will probably be utilizing the "MATH_DATA" section. Like the ".tmpdata" section, if your ISR uses the "MATH_DATA" section when your normal code is in the middle of a calculation, your ISR could corrupt the values needed by the normal loop code. Like the "save=PROD" above, adding the 'section(".tmpdata"), section("MATH_DATA")' to the #pragma line instructs the compiler to restore these memory locations to their original value at the end of the interrupt.
The downside to saving these additional data sections is that it increases the time the processor needs to spend handling EVERY interrupt. The ".tmpdata" section size is dependant on your code, but the default 2006 code has a 12 byte area (this information can be found in the .map file) that requires about 76 instruction cycles to save and another 76 to restore. This adds about 15 microseconds to every interrupt call. The "MATH_DATA" section has a size of 20 bytes and will add a total of about 25 more microseconds. Normal context saving and execution of the interrupt is probably in the neighborhood of 4-5 microseconds, so each interrupt could delay your normal code processing by 45 microseconds before you even execute a single instruction of your actual interrupt code.
This is why you'll generally hear people say that you should only do what is absolutely necessary within an interrupt. If you can code your interrupts such that they don't require the ".tmpdata" and "MATH_DATA" sections and take very little time themselves, you can save a significant amount of processor time and be able to handle a much higher rate of interrupts, leave more time for your normal program loop and reduce the chance that you might miss an interrupt altogether (a floating point calculation within an interrupt is a very bad idea). To give you an example, this year, we are using interrupts to handle 3 encoders (max 3200 interrupts / second each), a 250 microsecond timer as a clock (4000 interrupts/sec), AI port scanner, TTL & Program port serial driver (maybe 1000 interrupts / sec total between the them) without any problems. However, they are all coded such that they only require us to save the PROD register. This took a while as it required us to examine the assembly code listing file and recode until we were able to get the functionality we needed without the compiler using any of the ".tmpdata" section variables. One thing you can easily do if you use a "if - else if" type statement in the InterruptHandlerLow routine, is to place the higher rate interrupts early in the if statement. This will allow the processor to find the "correct" interrupt faster reducing the overall time spent processing interrupts.
Without actually seeing your code, I can't tell if you need to save the "MATH_DATA" and ".tmpdata" sections, so to be on the safe side, I recommended saving both of them. This is the quick way to test to see if the interrupts were causing your problem without actually changing any of your code.

Sorry for the long post, but I hope it's useful.

Mike
 


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Loop time for OperatorControl function? Debug blows... Chris_Elston Programming 10 13-02-2006 14:42
TTL port to a serial port on a demo board ImmortalAres Programming 16 09-07-2005 23:44
Auton + Functions ten3brousone Programming 0 27-02-2005 20:11
RoboEmu2(code simulator)--now with C! rbayer Programming 23 17-02-2005 09:17
heres the code. y this not working omega Programming 16 31-03-2004 15:18


All times are GMT -5. The time now is 11:56.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi