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.
I am trying to put a subroutine at a fixed address (I want it to remain fixed after the code is rebuilt and other modules are changed). First I linked my code and obtained its absolute linked address (assigned by the linker). Then I used the _at_ (0x07A) command in the C source file. I got a FIXUP error when I linked. When I did the same thing using the linker SE command, I didn't get any errors. I really wanted to cast the addresses in the source C code file using the _at_ command but I am having problems.... Any thoughts... Thanks, Jim
Jim Okay, to find the problem, first when you compile the file that has the ?PRBOOT_MSGHDLR?BMSGHDLR in it, use the CD option. This appends an assembler listing to the list file. From the listing file, find the 00006F offset address from the :?PRBOOT_MSGHDLR?BMSGHDLR segment. That instruction will contain the address that the linker cannot handle. In my example below, I could get a FIXUP message at address 000005, if the function I was calling could not be reached by that particular instruction. This can also happen with data accesses. ; FUNCTION Context_SaveProgId? (BEGIN) ; SOURCE LINE # 48 000000 CA3B PUSH DR12 000002 7F30 MOV DR12,DR0 ;---- Variable 'sptr' assigned to Register 'DR12' ---- ; SOURCE LINE # 51 * error could appear here 000004 9A000000 E ECALL I2CStop? ; SOURCE LINE # 52 000008 9A000000 E ECALL I2CStart? ; SOURCE LINE # 54 00000C 9A000000 E ECALL HwdIOWait? ; SOURCE LINE # 55 000010 74D0 MOV A,#0D0H ; A=R11 000012 9A000000 E ECALL I2CSend? 000016 7006 JNZ ?C0001 I think that you have a bigger problem though. I see that the C library code is also stored in the 'fixed' portion of memory. Unless this remains at the same locations, you are going to have more problems in the future, especially if the libraries change. I believe that your system has a kernel in fixed memory, and the application is loadable to flash. What you need to do is separate the fixed program from the application. In other words, the kernel should compile and link with only the code that will be fixed in memory. The application should compile and link only the code that is in external memory. Functions that are called between the application and kernel are defined in the linker with fixed addresses. When the application is linked, calls or jumps are made to those addresses. Any library functions will be present in the flash memory for the application, and any library functions will be present in the fixed memory for the kernel. In this way, if the tools are changed, you can compile and link the application knowing that the libraries are correct for that version of the compiler. The application needs a fixed startup address that the kernel can jump to after reset. This can also be done by using the linker to fix the address of the main() function. Our product has this architecture, and that is how we handled this. The application compiles and links as one object, and the kernel does likewise. There are only a few addresses that are fixed by the linker between the two, so that function calls can be made.
Tom Thanks for the help and your design comments. I believe that I can locate variables and subroutines where I want them in internal or external memory. I am concerned about the library routines as you pointed out. Is it possible to get the library source and then locate subroutines and data to external memory when the application code may require these utilities? I could let the linker relocate them if this is possible. Note: This system design should not see many changes in the functional side, however the fixed side (251 onboard) will not be allowed to change once burnt into the 251. The functional code changes will be done so as not to intentionally change the onboard code image. Any thoughts on this???