in C51, if I use overlap optimize, my project have problem.( routine R1 changed routine R2's auto variable). if I do not use overlap optimize. the problem gone. Is this Keil's problem? I guess so. How dose Keil do overlap optimize?
Are you sure it's a problem with the optimization, or a problem with the overlay analysis? There are a number of ways that you can wind up with a call tree that is incorrect, generally involving function pointers. If the call tree is not correct, then the assignment of auto variables to memory locations could overlap inappropriately and cause that symptom. Sometimes you have to tweak the the overlay tree manually to get the right results. The manual has a discussion of the overlay processing that you might want to study; there's also an app note. (And old discussions on this board, of course.)
If I understand correctly what you have written, you have two functions (R1 and R2) that both have automatic variables. The optimiser is allocating the same (or overlapping) addresses to the automatic variables of both funtions - which is exactly what it is supposed to do. Within a function, your software should not make any assumptions about the value of an automatic variable when the function is started. If you want a variable to have a specific value when a function starts, you can define it as automatic but include an initialiser value (or assign a value before you start to use the variable). If you want a variable to have a value that persists between calls to a function, you must define the variable a static.
I am sure it's overlay problem. I tried use a static variable as a copy of R1's auto variable, then worked around. or I turned off overlay optimise option, the problem gone. From this I make conclusion. It dose is Keil's problem. BTW, I did not make any assumption for auto variable. the R1 routine is following. enum { FILTER_FR, FILTER_COLOR }; f_rotate_motor() function will be block for 300ms. so, R2 get to run, R2 has a pointer variable use the same address as FilterPos. When R1 resumed, FilterPos changed. bit f_set_filter( byte FilterPos ) { bit success; ASSERT ( FilterPos == FILTER_FR || FilterPos == FILTER_COLOR ); if ( FilterPos == FILTER_COLOR ) { if ( f_current.filter_position == FILTER_COLOR ) { success = TRUE; motor_color_flt++; } else if ( f_current.filter_position == FILTER_FR ) { success = f_rotate_motor ( FLUOR_DEGREE, COLOR_DEGREE, 1 ); ASSERT ( FilterPos == FILTER_FR || FilterPos == FILTER_COLOR ); } else ASSERT( FALSE ); ASSERT ( FilterPos == FILTER_FR || FilterPos == FILTER_COLOR ); } else if ( FilterPos == FILTER_FR ) { if ( f_current.filter_position == FILTER_COLOR ) { success = f_rotate_motor ( COLOR_DEGREE, FLUOR_DEGREE, 1 ); ASSERT ( success == TRUE ); } else if ( f_current.filter_position == FILTER_FR ) { success = TRUE; } else ASSERT( FALSE ); ASSERT ( FilterPos == FILTER_FR || FilterPos == FILTER_COLOR ); } else { ASSERT_W( FALSE ); } if ( success == TRUE ) { ASSERT ( FilterPos == FILTER_FR || FilterPos == FILTER_COLOR ); f_current.filter_position = FilterPos; } return success; }
_rotate_motor() function will be block for 300ms. so, R2 get to run This line sounds like you're using some sort of RTOS to switch between your tasks. If you have two different tasks that can preempt each other, then you need to manually adjust the overlay tree to be sure each task has its own "stack". Each independent thread needs to be an independent root of an overlay tree. See chapter 9 of the linker manual. Turning overlaying off entirely will of course avoid the problem, at the cost of using up a lot of memory.