AnsweredAssumed Answered

Intermittent problem with USB Host Bootloader starting application on K22

Question asked by Angelo Quattrociocchi on Sep 2, 2015
Latest reply on Jul 11, 2016 by Andrew Darrow

I have a bootloader project that was based on the AN4368 source (USB Host bootloader) running on a custom board using the K22FN1M0, and most of the time this works fine.  On some units however, when the bootloader jumps to the application it appears to freeze.

 

The application is an MQX4.0 project, and presumably since it works most of the time the linker and other settings are OK.  The bootloader never fails to start, as I can see from the message printed by it.  I watch the crystal and it always starts, and continues when it should be jumping to the application.

 

Early in the main application there are some other messages printed, and these never appear when this lock-up occurs.  I'm not sure how to debug the main application (or if that's even possible), so I don't know if the main application is starting at all, or if it fails to jump.  I will try to add some code earlier in the boot up process that I can use to determine if it's actually starting (like toggling some pin).

 

The jumping part of the bootloader is essentially the same as the original code, and includes the following:  (I cleaned it up a bit to simplify this post.)

 

#define IMAGE_ADDR     ((uint_32_ptr)0x10000)

static void Switch_mode()
{
     /* Get PC and SP of application region */
     New_sp  = IMAGE_ADDR[0];
     New_pc  = IMAGE_ADDR[1];

     if ((New_sp != 0xffffffff) && (New_pc != 0xffffffff)) {
          printf("\nUSB Bootloader - Executing Application...\n"); /* Run the application */
          printf("New_sp = %X\n", New_sp);
          printf("New_pc = %X\n", New_pc);

          asm
          {
               ldr   r4,=New_sp
               ldr   sp, [r4]
               ldr   r4,=New_pc
               ldr   r5, [r4]
               blx   r5
          }
     }
}

 

I added the print-outs of the New_sp and New_pc values and this is what the output looks like when starting the application.

 

USB Bootloader - Executing Application...

New_sp = 2000FC00

New_pc = 1AEDD

 

It looks the same whether the main application actually starts or not.  I'm not sure about these values, but I'm a little unclear about how this jump is done anyway so I'm assuming these values are correct.

 

Do you think I should be looking on the bootloader side, or the application code?  Could there be some hardware factor I should investigate?  I saw another forum post that indicated the ARM MSP should be reset to zero, but I don't know if it applies to this situation.  Re: Problem of initialization of MQX after jumping to the start of MQX application ( _boot() )

 

Thanks,

Angelo

 

EDIT: Update...I tried to do some debugging but couldn't figure out how to debug the main application after being jumped to from the bootloader.  I tried to add some I/O changes early but I think it was too early and the program didn't run at all.  But then I just loaded the original application directly in Flash (with no bootloader) and tried power-cycling the unit.  The main application always starts properly, so it appears that the issue is somehow related to the bootloader.

 

EDIT2:  Based on the link I included above, I tried to clear the master stack pointer but it didn't seem to make a difference.  This is how I did it:

asm

{

     ldr     r4,=New_sp

     ldr     sp, [r4]

     ldr     r4,=0x00

     ldr     r5, [r4]

     MSR     MSP, r5

     ldr     r4,=New_pc

     ldr     r5, [r4]

     blx     r5

}

 

I also tried modifying the delay before Switch_mode is called.  Presumably this was added to let the button input settle.  I tried increasing that wondering if the clock or something else needed more time to settle, and even making it wait 10s before jumping doesn't seem to make it more reliable.  In fact it seems that with extra delay (even only ~100ms) it fails more often, but I didn't do a lot of trials to confirm this.  I suspect maybe the clock gating or GPIO initialization code might be leaving it in a bad state.

 

My other thought, going back to the main application code, is that the clock setup is not executing properly.  I know the ARM devices have a lot of clock options, and I wonder if the same code which reliably gets the clock started when running from power-up (without the bootloader), does not work as well when jumped to from the bootloader.  So maybe it does jump but the application gets stuck in the early clock init.  For example there are various places in bsp_cm.c where it waits indefinitely for PLL lock, etc.

Outcomes