I am having a problem getting my RL78 bootloader to correctly jump to and execute the new application. My bootloader is written to parse SREC data and write it to the proper place in memory using the Renesas FSL library. The application that I programming onto the board simply flashes two LEDs and is small enough that I declared the SREC data as a constant in the bootloader so as to eliminate the need for a communication protocol until I got the bootloader itself working. My bootloader can successfully write the new application to the proper place in flash, however the jump to the new application does not work (i.e. the LEDs do not flash as expected and there is in fact no change to the LEDs to indicate anything is happening).
Here is the chip and software tools that I am using: Chip = Renesas RL78 L13 R5F10WMG IAR Embedded Workbench 4.21.1 FSL T01 for IAR(V2.xx) :V2.21 (*)
Figure 1 below shows the declaration for the new application SREC file declared as a constant in the bootloader. Figure 2 shows a memory dump of the flash in my MCU after the self-programming is finished, and the data is at the intended location in flash. With those things in place, I should be able to jump to the new application. I have looked at several of the forum entries on this topic and tried a few different ways to accomplish the jump (none of which worked for me). Note that although I tried the FSL bootswap, I cannot use that method because the final bootloader will be larger than 4K.
The methods that I tried for performing the jump to the application are as follows:
//--------------------------// Method 1//-------------------------- if ((ucResult == FSL_OK) || (ucResult == SREC_LAST_REC)) { DI(); R_TAU0_Channel0_Stop(); R_UART0_Stop(); AppMain(); } where AppMAin is declared as: void (*AppMain)(void)= (void (*)(void))0x00001000;
//--------------------------// Method 2//--------------------------if ((ucResult == FSL_OK) || (ucResult == SREC_LAST_REC)) { DI(); R_TAU0_Channel0_Stop(); R_UART0_Stop(); JumpToApp(0x1000, 0x1004); } where JumpToApp is declared as: void JumpToApp(uint16_t usStackPointer, uint16_t usProgCounter) { asm("MOVW SP, AX"); // set stack pointer = 0x1000
asm("MOVW AX, BC"); asm("BR AX"); // branch to program counter = 0x1004 }
//---------------------------------------------------------------------------// Method 3 (this is the method that I ultimately would not be able to use)//--------------------------------------------------------------------------- if ((ucResult == FSL_OK) || (ucResult == SREC_LAST_REC)) { DI(); R_TAU0_Channel0_Stop(); R_UART0_Stop();
FSL_InvertBootFlag(); FSL_ForceReset(); } Any help would be very appreciated. I feel like I am very close but I can't find that final piece to get it working. Thanks in advance for your help.
Can you step thru the boot-loader code with a debugger to observe transfer of control to the application, and then step thru the application code to toggle the LEDs?
There are several similar threads on this forum, I would suggest reviewing many of them to look for hints.
I stepped through with the debugger using Method 1 above (i.e. by calling AppMain() at address 0x00001000). The code vectors to 0x00001000 and then begins to step through the vector table for AppMain and gets hung up because the micro thinks it should be executing sequential instructions rather than performing the reset procedure that I actually want.
How should I be performing this jump to main in a way that uses the vector table for the new application? Should I be vectoring to the address of the main function in the new application?
Hi Bill,
What went wrong with method 2 ? Did the program jump to 0x1000 ?
Regards
By default the address of application image starts at 0x2000.
Have you changed the default address ?
Based on various feedback, I reorganized my memory map as follows:
So given the new memory layout outlined above, I believe that when I swap boot sectors using FSL_InvertBootFlag() followed by FSL_ForceReset(), the start-up code for the application that resides in BOOT1 should be called and properly reset into my new application that resides at address 0x2000. However I found that the bot flag is not being swapped as commanded. When I run:
fsl_u08 fsl_status;
FSL_GetBootFlag(&fsl_status); /* Invert boot flag to prepare for boot swap */ fsl_status = FSL_InvertBootFlag();
while (fsl_status == FSL_BUSY) fsl_status = FSL_StatusCheck();
FSL_GetBootFlag(&fsl_status);
fsl_status == 0 after the second call to FSL_GetBootFlag(). I am using the self programming library as shown in the RL78 One Image Bootloader Example code including initialization and the memory writes that use the library are working well. Any thoughts on why how to fix this problem with the boot flag?
Can you find what value does ' FSL_InvertBootFlag' return ?
www.renesas.com/.../rl78-family-flash-self-programming-library-type01-users-manual-rev105
After some twists and turns I was able to get the bootloader to work. The solution to the boot flag problem that I reported above was that the stack size needed to be increased. Stack overflow was causing the software to go off into invalid memory space.
At the start of my development, I was hoping to implement a bootloader that would update the application in memory and then simply jump to the new application and begin executing. In the end I realized that I would not be able to use that architecture because I needed one set of interrupt vectors for my bootloader, and a different vector table for my application. This requires the boot swap functionality provided in the RL78 because the bootloader vector table needed to be replaced by the application’s vector table. If I hadn’t needed interrupts in the bootloader, I might have been able to use a single interrupt vector table (i.e. the application’s vector table) and simply jump to the new application after it was updated as I originally wanted to do.
I also knew that my bootloader was going to be larger than the boot cluster. To solve this problem I implemented a linker script that allows the bootloader code to be split between the boot cluster and program flash memory. This combined with the boot swap functionality made the bootloader work.
Thanks to everyone for your help!
Hi, finally you get the way, I have the same solution as yours, but right now,I have a question
Bill L. said:bootloader vector table needed to be replaced by the application’s vector table
What does that mean ? I have a problem when trying to update bootloader from application,
Code flash:
Bootloader is (boot cluster 0) 0x0000-0x1ffff, 0x4000-0xAFFF
Application:(boot cluster 1) 0x2000-0x3Ffff, other code flash.
I can update application from bootloader, but the application was stacked to write the data to boot cluster 0.
Is anyone know what happened?
Peter.Du said:Bill L. said:bootloader vector table needed to be replaced by the application’s vector table What does that mean ? I have a problem when trying to update bootloader from application,
The vector table replacement happens automatically when the boot clusters are swapped. If you modify the application linker script to map the .reset, .intvec, etc. into boot cluster 1 (addresses 0x1000 - 0x1FFF), then the bootloader's vector table is replaced with the application vector table when when boot cluster 0 and boot cluster 1 are swapped.
Did you have trouble using the FSL_ForceReset function from the FSL library? In my case, it's showing "No source available."
FSL_ForceReset
I didn't use FSL_ForceReset. I inverted the boot flag and executed a soft reset by writing an invalid value to the watchdog timer:
unsigned char BootSwapReset(void) { fsl_u08 fsl_status; // Invert boot flag to prepare for boot swap fsl_status = FSL_InvertBootFlag(); if (fsl_status != FSL_OK) return fsl_status; // This causes a processor reset WDTE = 0xFFU; // Should never occur, this silences compiler return fsl_status;}
How did the sector viewer of the application turn out? When I perform the boot swap, the application doesn't run. It's as if it indexed the vector table incorrectly.
hello sir, wondering if you could help me with a similar topic.
Hello Quang Le
There's a discussion regarding the bootswap function and running two individual applications inside an RL78 MCU, which you might find useful. Take a look at this link:
community.renesas.com/.../2-project-codes-to-be-placed-in-the-same-rl78g23
Feel free to ask any follow-up questions if needed.
Best regards