I am using MBD9F126(ARM Cortex R4) micro-controller. In that I am flashing code into ROM and then I am executing the code from RAM after RAM copy. I am using the Green hills compiler. Before the RAM copy I am executing basic board Initialization code.
LDR r12, ADDRESS_START_PREINIT
BLX r12
ADDRESS_START_PREINIT:DCD Start_PreInit
Start_PreInit is board initialization function. IF I am giving like this after BLX it'll branch to RAM location. As RAM copy is not done yet so it goes to unknown area.
Instead of this If I am writing
bl Start_PreInit
Its working properly that is going to ROM location of code. I don't why compiler has such a behavior?
And also
ADDRESS_START_PREINIT:DCD Start_PreInit . Is it done during linking??
The bl Start_PreInit
instruction works because the branch target is encoded in the instruction opcode as an offset relative to the current PC
(r15
). Since r15
is pointing to ROM, the target is another ROM address.
The blx r12
instruction branches to the absolute address that was loaded into the r12
register.
When you load the contents of ADDRESS_START_PREINIT
into a register, what you're getting is the absolute address that the linker calculated for the Start_PreInit
address. Apparently the linker has fixed that to the RAM absolute address.
You might be able to fix the problem with a linker configuration or by performing some transformation on r12
when it's loaded with the RAM address (something like (r12 - RAM_START) + ROM_START
) before branching. Or use the pc-relative encoding instead of the register-absolute encoding for the branch instruction if the target address is in range.