|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
For some weird reason, our code seems to error out on the 2007 RC and causes it to fall into programming mode. It usually takes between 100-200 seconds to happen, and once its in programming mode, IFI's dashboard doesn't show any errors either. Does anyone know potentially issues that would cause this? Please don't ask for the code as I am not allowed too post it anywhere as we are busy working on something (hopefully) unique. We are considering releasing the finished product.
|
|
#2
|
|||||
|
|||||
|
Re: Code error causing robot to go into programming mode.
The master CPU is in charge of putting the robot in program mode. Without specific additional hardware, there is not supposed to be any way for the user program, misbehaving or otherwise, to do it.
Is something intermittently grounding the PROG pin on the RC? Make sure the three-pin PROG/RESET connector is free of metal shavings. Is your master code corrupt? Try reloading it (and remember to reload your user code immediately afterward). |
|
#3
|
|||
|
|||
|
Re: Code error causing robot to go into programming mode.
We have had code faults/freezups that lit the program
light, but it wasn't really in program mode. We have had to hold the program button down for the usual amount of time to get it into program mode, not being able to see the light change, to load a new program to recover the RC. Given the "uniqueness" of what you are doing, and the stated fact that you don't want to expose it to get help, you are handicapping those who might be able to help. Eugene |
|
#4
|
|||
|
|||
|
Re: Code error causing robot to go into programming mode.
"The master CPU is in charge of putting the robot in program mode."
Out of curiosity, how is this done? It doesn't appear to be using the ICSP programming as that requires the RB5/PGM pin to be dedicated to programming mode and therefore cannot be used as general io bit, but it is available on the user processor so... Also, the rs232 port used to download data is connected to the user processor, does this mean that it is connected to both the master and shared processor? The SPI port communications between the master and slave only communicate the fixed size data io controller tx/rx packets via double buffering... there doesn't appear to be anything else communicated via this path when I looked at the SPI port, although it is possible there is more code for this port other than the high priority interrupt routine. I was always under the impression that the boot block in 0..800h contained the program download bootloader within the user processor and once put into program mode, this code within this boot block on the user processor was running. |
|
#5
|
|||
|
|||
|
Re: Code error causing robot to go into programming mode.
After some investigation, we have arrived at a couple conclusions:
As I can't post the code, I realize we have to track down the issue ourselves. Other then that, does anyone else have an idea why the robot can fall automatically in programming mode from code? If we find any other methods, we will report back. |
|
#6
|
|||||
|
|||||
|
Re: Code error causing robot to go into programming mode.
Oops, I was thinking of a different system. My mistake.
|
|
#7
|
|||
|
|||
|
Re: Code error causing robot to go into programming mode.
The most likely cause is a random jump/call into the bootloader code in lower memory where I believe the program load code lives.
Look for computed jumps or function calls. These are the most likely culprits. Its possible if you are doing something like: Code:
void (*myfunction)(void);
:
myfunction = function1;
:
myfunction();
}
Another option is poor power conditioning resulting in drop outs, brown outs, or noise spikes that could cause strange execution results... but this would be low on my list of suspects. Try printing out the address of any computed function calls like above or any computed jumps. Computed jumps are sometimes used for case and other tables by computing and offset and then directly writting to the PC<low> address register. Print out the computed address before invoking the jump. |
|
#8
|
|||
|
|||
|
After some intensive investigation, we tracked down the issues to the interrupts. The default code has this defined:
Code:
#pragma code #pragma interruptlow InterruptHandlerLow save=PROD/* You may want to save additional symbols. */ void InterruptHandlerLow () Code:
#pragma code
#pragma interruptlow InterruptHandlerLow save=PROD, section(".tmpdata") /* You may want to save additional symbols. */
void InterruptHandlerLow ()
|
|
#9
|
|||
|
|||
|
Re: Code error causing robot to go into programming mode.
There are conditions for which you may also need to save MATH_DATA,
depending on just what is in the functions you are using. #pragma interruptlow InterruptHandlerLow save=PROD,section("MATH_DATA"),section(".tmpdata") |
|
#10
|
||||
|
||||
|
Re: Code error causing robot to go into programming mode.
Can someone explain what exactly the line
#pragma interruptlow InterruptHandlerLow save=PROD,section("MATH_DATA"),section(".tmpdata") actually does.. i've always wondered |
|
#11
|
|||||
|
|||||
|
Re: Code error causing robot to go into programming mode.
Code:
#pragma interruptlow InterruptHandlerLow save=PROD,section("MATH_DATA"),section(".tmpdata")
|
|
#12
|
||||
|
||||
|
Re: Code error causing robot to go into programming mode.
Thanks!
|
|
#13
|
|||
|
|||
|
Re: Code error causing robot to go into programming mode.
Quote:
Code:
#pragma code InterruptVectorLow = LOW_INT_VECTOR
void InterruptVectorLow (void)
{
_asm
goto InterruptHandlerLow /*jump to interrupt routine*/
_endasm
}
Code:
#define LOW_INT_VECTOR 0x818 This might seem weird as the hardware vector addresses for the PIC18F are: Code:
0000 - reset 0008 - high priority interrupt vector 0018 - low priority interrupt vector See section 2.8 of the compiler user's guide. Pragmas tend to be hints to the compiler and linker as to the programmer's intent. A #pragma code indicates that the following contains executable code, vs a #pragma romdata which would indicate the following contains variables and data. This section of the manual is a little misleading. The #pragma interrruptlow is used to declare a low priority interrupt handler, but what it REALLY does is change how the compiler works for the named routine. It inserts a context save at the beginning of the routine, a context restore at the end of the routine, and changes return not to a PIC18F RETURN instruction as it would for "normal" functions, but a RETFIE (return and enable interrupts). Code:
025E4 InterruptHandlerHigh
; context save, minimum by this version of the compiler
; by default is STATUS, BSR (bank select register), and W register
02E4 CFD8 MOVFF STATUS, PREINC1
025E6 FFE4 NOP
025E8 CFE0 MOVFF BSR, PREINC1
025EA FFE4 NOP
025EC 6EE4 MOVWF PREINC1, ACCESS
:
.
; ok, this is the end of the handler, restore context of W, BSR,
; and then STATUS before returning to user code
0261A 50E5 MOVF POSTDEC1, W, ACCESS
0261C CFE5 MOVFF POSTDEC1, BSR
0261E FFE0 NOP
02620 CFE5 MOVFF POSTDEC1, STATUS
02622 FFD8 NOP
02624 0010 RETFIE 0
Quote:
This is just one facet of interrupt routines that make it so interesting to make bullet proof interrupt handlers that always works. Other registers that could/might need to be saved are the table registers, FSRs, and others that are used by the compiler for various purposes including array computions and accesses. The safest thing to do is add a long list of things to save... but that slows down the interrupt routine by increasing the size of the context that needs to be saved... but it is the safest. To save a minimum context requires the programmer to analyze the interrupt routine code generated to see which registers and ram are used and make sure they are in the saved context. There are lots of games that can be played to reduce context save time. One way is to save a minimum context for the main interrupt routine and then save a different/fuller context for each specific handler. Code:
#pragma interruptlow __InterruptHandlerLow save=PROD /* You may want to save additional symbols. */
void __InterruptHandlerLow ()
{
unsigned char int_byte;
if (INTCON3bits.INT2IF && INTCON3bits.INT2IE) /* The INT2 pin is RB2/DIG I/O 1. */
{
INTCON3bits.INT2IF = 0;
HandleInt2();
}
else if (INTCON3bits.INT3IF && INTCON3bits.INT3IE) /* The INT3 pin is RB3/DIG I/O 2. */
{
INTCON3bits.INT3IF = 0;
HandleInt3();
}
else if (INTCONbits.RBIF && INTCONbits.RBIE) /* DIG I/O 3-6 (RB4, RB5, RB6, or RB7) changed. */
{
int_byte = PORTB; /* You must read or write to PORTB */
INTCONbits.RBIF = 0; /* and clear the interrupt flag */
} /* to clear the interrupt condition. */
else
{
CheckUartInts(); /* For Dynamic Debug Tool or buffered printf features. */
}
}
#pragma code
#pragma interruptlow HandlerInt2 save=PROD,section("MATH_DATA"),section(".tmpdata") /* You may want to save additional symbols. */
void HandlerInt2() {return;}
void HandlerInt3() {return;}
As I said, lots of different games can be played with the pragmas but all require programmers to understand what they are asking the compiler to do and why. Its one of the reasons that the save list tends to grow to fairly extensive lengths. |
|
#14
|
|||
|
|||
|
Re: Code error causing robot to go into programming mode.
In the code example above, the PROD registers are saved/restored in a nested manner although from the discussion this was not intended.
The W,BSR, and STATUS registers are also saved/restored in a nested manner when the strategy described above is used and you might be better off writing your own version of whatever math routine that you need, with its own internal state, that does not require saving/restoring MATH_DATA if performance is an issue. In addition to the business of saving/restoring data that the interrupt handler uses you also have to worry about race conditions when communicating multi-byte data between the interrupt handler and the main program. The individual bytes of a multi-byte value are read/written one at a time on the micro-controller and the interrupt can strike between these individual reads/writes, leading to a corrupt multi-byte value being transferred between the interrupt handlers and the main program. So, write that interrupt code and associated accessor routines with care... Eugene Last edited by eugenebrooks : 29-10-2007 at 02:39. |
|
#15
|
|||
|
|||
|
Re: Code error causing robot to go into programming mode.
The real gotcha is upon returning from HandlerInt2() in the example, interrupts are turned back on by the RETFIE at the end of HandlerInt2. Not too much of a problem unless the machine is saturated with interrupts and then a stack overflow condition may randomly occur due to nesting of the main interrupt handler. Turning interrupts back off in the main isr upon return would limit the exposure to this problem to only 1-2 instruction cycles. But there are better methods that can be used to avoid this althogether.
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Error in code light on, trouble finding error | Bryan Herbst | Programming | 16 | 12-10-2007 21:59 |
| Strange ERROR.MCP file coming up Robot not programming! | Salik Syed | Programming | 5 | 08-05-2006 21:46 |
| RC randomly resets or goes into program mode | Tom Bottiglieri | Programming | 4 | 15-02-2006 23:32 |
| how to convert Easy C code into real code? | TheHolyLancer | Programming | 1 | 29-01-2006 09:09 |
| Inserting Naviagation code into Default code? | actorindp | Programming | 3 | 28-01-2004 18:12 |