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 -------------------------------------------------------
do you get any linker warnings or did you disable any linker warnings?
Compiler: WarningLevel = 2 (max warninging level as far as I can tell)
Linker: No warnings have been disabled.
Build output has 12 identical warnings: SOCKET.C(213): warning C182: pointer to different objects
The culprit of which is a function that recieves a char argument, and does the following:
//declarations u_char xdata* src2 long xdata* src2_long; func() { src2_long = src2; dst_long = dst; }
I can eliminate the warnings by making a type cast:
src2_long = (long xdata*)src2; dst_long = (long xdata*)dst;
...but I'll have to read the compiler manual to be sure what the effect of the cast is (as I don't know enough about 8051/Keil and xdata types, yet).
Testing the type casted code on the system did not fix the underlying problem that causes the system to hang.
Optimization I've been changing the optimization and have the following results:
OPTIMIZATION_LEVEL = 5 compiles with no warnings
OPTIMIZATION = 4 (resigter variables) compiling SOCKET.C... SOCKET.C(168): error C253: INTERNAL ERROR (ASMGEN - TRIPLE=0FB[00961289]) SOCKET.C(168): error C253: INTERNAL ERROR (ASMGEN - TRIPLE=103[00961421]) compiling dolphin_utils.c... compiling memory_mapping.c... compiling MAIN.C... compiling startup_utils.c... Target not created
The code refered to is:
send_ptr = (u_char *)(SBUFBASEADDRESS[s] + (UINT)(wr_ptr.lVal & SMASK[s]));
Keil Error description: This error can occur under the following circumstances: An intrinsic function (for example, _testbit_) was activated incorrectly. This is the case when no prototype of the function exists and the number of actual parameters or their type is incorr --->this doesn't make sense to me in this context.
OPTIMIZATION = 2 & 3 *** WARNING L15: MULTIPLE CALL TO SEGMENT SEGMENT: ?PR?_PUTBYTE?SERIAL CALLER1: ?PR?TIMER0_ISR?DOLPHIN_UTILS CALLER2: ?C_C51STARTUP
1. Is it not strange that the ERROR I get with optimization = 4, does not appear with optimization = 2 or 3?
2. Could the bug have anything to do with the warning for optimization levels 2&3...i.e. a code re-entrancy problem. This is my best guess at the moment, so my strategy is to keep optimization to a minimum and continue.
Thanks for the help.
Decreasing the optimization level to 2 seems to remove the crash (long term test running overnight now). /Simon
The internal error is indeed strange. Please try the current release (Eval Verison should do the job). If the Internal Error still appears, send us a test file that allows us to reproduce the error.
Email for support is: support.intl@keil.com
I've installed the latest evaluation version (v8.09). I got a few new errors: "warning C318: can't open file '89c51rd2.H'" which caused a lot of "error C202: 'WDTRST': undefined identifier".
I fixed those and now have erros cuased by memory allocation: RAMSIZE(256) *** WARNING L15: MULTIPLE CALL TO SEGMENT SEGMENT: ?PR?_PUTBYTE?SERIAL CALLER1: ?PR?TIMER0_ISR?DOLPHIN_UTILS CALLER2: ?C_C51STARTUP *** ERROR L107: ADDRESS SPACE OVERFLOW SPACE: DATA SEGMENT: ?DT?DOLPHIN_UTILS LENGTH: 001CH *** ERROR L107: ADDRESS SPACE OVERFLOW SPACE: DATA SEGMENT: ?DT?SPECIAL_LAN_SEND LENGTH: 0008H *** ERROR L107: ADDRESS SPACE OVERFLOW SPACE: DATA SEGMENT: ?DT?MEMORY_MAPPING LENGTH: 0005H *** ERROR L107: ADDRESS SPACE OVERFLOW SPACE: DATA SEGMENT: ?C?LIB_DATA LENGTH: 0001H *** ERROR L105: PUBLIC REFERS TO IGNORED SEGMENT SYMBOL: SENDBUF SEGMENT: ?DT?DOLPHIN_UTILS
ETC.....
****************************************************************************** * RESTRICTED VERSION WITH 0800H BYTE CODE SIZE LIMIT; USED: 4733H BYTE (889%) * ****************************************************************************** Program Size: data=171.0 xdata=154 code=19042 LINK/LOCATE RUN COMPLETE. 1 WARNING(S), 45 ERROR(S)
*** FATAL ERROR L250: CODE SIZE LIMIT IN RESTRICTED VERSION EXCEEDED MODULE: SERIAL.obj (-----) LIMIT: 0800H BYTES Target not created
-------------------------------------------------------
So I don't think I will be able to use the evaulation version as I doubt whether it will create a target once I have got rid of all the errors, or am I wrong?
Has there be a significnt increase in the librbaries from version 7.03? I'll take a closer look at the mapfile, but it seems a bit strange that the code has increased in size that much, so it must be the evaluation limit I have exceeded (by 889% according to compiler).
I'll use the support email you suggest as it will be easier to exchange files. Thanks for the help to date.
So I don't think I will be able to use the evaulation version as I doubt whether it will create a target once I have got rid of all the errors, or am I wrong? I see no error that relates to using the eval.
Erik
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.
"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