How to call optiboot_x from application

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everyone,

up to now i used the ATTiny85 with the AVRootLoader for my small projects.

Now I test the ATTiny1614 on a breadboard and do my first tests with the optiboot_x as bootloader.
I'm working with Atmeld Studio 7 and I want to adapt the optiboot_x for my needs, my first tests are already successful.

The bootend fuse is set to 8 (x 256 Byte) so I still have space for adjustments.

Now I try to call the bootloader from my application, which unfortunately does not work.

 

In the Project Properties of my application the Linker / Memory Settings / FLASH segmaent is set to .text=0x0400

 

In the application i defined:

 

    typedef void (*call_optiboot_t)(void);
    const call_optiboot_t call_optiboot = (call_optiboot_t)(0x0000);

 

and want to call optiboot_x after som LED flashes
    ....
    call_optiboot();
    ....

 

Disassembly
            call_optiboot();
00000471  LDI R30,0x00        Load immediate
00000472  LDI R31,0x00        Load immediate
00000473  ICALL         Indirect call to (Z)

 

But the bootlaoder isn't called, my Application stil runs and flashes the LED. Any idea what i'm doing wrong?

 

Best regards
Juergen

 

This topic has a solution.
Last Edited: Sun. Nov 22, 2020 - 06:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You set the fn ptr to 0 so why are you surprised if you end up with an ICALL to 0.

 

(0 is not the address of any function in a bootloader) 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You set the fn ptr to 0 so why are you surprised if you end up with an ICALL to 0.

 

(0 is not the address of any function in a bootloader) 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

I do not understand why the main application code would be calling the bootloader.  On reset, the bootloader configures the AVR USART and checks to see if any data is arriving within a tiny time period.  If data arrives into the USART before the end of this time period, then the AVR's Store_Program_Memory framework gets activated, and a new program is written into the flash.  This implies that the main application program that is currently in the flash (at power up) is going to be overwritten.  So I can't think of any reason why the main ap would call the bootloader.

 

It appears that your code is loading  0x0000 into the indirect-reference register (register Z; r30:r31) and  is beginning to execute code there.  At that location is a JMP instruction to the code that is executed when the AVR is powered on and reset-stabled.  It is jumping to the main application's configuration/reset entry point instead of the bootloader's entry point.    It is likely that your AVR has a fuse setting that sends the code execution entry point to the bootloader's starting address when the device is powered-on or reset.  It is unlikely that the this fuse setting will be the factory default.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi clawson, hi Simonetta,

 

my device must start immediately after a poweron reset. The application has no time to spend another second in the bootloader before starting and therefore has to call the bootloader from my application  if necessary, e.g. by pressing a button that my application detects and then starts the bootloader.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You need to get a handle on when your bootloader will jump to the app and when it stays in the bootloader. If you are calling the bootloader when conditions are not met to remain in the bootloader, then you will end up back in the app.

 

Here is an example which stays in the bootloader IF there are no flags set AND app appears valid, AND a bootloader pin not pressed. Which means to call the bootloader from the app- clear the reset flags and call the bootloader as before. If something goes wrong where the app is screwed up, pull the bootloader pin low and power on. In any case if the first byte in the app space is erased, then stay in the bootloader.

 

                static inline void
    entryCheck  ()
                {

                #define BLPIN   &PORTA,2 // bootloader pin, low = stay in bootloader after a reset

 

                // get byte address of app fron fuses
                u16 appAddr = FUSE.BOOTEND*256;

 

                // app first byte ok? (read from memory mapped flash)
                bool appOk = *(u8*)(MAPPED_PROGMEM_START|appAddr) != 0xFF;

 

                // check boot pin, if pressed (off/low) then user wants bootloader
                pinPullup( BLPIN ); //or similar pin code
                bool noBl = pinIsOn( BLPIN ); //pinIsOn=high=not pressed=true -> noBl

 

                // if any flag + BLPIN not pressed + app appears valid,
                // go to app (need word address to call)
                if( RSTCTRL.RSTFR && noBl && appOk ) ((void(*)())(appAddr/2))();

 

                // no flags, app not valid or BLPIN pressed, so return (run bootloader)

                }

 

 

                int
    main        ()
                { 
                  
                entryCheck();

                // if we are here, bootloader is wanted

                while(1){
                    //bootloader
                }

                }

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

(0 is not the address of any function in a bootloader) 

On mega-0 and xTiny, 0 is the correct "start of bootloader" address.

 

Are you SURE you're not calling the bootloader?  Depending on how the reset cause flags are set, the bootloader COULD be immediately re-start your application.

Note that AFAIK, the xTiny chips always start at 0x0; how are you currently bypassing the bootloader to start your application immediately?

 

Make sure you have a recent version of optiboot_x; there were fixes to the DO_NVMCTRL (ability to get the bootloader to manipulate nvm on behalf of the app.  You're not using that yet, but...)

 

The xTiny chips also have a SW Reset capability.  It was my original intent that that would be interpreted by Optiboot_x to be an explicit "run the bootloader" command.  This is currently not implemented, though (I'm waiting for user feedback, and there hasn't been much.)  Likewise, the "FANCY_RESET_LOGIC" code is not turned on.

 

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:

.....  Depending on how the reset cause flags are set, the bootloader COULD be immediately re-start your application.

 

... that was the cause of my problem.After clearing the RSTFL and triggering a SWR in my application it jumps back to the bootloader.

RSTCTRL.RSTFR = RSTCTRL.RSTFR;
_PROTECTED_WRITE(RSTCTRL.SWRR, RSTCTRL_SWRE_bm );

Now my bootloader starts the application directly after POR and the application can call the bootloader if it should.

 

Thanks westfw