Hey All,
I'm working on a RAM-based bootloader for the RA2A1. I have written stub code to call at 0x20004000 in RAM for testing. This test code is copied to RAM and then called. The code simply takes an int parameter, increments it, and returns. Everything works fine provided that I either single step into or break at the entry point at 0x20004000.
Actual (and correct machine code 10 bytes in RAM):
push {lr} <-- If I do not break here the CPU crashes
mov r1, #1
add r0, r0, r1
pop {pc}
The crash goes to the default handler
void Default_Handler (void)
{
/** A error has occurred. The user will need to investigate the cause. Common problems are stack corruption
* or use of an invalid pointer. Use the Fault Status window in e2 studio or manually check the fault status
* registers for more information.
*/
BSP_CFG_HANDLE_UNRECOVERABLE_ERROR(0);
}
With instructions to look at the "Fault Status Window". So after some trouble finding this window, it is greyed out!!
What is up with that?
Here is the stub calling code:
static int jump_to_address (uint32_t address, int arg) {
int returnValue;
// Function pointer to the address
int (*func_ptr)(int) = (int (*)(int))address;
returnValue = func_ptr(arg);
return returnValue;
My guess is that execution from RAM is limited by CPU settings. And single stepping/breaking can override
that limitation somehow. If I move the breakpoint to the next instruction at 0x20004002 it also fails.
I MUST break or step into 0x20004000 for it to work correctly.
Does anyone know what is wrong? Thanks in advance!
Hello Dan,
Thanks for reaching out Renesas Community!
If I have understood correctly, you try to execute the code from RAM and not from the code flash.
Your problem seems to be how you try to set the Program Counter and the Initial Stack pointer registers.
Please check the thread below, I believe it matches with your case:
https://community.renesas.com/mcu-mpu/ra/f/forum/29018/running-application-from-ram-on-ra4w1-in-e2studio
Also, check the FAQ below, in order to understang the whole remap execution process:
https://en-support.renesas.com/knowledgeBase/21094312
Hope it helps!
Regards,
AL_Renesas
Hello AL_Renesas,
Thank you for your reply, but it seems you have misunderstood my problem. I have figured out how to call code in RAM from my ROM application. How to set up the .ld file to get the RAM code where I want it to be copied etc. E2 studio DOES NOT load the RAM code, my App copies it there.
Here is the copy code:
extern uint8_t __boot_stub_start, __boot_stub_end; //from the loader script
/******************************************************************************
* Function Name: copyStubToBootRam
* Description : Copies a small test function from ROM to BOOT RAM.
* Arguments : none
* Return Value : none
*
* Notes:
* *p_rom_section = pointer to ROM to be copied from
* *p_ram_section = pointer location in RAM to copy the code to
* size = number of bytes to be copied
******************************************************************************/
void copyStubToBootRam(void)
uint8_t *p_rom_section = (uint8_t *)(&__boot_stub_start);
uint8_t *p_ram_section = (uint8_t *)(&__boot_start);
uint32_t size = (uint32_t)(&__boot_stub_end - &__boot_stub_start);
for (uint32_t i = 0; i < size; i++) {
p_ram_section[i] = p_rom_section[i];
My problem is when I call the RAM code at address 0x20004000 from my application, it immediately causes a general fault unless I put a breakpoint on the first instruction in the RAM code.
RAM CODE is at address 0x20004000:
0x20004000 push {lr} <-- If I do not break here, the CPU goes to the general fault handler
It does not matter what the actual 1st instruction is. It will do the same thing even with a NOP as the first instruction. But with a breakpoint, followed by a run, it performs as expected. Why do I need a breakpoint?
Hello,
Can you share your project with us, in order to check it in detail?
Regards
Your address should be 0x20004001 for thumb instruction.
Try
jump_to_address( 0x20004001, any_value);
Yes, that fixes the problem, thank you very much. It seems the PC still gets address 0x20004000, but with a call set to 0x20004001 everything works. Odd addresses just signal thumb mode but are otherwise ignored? I need to learn more about ARM.
Can you tell me why the "Fault Status" window in E2 studio does not work. All the special registers such as HFSR are greyed out. Is this a paid-for add-on?