Can't boot TWR-K60N512 standalone...

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

Can't boot TWR-K60N512 standalone...

Jump to solution
1,270 Views
EdSutter
Senior Contributor II

I've been building a small app on a TWR-K60N512 (includes the serial card) for several days using a Segger JLink programmer connected to the 20-pin debug header.  This has been working just fine.  Now I tried removing the programmer to allow the board to run standalone and it doesn't boot.  I'm not using the JLINK for power (J13/USB does that); so I'm confused.

With JLINK attached, I can power cycle the board and then just run a JLINK script (see below) to restart it and that works fine; so that tells me that the boot flash is properly programmed (doesn't it?).

I noticed that with the JLINK attached, the "RESET" button on the TWR-K60N512 also just locks up the board (I assume it goes to the same "space" as a powerup).  Any ideas what I might be doing wrong?

Thanks

JLINK reset script:

device=MK60DN512xxx10

speed auto

r

h

go

exit

Labels (1)
0 Kudos
1 Solution
641 Views
mjbcswitzerland
Specialist V

Ed

I loaded your code to my TWR board and I am 99% sure it is due to the watchdog not being configured early enough.

Your code starts at 0x0439 (the first instruction executed) and the very first thing that it does is initialise variables. In this case it has 0x970 variables to be initialised (this is a loop copying const values from Flash at 0xd6e8 to the RAM area 0x1fff0410..0x1fff0d80 [initialised variables]). In fact it copies always long words starting at the end of the area and working backwards.

If a breakpoint is set "after" this loop [address 0x44a]  it will never be reached - there is a reset before it gets that far.

If a memory fill is performed in the RAM area before starting it is seen that the loop manages to copy 32 long words before the reset takes place since the FLASH values are seen to have been written there).

When working with the debugger the results can be a bit different - by setting a breakpoint in the loop itself it was in fact possible to run to the break point in each loop cycle and it managed many loops without the reset taking place.

I didn't see any code that configures the watchog (there is a routine called monWatchDog but looks to not be doing any initialisation). Therefore I couldn't try jumping to code that disables the watchdog and then jumping back to the initialisation to see whether the code then actually ran successfully. Since the requirements for unlocking and disabling the watchdog are very critical it is not posssible to do it manually.

Using code that initialises variables before configuring the watchdog may work if there are only a few variables to be initialsied but when the operation exceeds the 256 allowed instructions it would then fail (eg. when a few more variables are added).

I can't explain why the debugger allows the code to operate but, as stated above, I believe the only way to do this is to put the watchog initisation "before" any variable initialisation since it is "normal" (from experience and written references) that if the 256 instructions are used up the watchdog will fire and so the code can't operate.

Regards

Mark

View solution in original post

0 Kudos
8 Replies
641 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

Hello Ed:

You do not mention the IDE/toolchain, but just in case you use CodeWarrior we have seen this problem before, check the next thread:

Re: MK10DX256VLK7 doesn't run standalone, just when debugging. Verified it's running from FLASH, not...


Regards!,
Jorge Gonzalez

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
641 Views
EdSutter
Senior Contributor II

Jorge,

Not using any IDE; just gcc and Segger JLINK to burn the boot flash.

No semihosting involved here, my printf is directed to the serial port that is on

the TWR-SER card.  I just use the USB port for power.

Ed

0 Kudos
641 Views
mjbcswitzerland
Specialist V

Ed

Please post/attach your binary and MAP file.

I would be interested in checking what the Kinetis is doing in this case.

Regards

Mark

0 Kudos
641 Views
EdSutter
Senior Contributor II

Mark,

Ok, here they are...

I included the .elf file as well.

Ed

0 Kudos
642 Views
mjbcswitzerland
Specialist V

Ed

I loaded your code to my TWR board and I am 99% sure it is due to the watchdog not being configured early enough.

Your code starts at 0x0439 (the first instruction executed) and the very first thing that it does is initialise variables. In this case it has 0x970 variables to be initialised (this is a loop copying const values from Flash at 0xd6e8 to the RAM area 0x1fff0410..0x1fff0d80 [initialised variables]). In fact it copies always long words starting at the end of the area and working backwards.

If a breakpoint is set "after" this loop [address 0x44a]  it will never be reached - there is a reset before it gets that far.

If a memory fill is performed in the RAM area before starting it is seen that the loop manages to copy 32 long words before the reset takes place since the FLASH values are seen to have been written there).

When working with the debugger the results can be a bit different - by setting a breakpoint in the loop itself it was in fact possible to run to the break point in each loop cycle and it managed many loops without the reset taking place.

I didn't see any code that configures the watchog (there is a routine called monWatchDog but looks to not be doing any initialisation). Therefore I couldn't try jumping to code that disables the watchdog and then jumping back to the initialisation to see whether the code then actually ran successfully. Since the requirements for unlocking and disabling the watchdog are very critical it is not posssible to do it manually.

Using code that initialises variables before configuring the watchdog may work if there are only a few variables to be initialsied but when the operation exceeds the 256 allowed instructions it would then fail (eg. when a few more variables are added).

I can't explain why the debugger allows the code to operate but, as stated above, I believe the only way to do this is to put the watchog initisation "before" any variable initialisation since it is "normal" (from experience and written references) that if the 256 instructions are used up the watchdog will fire and so the code can't operate.

Regards

Mark

0 Kudos
641 Views
EdSutter
Senior Contributor II

Mark,

You're right!!!

After reading your response and looking at my code (again), I realized I moved my call

to SystemInit() (where I was disabling the WD) to a point much deeper in my startup.

I now do the watchdog disable right out of the reset handler and it boots fine!!!

Thanks very much!!

Ed

PS...

An interesting take-away from this is that somehow the SEGGER (or something that is associated

with that connection) magically disables the WD when connected.

0 Kudos
641 Views
mjbcswitzerland
Specialist V

Hi

Is it a watchdog issue? Ensure that the watchdog is either disabled or configured within 256 clock cycles (maybe the debugger is handling this too):

http://www.utasker.com/docs/KINETIS/uTaskerV1.4_Kinetis_demo.pdf (page 33)

http://www.utasker.com/forum/index.php?topic=1664.0

Regards


Mark

0 Kudos
641 Views
EdSutter
Senior Contributor II

Mark,

I don't *think* thats a problem.  I've booted a K64F FRDM board prior to this with similar startup.

I disable the watchdog in SystemInit()..  Strangely, there is something else to add, based on your

watchdog suggestion...

I have a small reset function which enables the watchdog and just waits for it to kick in.

Based on your comment, I added a timeout to the wait loop that I have in there just to see

if its getting locked up in the while(1) (endlessly waiting for a reset to occur).  Its not timing out.

That tells me that the board actually is *trying* to reset, but is not successfully.

Ed

0 Kudos