Bootswapping operation is very unstable, even more in release

Hi everyone,

Context of the project

I'm working on a bootloader project based on RL78. I set my memory like this : 

This idea is to jump from application to bootloader when I want to update the application and to jump from bootloader to application when I'm finished with the upload.

Major Issue

I'm able to start bootloader, flash the program, jump to application, jump to bootloader and flash program again. But this is ok like 50% of the time in DEBUG. The first start and flash is always working, the first jump is almost always working and after that it depends.

In release mode, it is even worse. I can start bootloader, flash the program and most of the time I can't even jump to the application

How did I code that ?

I'm based on the renesas FSL library and working on the R5F10DPJ microcontroller. To perform the bootswapping, I'm using this function : 

void Flash_SwapBootCluster()
	fsl_u08 fsl_status;
	UINT32 wait;
	// Open FSL and prepare all functions

	// Invert bootflag to start correct bootloader and close FSL
	fsl_status = FSL_InvertBootFlag();
	while(fsl_status != FSL_OK)
		fsl_status = FSL_InvertBootFlag();

	// Close FSL

	/* Delay */
	wait = (UINT32)0;
	while(wait < (UINT32)10000)

	// Perform swapping of bootcluster
	fsl_status = FSL_SwapBootCluster();
	while(fsl_status != FSL_OK)
		fsl_status = FSL_SwapBootCluster();

I start to be out of idea, am I doing something wrong with this boot swapping ?

Thanks in advance and have a good day !

  • Hello,

    First of all your memory layout is a bit confusing.

    There should be boot cluster 0 (for the one boot program) and boot program 1 (for the other boot program), if you want to use the boot swap mechanism. On top of them there should be the application(s).

    The boot program must exist only inside the memory size of a boot cluster.

    Regarding the boot swap, after calling FSL_InvertBootFlag you should issue a software reset so the boot swap takes place. The new bootloader is active after reset.

  • Hi, thanks for your answer Slight smile

    Concerning my memory organization, I aggre it wasn't very clear. In fact, there is 2 applications : The one handling the bootloading process to update the flash and the other one, the main application. Each of these application have their own boot (interrupt vector, ...)

    Ok so calling the FSL_SwapBootCluster is not necessary since I already inverted boot flag. I just need to perform the reset then. I'll try this thanks !

  • What do you mean by 'added a new cstart file' ? The cstart file is only one. Just add the lines to initialize RAM in the existing cstart file:

    If you pause the program after these lines you should see the RAM filled with 0xAA vaues.

  • What I meant is that IAR is based, by default, on the cstartup.s87 located in installation folder. So I copy paste it to my project and modified it to avoid modifying the default file for other project.

    Here is my cstartup file, for IAR

    I modified those lines since it look the same as you for your startup file (In comment, after 'Adrien -', is the initial line)

            ; Init stack segment for as the generated code may sometimes
            ; access the 4th byte of a return address before it is initialized
            MOVW    HL, #LWRD(0xBF00) ;Adrien - MOVW    HL, #sfb(CSTACK) ;
            MOVW    BC, #LWRD(0x3FE0) ;Adrien - MOVW    BC, #LWRD(sizeof(CSTACK))
            CMP0    C
            INC     B
            MOV     A, #0xCD        ; 0xCD to fool C-SPY's stack limit check
            MOV     [HL], A
            INCW    HL
            DEC     C
            BNZ     loop_s
            DEC     B
            BNZ     loop_s
            MOV     CS, #0

    I tried added your lines in my startup file but I got errors unfortunately. I'm quite a newbie in assembly :/ 

    Sorry for taking a lot of your time with this issue

    EDIT : I also tried another thing, set the RPERDIS flag to 1, to avoid reset link to RAM parity error

    EDIT 2 : After reset, RPERDIS is reset to 0 and a parity error might happen before I set it again so it may be useless in my case then

    EDIT 3 : Alright, RAM Initialization was the answer like you said. It was important to fill with 0xAA while my code was filling with 0xCD. Thanks a lot !

  • Hello,

    That's very good news.

    One doubt about your last comment though. I do not think the value for RAM initialization is important to prevent RAM parity errors.

    My guess is that your RAM was not fully initialized before but after you modified the cstart file as instructed, the RAM is now initialized with a random value (0xAA in this case) and the RAM parity errors are prevented.

    If a reset will occur after a RAM parity error is controlled by RPERDIS bit:

    So if you have this bit to its default value 0 and everything works as expected then no RAM parity errors occur during RAM access.

  • That's strange because everything is working fine since I only modified the 0xCD to 0xAA but I guess maybe something was not taken into account and then the RAM was not correctly initialized

  • So instead of 0xAA in the lines of code, you filled with 0xCD and it didn't work ?

  • Initially it was 0xCD ( I took the file from C:\IAR\IAR_Systems\Embedded_Workbench_7.0\rl78\src\lib ) and I saw that it was filled with CD. But nothing worked. Then I changed the value to 0xAA and it was working

  • My cstartup.s87

    Images of the RAM :

    When reaching main, all 0xAA are linked to the SELFRAM I set in the linker file for the FSL library. Then, another init is writing 0x00 on top of it I guess

  • All values will have the same result.

    Do you say that if you change this line:

    MOV     A, #0xAA


    MOV     A, #0xCD

    results in an error ?

  • I just retest it with the 0xCD and it is still working. So I really don't know what changed and why but the first time it works was just after I changed this value.

    I'll investigate a bit more on what could have change

Reply Children
No Data