Calling code in PSRAM

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User3847
Level 3
Level 3
Dear all,

I am implementing a second-level bootloader and I am having a Bus Fault when calling a function I located in PSRAM.

What I did:

* I made the linker put the bootloader functions in FLASH (LMA) but reference them in PSRAM (VMA), so my functions start @ 0x10000000.
* I made the startup copy from the flash location to the PSRAM. I checked that the bytes are copied succesfully.

When I call a function inside PSRAM (it is a void()(void) function so just a bl) I get a Bus Fault.

Must something else be done to use the PSRAM for code?

Best regards,
0 Likes
2 Replies
User3847
Level 3
Level 3
sblanco wrote:
Dear all,

I am implementing a second-level bootloader and I am having a Bus Fault when calling a function I located in PSRAM.

What I did:

* I made the linker put the bootloader functions in FLASH (LMA) but reference them in PSRAM (VMA), so my functions start @ 0x10000000.
* I made the startup copy from the flash location to the PSRAM. I checked that the bytes are copied succesfully.

When I call a function inside PSRAM (it is a void()(void) function so just a bl) I get a Bus Fault.

Must something else be done to use the PSRAM for code?

Best regards,


Oh, the bytes are copied all right, but it seems the contents are not quite right, so perhaps the linker part is not right.

I do the following for that:

.text : AT(ORIGIN(FLASH_1_uncached))
{
sText = .;
*(.Xmc4500.reset);
*(.Xmc4500.postreset);
*(.XmcStartup);
*(.text)
*(EXCLUDE_FILE (*bootloader.o) .text.*)
*(EXCLUDE_FILE (*bootloader.o) .gnu.linkonce.t.)
....

and then...

.bootloader :
{
*bootloader.o (.text.* .gnu.linkonce.t.*);
} >PSRAM_1 AT>FLASH_1_cached

__boot_start = LOADADDR(.bootloader);
__boot_size = SIZEOF(.bootloader);
__boot_dest = ADDR(.bootloader);

My map file then says:

.bootloader 0x10000000 0x5c8 load address 0x0801c3f0
*bootloader.o(.text.* .gnu.linkonce.t.*)
.text.CheckFirmwareComplete
0x10000000 0x34 Debug/obj/src/bootloader/bootloader.o
0x10000000 CheckFirmwareComplete
.text.CheckNewFirmware
0x10000034 0x10 Debug/obj/src/bootloader/bootloader.o
0x10000034 CheckNewFirmware
.text.NewVersionAvailable
0x10000044 0x50 Debug/obj/src/bootloader/bootloader.o
0x10000044 NewVersionAvailable
.text.EraseFlash
0x10000094 0x150 Debug/obj/src/bootloader/bootloader.o
0x10000094 EraseFlash
.text.VerifyEraseFlash
0x100001e4 0x44 Debug/obj/src/bootloader/bootloader.o
0x100001e4 VerifyEraseFlash
.text.WriteFlash
0x10000228 0x140 Debug/obj/src/bootloader/bootloader.o
0x10000228 WriteFlash
.text.VerifyWriteFlash
0x10000368 0x144 Debug/obj/src/bootloader/bootloader.o
0x10000368 VerifyWriteFlash
.text.FlashFirmware
0x100004ac 0x80 Debug/obj/src/bootloader/bootloader.o
0x100004ac FlashFirmware
.text.bootloader
0x1000052c 0x38 Debug/obj/src/bootloader/bootloader.o
0x1000052c bootloader
*fill* 0x10000564 0x4 00
.text.bootloader.stub
0x10000568 0x60 linker stubs
0x0801c3f0 __boot_start = LOADADDR (.bootloader)
0x000005c8 __boot_size = SIZEOF (.bootloader)
0x10000000 __boot_dest = ADDR (.bootloader)

And the startup file just copies from flash to RAM.

Do you see anything wrong?

Thanks in advance
0 Likes
User3847
Level 3
Level 3
Well, in the end it was just wrong; I had to just keep the flash order flowing...

.bootloader : AT(__exidx_end | 0x04000000)
{
*bootloader.o (.text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
*SPI001*.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
*FLASH002*.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
*spansion*.o (.text .text.* .gnu.linkonce.t.* .rodata .rodata.* .gnu.linkonce.r.*);
} >PSRAM_1

__boot_start = LOADADDR(.bootloader) & 0x0BFFFFFF;
__boot_end = __boot_start + SIZEOF(.bootloader);
__boot_size = SIZEOF(.bootloader);
__boot_dest = ADDR(.bootloader);


/* CONST data section */
.rodata ABSOLUTE(__boot_end): AT(__boot_end | 0x04000000)
{
*(EXCLUDE_FILE (*bootloader.o *SPI001*.o *FLASH002*.o *spansion*.o) .rodata .rodata.*)
*(EXCLUDE_FILE (*bootloader.o *SPI001*.o *FLASH002*.o *spansion*.o) .gnu.linkonce.r*)
} > FLASH_1_cached
0 Likes