Bootloader to Application

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Bootloader to Application

1,393 Views
JHinkle
Senior Contributor I

How/What is the best way to pass data from the bootloader to the application on a K64?

In the bootloader, I bring the clock up to speed (PLL).  I've read someplace that you don't want to have the application go back back thru the clock setting process as it might hang.  

Can anyone verify the clock concern?

I'm getting mixed speed results in the application.  Sometimes it at speed and other times - it runs slow.  I can't get more info since the code is in protected mode at this point and I can't connect a debugger.

I attempted to pass a flag from the bootloader to the application which tells the application the clock is already up to speed so bypass the setting process.

I read somewhere that the registers of the RTC were a good place to pass data.  In the bootloader, I engage the RTC clock and then set a value in RTC_TSR.  When I get into the application, prior to performing the clock function, I check but they are always zero, not the value I place it it.

Any other ideas on where to squirrel a few bytes of data during the jump?

One last question regarding the jump.

I have the ENET operational in the bootloader.  Prior to the jump, I turn off the ENET, turn off its' clock.  My issue is, the ENET does not always come back and work properly in the applicattion.

What am I missing to enable the ENET to properly work after the jump?

Thanks.

Joe

0 Kudos
Reply
3 Replies

1,143 Views
JHinkle
Senior Contributor I

Thanks Mark:

I tried the Flash Acceleration Ram for passing data but that doesn't work either.

I concluded as he have, to reserve some memory that is not initialized on reset and not used by the application.

I did a check and dirty fix -- I added a compiler directive to place a return a the start of the clock set-up function if I'm in release mode -- which I only use in association with the bootloader.

Thanks for the clock comment.  I'm using the standard SystemInit that NXP makes available via their CMSIS for K64.  I had associated my ENET issue with potential clock issue since I thought that was the only variable that changed when I went from freestanding debug to bootload release mode.  I found THAT was not the only variable -- my issue is explained in the next paragraph.

My issue with the ENET not firing up .....  My bootloader acquires a MAC during the manufacturing process and places it into flash.  The application then goes to the flash location to use it.  I had the location wrong when I made the conversion to bootloader mode vs debug mode.  Funny thing -- bad MACs don't get DHCP replies -- they just get ignored.

Can you explain your "PowerDown"?

I attempted to turn the hardware specific clock off ... example below.

 SIM_SCGC6 &= ~SIM_SCGC6_SPI0_MASK; //Turn off clock to SPI 0 module

That code would generate a HardwareFault.  I haven't looked into it closer since it did not appear to bother my jump to leave the clock engaged for the SPI.

Thanks.

Joe

0 Kudos
Reply

1,143 Views
mjbcswitzerland
Specialist V

Joe

>>Funny thing -- bad MACs don't get DHCP replies -- they just get ignored.
Some DHCP servers won't accept a MAC address of 00-00-00-00-00-00 (others do). It is probable that if the MAC address is a multicast address (bit 24 set to '1') it will generally be ignored.

>>Can you explain your "PowerDown"?
#define POWER_DOWN(reg, module) SIM_SCGC##reg &= ~(module)

SIM_SCGC6 &= ~SIM_SCGC6_SPI0_MASK;
is simply written as POWER_DOWN(6, SIM_SCGC6_SPI0_MASK) for a certain degree of portability (and more obvious to what it is doing).

SIM_SCGC6 access won't cause a hard fault. It would however cause any subsequent accesses to SPI0 to hard fault though, which is more likely to be the issue.

Regards

Mark

0 Kudos
Reply

1,143 Views
mjbcswitzerland
Specialist V

Joe

Clock concern:
- I never had problems with the application re-configuring the clock after the boot loader had done it before; I tested on about 60 different KE, KEA, KL, K, KV, KW parts.
However it probably depends on the application initialisation code used since I have heard that MQX users sometimes have problems with the clock configuration hanging. This means that it "shouldn't" be a problem, or is certainly curable.
I know that there can be some watchdog issues when the processor is running quickly at the jump to the application since Arduino Teensy code will fail unless its watchdog code is removed (it takes too many clock cycles to perform the disable).

Flag passing:
- The uTasker project sets the initial stack pointer (in boot loader and application) to be several long words below the end of SRAM, meaning that these locations are never used by general code. They are used as a mail-box for passing information between application and/or boot loader (eg. application can post a command to tell the boot loader to do something after a reset), or to maintain a counter of the number of soft resets since a power up, etc. A flag can be located in such memory to inform the application to skip initialisation if needed, however it is probably also just as easy to check some clock settings to identify whether it has already been done or not. [Exceptions may be when very low power modes are used where parts of SRAM are powered down, and so data is not retained; otherwise SRAM content is retained across soft resets]

RTC registers:
- These should be maintained across warm resets but maybe you haven't set up the RTC enough to allow this to happen (?)

Ethernet:
- I have used the uTasker Ethernet loader and applications using Ethernet for several years, also on K64s, without any problems. This is the sequence (suitable for K64) used before the jump as reference (when USB hasn't been used, otherwise it is also best to shut down the USB regulator etc.):

SYSTICK_CSR = 0;
POWER_DOWN(4, (SIM_SCGC4_UART0 | SIM_SCGC4_UART1 | SIM_SCGC4_UART2 | SIM_SCGC4_UART3));
POWER_DOWN(1, (SIM_SCGC1_UART4 | SIM_SCGC1_UART5));
POWER_DOWN(2, SIM_SCGC2_ENET);
POWER_DOWN(3, (SIM_SCGC3_SDHC));
IRQ0_31_CER  = 0xffffffff;
IRQ32_63_CER = 0xffffffff;
IRQ64_95_CER = 0xffffffff;
IRQ0_31_CPR  = 0xffffffff;
IRQ32_63_CPR = 0xffffffff;
IRQ64_95_CPR = 0xffffffff;
(it just powers down various peripherals and ensures all interrupts are masked so that there can't be any pending interrupts when the peripherals are re-initialised by the application drivers).

Regards

Mark
Kinetis for professionals: http://www.utasker.com/kinetis.html

0 Kudos
Reply