I want to compile my project to be PI (it is an RTX app running C code on STM32L1xx). For target options, I check "Make RO Sections PI" in the Linker tab with no scatter file or misc controls. In the C/C++ and Asm tabs, I check "RO PI" and add "--apcs=/fpic" to misc controls.
Upon cleaning/rebuilding the target, I get no compiler warnings or errors, but the linker throws hundreds of warnings and errors for all object files, with these 3 codes: L6412W L6248E L6285E
I've obviously looked up the meaning of these error codes, but I'm not sure what to do about it. I've read infocenter.arm.com/.../index.jsp but I can safely assume I'm not doing this in every object file; I suspect it's something more fundamental to the target options. Even my Startup.s file has these errors and I copied it from STM. Any ideas?
Some examples of warning and error messages are:
.\obj\Project_Pic.axf: Warning: L6412W: Disabling merging for mytask.o(.conststring), unsupported relocation R_ARM_REL32 from mytask.o(.text) .\obj\Project_Pic.axf: Error: L6248E: startup.o(RESET) in PI region 'ER_RO' cannot have address type relocation to Reset_Handler in PI region 'ER_RO'. .\obj\Project_Pic.axf: Error: L6248E: startup.o(RESET) in PI region 'ER_RO' cannot have address type relocation to NMI_Handler in PI region 'ER_RO'. .\obj\Project_Pic.axf: Error: L6248E: startup.o(RESET) in PI region 'ER_RO' cannot have address type relocation to HardFault_Handler in PI region 'ER_RO'. .\obj\Project_Pic.axf: Error: L6248E: params.o(.text) in PI region 'ER_RO' cannot have offset type relocation to m_p_MyParams in ABSOLUTE region 'ER_RW'. .\obj\Project_Pic.axf: Error: L6248E: routing.o(.text) in PI region 'ER_RO' cannot have offset type relocation to m_MyMutex in ABSOLUTE region 'ER_ZI'. .\obj\Project_Pic.axf: Error: L6248E: params.o(.data) in ABSOLUTE region 'ER_RW' cannot have address/offset type relocation to GetMyParam in PI region 'ER_RO'. .\obj\Project_Pic.axf: Error: L6285E: Non-relocatable Load region LR_1 contains R-Type dynamic relocations. First R-Type dynamic relocation found in startup.o(RESET) at offset 0x4.
Addresses in the Vector Table are hard, absolute addresses. To be able to move a Cortex-M3 ROM image, where everything else is address independent, you'd need to carve out an area of RAM, and fix up a copy of the vector table with the correct addresses, and then point the SCB->VTOR at this RAM resident table. The table has address alignment requirements.
I attempt to point VTOR at the RAM table with:
#define VECT_TAB_SRAM #define VECT_TAB_OFFSET 0x0
But I'm not sure how to carve out an area in RAM or fix the vector table in my Startup.s file:
; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size __Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler DCD 0 ; Reserved ..........
You'd change the target memory description for IRAM1 either in the dialog pane, or via a linker script. ie raise the base from 0x20000000 to 0x20000200 (or what it needs), and shrink the size by the same amount. Now you have an area of RAM outside the purview of the linker and compiler.
If you want to make a relocatable app then you really need to consider separating it from a boot loader, and create a branch table at the front of the app to replace the vector table. ie branches not addresses
Then build the application as position independent, if your code permits, and then let the boot loader pick which application to be run, and have it build a RAM based vector table pointing at your branch list for the chosen app, and point SCB->VTOR at this table.
Alright that first part makes sense. My vector table size is 0x124. So in the Target tab of target options, I set IRAM1 start to 0x20000124 and size 0xBEDC (which is 0xC000-0x124); in the Linker tab, I also set R/W base to 0x20000124. I must be missing something though, since it still fails with the same exact linking errors/warnings.
I'm not sure about the second part. It won't work by just keeping the vector table in RAM? It seems like it should be relatively straightforward to set some compiler/linker flags so the RO code is built PI (assuming the C code is compliant).
You've got DCD's for absolute addresses, while the object file can hold this in a "self relative" format internally, it can't be linked to a bin/hex with some load address independent value.
You can't construct a address independent binary using the paradigm you're using, and the way the Cortex-M3 works. The addresses in the vector table need to be absolute addresses.
You'd have to build a table with a different paradigm, using a list of RELATIVE branches
One of your other choices could be to modify the scatter file so that it builds a load region at the bottom of RAM, and puts the vector table in there. The C start up code can then copy that data in, or you can move it manually in main()
But you're still going to need to break this into two pieces so the "App" portion is separate from the "Loader" portion which HAS to manage the requirements of the Cortex-M3 to have a vector table with fixed addresses for the initial stack, and program counter.
May be you want to go look at how things are done with the Cortex-M0, where you can't relocate the vector table. Look at the IAP (In Application Programming) type examples. Look also how ARM7/9 and 68000 part used to deal with the dilemma of booting a ROM and relocating vectors into RAM, and relative branching.
Sounds like a lot of great info, and I really appreciate the suggestions on where to learn more about it (there's so much documentation out there, it's hard to find the right info). Thanks!