Hi,
I have a strange problem with some code, and I am beginning to suspect that there may be a problem with the C51 compiler or at least my use of it.
The processor runs on a small custom made board that is used to output data via a phy module over UDP to a PC unit. There is no operating system, just the usual while(1) loop. The Atmel has a single watchdog timer that resets the processor if the timer is not reset within a given time.
For some reason, that I have not been able to determine yet, the Atmel processor hangs after approx. 3 minutes running sending UDP packets as it should - it is then eventually reset by the timer. Although I cannot explain why the system hangs, I have however been able to fix the problem by inresting 3 No-operation calls (NOPs) in the code (see code excerpt below). The system will thereafter run for >1 week without failing.
This strange thing is that the code where the NOPs are inserted is never executed, so timing should not be the issue - only memory allocation. Unfortunately the optimization is set to level8. This makes it hard to get an overview.
The one thing I have notiiced in the memory map is that the sections: ?CO?MAIN and ?PR?TIMER0_ISR?
get switched when adding the NOP functions. The same switch occurs when setting optimization to level=0 (although I can't run this unlinked code).
-Is there anyone out there that has some suggestions as to how I can go about debugging this problem? -Are there tools available that would give me some more insight into what is going on in memory runtime? -Any know bug with the compiler that may be the cause (also considering the high optimization level)?
CODE:
void timer0_ISR (void) interrupt 1 { ET0 = 0; // disable Timer 0 Interrupts if ((timer0OverflowCount) == 1*HeartBeatTimeOutSeconds) //(1.02s to be precise) { timer0OverflowCount = 0; if (P1_2 == 1) //Channel is on. No need to reset if it is off. { PutString("timer0 timed out because of missing heartbeats. Reset imminent."); PutStringLn(""); ResetFlag = 1; while(1); } } timer0OverflowCount++; // increase the overflow cnt TH0=0; //reset timer TL0=0; ET0 = 1; // Enable Timer 0 Interrupts _nop_ (); _nop_ (); _nop_ (); }
.
Setup:
Keil uVision2 Compiler: C51&A51 V7.03 (also tried upgrade to V7.08) Linker V5.02
------------------------------------------------------- Device: T89C51RD2 8051 based CMOS controller with PCA, Dual DPTR, WDT 40 MHz High-Speed Architecture, X2 function, 32/48 I/O lines, 3 Timers/Counters, 7 Interrupts/4 priority levels 64K FLASH, 2K EEPROM (Boot Flash) , 256 Bytes on-chip RAM, additional 1K XRAM -------------------------------------------------------
I see no error that relates to using the eval.
Wow! I didn't realise you actually were blind.
only spottily, I see it now. Thanks for getting it right.
Erik
"the first place you go blind is on the eyes"
She always said that when I missed seeing something.
just to conclude on what has been done:
When setting the compiler to optimization level 2 or 3 I got a warning pointing to re-entrancy problems; a call to PrintByte() of significant length inside the Timer0_ISR(). I have eliminated this problem by removing the code from the ISR.
I am running stability tests, but so far I can say that with high probility the problem seems to have been removed. I have notified support of the issues related to optimizer (and the lack of warnings with different settings). And of the internal error mentioned in one of my earlier posts.
Unfortunately I am not able to test to see if the problems exist with the latest version as the evaluation version has code size limits that I hit.
Thanks to all that have helped me in my quest!
Regards, Simon
P.S. After reading some similar posts I feel more confident that the issue I found is related to the stability problem I observed. (Muliple call to segments (re-entrancy) http://www.keil.com/support/docs/805.htm http://www.keil.com/support/docs/2042.htm