3
\$\begingroup\$

Because I need to maintain some GPIO output states when transitioning from the application to bootloader, I'm jumping back into the bootloader instead of using a software reset to get there (which results in the GPIO tri-stating for ~200ms).

Before I make the jump, I disable interrupts and clear interrupt flags. After the jump, the bootloader starts working through its initialization, but once it gets to INTEnableSystemMultiVectoredInt(), the MCU resets...

I tried overridng _DefaultInterrupt to catch an interrupt that might have been left on by the application for some reason, but this doesn't seem to be working. The MCU just resets and I'm left scratching my head.

Any ideas to what could be causing this? I'm essentially mimicking the behavior of jumping from the bootloader to the application (which works) and so I don't know why it's not working the other way around. Anyone ever able to jump from a PIC32 app to the bootloader without a software reset?

\$\endgroup\$
3
  • \$\begingroup\$ When you "disable interrupts" do you just do a single global interrupt disable, or do you disable each and every individual interrupt which may have been enabled? You can see where I'm going with this I'm sure ... \$\endgroup\$ – brhans Apr 25 '18 at 15:24
  • \$\begingroup\$ @brhans, I'm doing both right now. I do a global disable, then individual disables, and clear all flags \$\endgroup\$ – bt2 Apr 25 '18 at 15:25
  • \$\begingroup\$ Just a guess, but how about in your bootloader, immediately before the INTEnableSystemMultiVectoredInt() call, you do the opposite and set it to single-vector mode ... ? \$\endgroup\$ – brhans Apr 25 '18 at 17:45
1
\$\begingroup\$

Maybe you want to re-think your application some. Using the boot loader should be a seldom needed activity that can be relegated to non-standard system behavior. As such there should be minimal, if any need at all, to maintain GPIO states through a software reset/restart.

I can think of no instances where your application should not be able to work in boot loader mode without depending upon special states of GPIOs setup in the application portion of the code. I say this because the boot loader still has to work in cases where it starts with no application present or in cases where there was an interruption of the application programming process and the application is invalid.

If you have partitioned your system design where some GPIO states are setup in the boot loader and then you try to depend upon those states in the application then I think you have architected things incorrectly and should take a careful look at isolating your boot loader logic from the application logic to the greatest extent possible.

If there is indeed some critical state that does need to be maintained then I believe that is best handled in an external I2C GPIO expander that is decoupled from the processor transitions into and out of the boot loader mode.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the words of wisdom. This functionality isn't critical, but would drastically simplify the process for someone in the field. Can't change the hardware at this point. \$\endgroup\$ – bt2 Apr 25 '18 at 16:08
0
\$\begingroup\$

This seems like a dumb mistake in retrospect, but I was jumping to the bootloader's main function. I needed to jump to the reset entry address, so that some compiler generated startup code could run and, among other things, setup the interrupt vector table to the bootloader's ISRs before entering the bootloader's main function.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.