We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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 -------------------------------------------------------
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