Hi there,
I am currently seeing a relatively strange occurrence with the Keil compiler and linker overlapping two pieces of code into the same code area without showing any warnings or errors to the user.
Here are the details:
* Compiler/Linker versions:
CX51 COMPILER V9.02 - SN: K1NCC-YA1WVE COPYRIGHT KEIL ELEKTRONIK GmbH 1987 - 2010
LX51 LINKER/LOCATER V4.47a - SN: K1NCC-YA1WVE COPYRIGHT KEIL ELEKTRONIK GmbH 1995 - 2010
* Attached map file (linker_overlap.map), lines 651 - 653:
00CD88H 00CD93H 00000CH BYTE UNIT CODE_TIMER/B3 ?PR?_TIMER_INIT?TIMER *** OVERLAP *** 00CD89H 00CD95H 00000DH BYTE UNIT CODE/B3 ?L?COM000A
The linker is clearly overlapping two functions (timer_init and a linker optimized code block) in the same code space, causing timer_init to contain invalid code. It clearly detects it during linking, since it prints and *** OVERLAP *** message in the .map file, but it shows no errors or warnings.
* Additional details:
- Multiple libraries linked in with a mix of linker code packing enabled and disabled per library. - Warning level set to 2 in the .lin file (WARNINGLEVEL(2)) - Optimization level set to 9 (Common Block Subroutines) in all libraries
Thanks in advance!
Carles
a) We are linking against an .omf file which is a precompiled ROM b) We make use of bank switching in both the ROM code and the final project
And you honestly expected that kind of contraption to work? Wow, you must be one brave coder.
Honestly, we kinda were expecting it to work :) and in fact it did until very recently when we spotted this problem.
You still haven't said that there is any actual problem in the operation of the system
From my previous post:
2) The first assembly instruction in timer_init() is also an LCALL but this time the address that follows it causes the flow to jump into the middle of function_x() in the common area. As per your suggestion, we just verified whether that could be an optimization trick used by the linker, but when we step through this code segment we see that function_x() completes as if it was called. This is not an integer division and the control flow never returns back to timer_init(), as it should if this was indeed an optimization.
When the problem occurs, the flow never returns to timer_init() and the code basically vectors into space. This particular function, timer_init() is invoked from our main() but since it never returns from it, the software effectively hangs completely, not being able to proceed into the actual useful code that is run after the initialization functions (timer_init() being one of them).
Thanks!
I see.
I think Keil support is your only hope here; it's just too deep for people on a forum - with no sight of your system or your source code - to make meaningful, detailed analysis or comments.
Or maybe you need to get in an indepenent reviewer?
A forum can only really give general observations, like the fact that you are making this really, really, really complicated - and that is just asking for trouble!
When you get to a stage like this where you're having to pull every single trick in the book to the max to fight the limitations of the 8051 architecture, you really have to ask yourself whether it's worth the effort - or would it be less trouble to switch to another architecture that just doesn't have the limitations that you're fighting...
Sorry - no easy answer there!
Yep, as I think I mentioned earlier, we have already contacted Keil's support for this. However I thought I might as well give it a shot in the forums, although I am perfectly aware that not all information required has been made available.
Yes, indeed I agree with you.
Thanks for your help!