I am trying to write the PIC. I wrote 2 programs in keil. 1 program is residing in the ROM (non PIC). And the second prgram (with-PI) I want to send over UART. I am trying to wrote the program and I also enabled /ropi and /rwpi options, and also tried oputputting the symbol definition file with --symdefs. Somehow I am not able to compile the PIC project. from my inderstanding "main()" is not required and from the startup file I am directly jumping to my_function(). The errors I am getting are pasted below:
toloadAPP.axf: Error: L6241E: toloadapp_startup.o(.text) cannot use the address of 'RWPI (R9 used as SB)' function add2num as the image contains 'USESV6 (R9 used as V6)' functions. toloadAPP.axf: Error: L6248E: toloadapp_startup.o(.text) in PI region 'ER_RO' cannot have address type relocation to add2num in PI region 'ER_RO'. toloadAPP.axf: Error: L6285E: Non-relocatable Load region LR_1 contains R-Type dynamic relocations. First R-Type dynamic relocation found in toloadapp_startup.o(.text) at offset 0xc.
The assembly file is as shown below:
AREA RESET, DATA, READONLY DCD Reset_Handler ; Reset Handler AREA |.text|, CODE, READONLY Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT add2num LDR R0, =add2num BX R0 ENDP END
The C file is as below:
int add2num(int a, int b) { return (a + b); }
Anybody can point to the documentation with which I can proceed further?
Thanks
Do you mean "PIC" as in the microcontroller family from Microchip,
or "PIC" as an abbreviation of "Position-Independent Code" ?
I mean Position Independant Code
I don't know of a good resource to point you for writing /ropi (aka PIC) asm code. "It's complicated", but I'll try to help below. It's especially complicated if your PI code has any writeable global data, so I'm going to pretend it doesn't.
> from my [u]nderstanding "main()" is not required
This sortof implies that no startup/library initialization will be done. That can work if there is no writeable data.
Let's look at the error messages:
toloadAPP.axf: Error: L6241E: toloadapp_startup.o(.text) cannot use the address of 'RWPI (R9 used as SB)' function add2num as the image contains 'USESV6 (R9 used as V6)' functions.
This says (in its own special way) that add2num is in a object file built with /rwpi and toloadapp_startup.o has been built without /rwpi. I suggest having no writable data and removing /rwpi.
toloadAPP.axf: Error: L6248E: toloadapp_startup.o(.text) in PI region 'ER_RO' cannot have address type relocation to add2num in PI region 'ER_RO'.
This says that you built toloadapp_startup.o using /ropi but you did a non-PI thing in the .s file. When you tell the compiler /ropi it is an *order* for it to produce PI output (or an error/warning if it can't). When you tell the assembler /ropi it is a *promise* that your .s file is PI and you've broken the promise. The assembler will not change your code to be PI -- you have to. (See more below)
toloadAPP.axf: Error: L6285E: Non-relocatable Load region LR_1 contains R-Type dynamic relocations. First R-Type dynamic relocation found in toloadapp_startup.o(.text) at offset 0xc.
This is a cascade problem from the previous.
AREA RESET, DATA, READONLY DCD Reset_Handler ; Reset Handler
This is writable data and it's unused, so remove it.
LDR R0, =add2num BX R0
This is equivalent to
LDR R0, lbl BX R0 lbl DCD add2num ; this is non-PI
You need to change this to something like:
LDR R0, Entry_offset ; this is PI ADR R1, Entry_offset ; this is PI ADD R0, R0, R1 BX R0 Entry_offset DCD add2num - . ; this is PI
(I haven't tested this and in ARM state (and maybe Thumb-2) it's possible to do the same thing with fewer instructions.)
If you need to use writable global data (or you use library functions that use writable global data) then you'll have to use /rwpi and things are more complicated still. Your loader will have to allocate/initialize the globals and point R9 at the appropriate global at the appropriate time. About this time, you might start thinking about using some existing OS that has already implemented shared libraries. (Linux is one, but I suspect there are others that are lighter weight.)
I'm not sure how you are trying to use the symdefs file, but you don't want the IDE to treat it as a source file; it's more like an object file.
When you use a symdefs file as input to the linker, the values in the symdefs file will be taken (I guess) as absolute addresses so I don't think the symdefs created by the /ropi link are going to be (directly) useful.
Hello Scott,
Thanks for your help.
We have modifed the code as you suggest and now we are able to generate *.sym file but when we try to link it to non-position independent (NonPI) code, the compiler treats *.sym file as assembly file and tries to assemble it and fails with error code
Build target 'mainAPP' compiling mainAPP.c... assembling toloadAPP.sym... ..\toloadAPP\toloadAPP.sym(1): error: A1158E: Illegal line start, should be blank ..\toloadAPP\toloadAPP.sym(2): error: A1163E: Unknown opcode T , expecting opcode or Macro ..\toloadAPP\toloadAPP.sym(3): error: A1163E: Unknown opcode T , expecting opcode or Macro ..\toloadAPP\toloadAPP.sym(4): warning: A1313W: Missing END directive at end of file
Please note that we also tried to modify the "default file extention" option but it still gives the same error.
Code for your ref.
IMPORT add2num AREA RESET, CODE, READONLY Reset_Handler PROC EXPORT Reset_Handler [WEAK] LDR R0, Entry_offset ; this is PI ADR R1, Entry_offset ; this is PI ADD R0, R0, R1 BX R0 Entry_offset DCD add2num - . ; this is PI ENDP END
C source code (Position Independent code)
I hope my understanding of adding *.sym file in files list is correct. I didn't find any other ways to include the *.sym file in the project.
Before getting too bogged down, are you sure that you actually need position-independent code at all...?
"Before getting too bogged down, are you sure that you actually need position-independent code at all...?"
That is, of course, a very good question.
The majority of users who implement boot loaders and field updating (potentially OTA - over the air) firmware updates do manage well without having position-independent code. Position-independence is most useful when playing with dynamically linked plugin modules (on "real" operating systems these modules are normally not position-independent but contains a fixup table where the loader have to patch the loaded module) but that is seldom needed for embedded devices.
Having replaceable, dynamically linked, modules in an embedded device normally makes it too hard to test the software before shipping - each version of each plugin module adds multiplicatively to the total number of software combinations that needs to be tested.
Hi.
In an attempt to design a fault-proof software update mechanism to be used "in-the-field" by end customers, my plan was to use multiple application flash "partitions". When updating to a newer software release the oldest would simply be overwritten. The new one should only be activated after it had been verified that it was written successfully to flash. If this was not the case there should be a mechanism to fall back to the previous version.
I assumed that I would require to generate position independent code. Is there another way to acheive what I describe above?
And what is the common practice? Having a boot loader that can manage ONE instance of the "application" in flash?
Thanks, Jonas
To Jonas Romfelt:
Maybe see these.
http://www.keil.com/forum/13583/ => search "Per Westermark", "1-Dec-2008 17:18 GMT" "But some basic methods to implement a boot loader are:" http://www.keil.com/forum/15092/ http://www.keil.com/forum/18723/
Thank you John for providing relevant links, very much appreciated! And thanks Per Westermark for the detailed forum posts.
After reviewing my requirements once more I think that using a second temporary storage area while downloading is what I need, hence position independent code is out of scope for this time.
Cheers, Jonas