5 years, 9 months ago.

Can't flash below address 0x80000 in K64F


I wrote my own flash utilities since i'm trying to update code over ethernet and I've done this many times with other processors.

I can erase/burn any segment of flash above 0x80000 like a champ! However, the processor resets with a "Core Lockup" event in the RCM_SRS1 register if I try any lower address ( 0x70000 for example). I have distilled the problem down to just the memory issue and can duplicate it in a single page of code. Thus eliminating the RTOS, ethernet, etc from the list of possible causes (still using mbed of course for printf(), etc). My thought is that there is something in the mbed reset sequence that protects the lower mem?

I've poked around the FPROT and MPU registers to look for any enabled protection scheme but all values seem to be default. And I never get any ACC or PRIV violations in FSTAT.


However, i'm new to the chip so please let me know where else to look.

Your example in the Bootloader code doesn't seem to have this issue.

I did use the attribute trick to locate my boot loader to higher mem so thanks for that.

Do you have any experience with the SWAP mechanism? it seems designed for firmware updating but I cannot understand the explanation in the docs.

Happy Thanksgiving Tony

--- Problem solved --- Sorry, i'm still not used to the forum etiquette but I couldn't close out this thread using what I thought was the proper method.

Summary of Solution: I took Erik's advice and imported the IAPBootloader project. I modified it to simply erase 1 sector and burn 64 bytes to it. Not unexpectedly, the program worked fine below 0x80000. Before weaving the IAP into my project, I decided to go down the Rabbit Hole and find out why my version didn't work. Since MI State was totally dominating Penn State on Saturday, it seemed like a good time to try manually disassembling the opcodes in the eraseSector routines and compare them to find the difference.

My version which used unsigned char pointers to reference the FLASH registers had all sorts of sign extension and word and halfword instructions to access the registers. At least that is my interpretation but I am totally new to the ARM core so there is good chance i'm wrong.

The IAP version had precise byte reads and writes. Again, I might be wrong.

So that let me to looking at the headers which define the register access. Apparently MK64F12.h defines the data structures for all Core registers. So the FTFE registers were already nicely defined. I originally thought the IAP defined those and since I wasn't using it didn't think those regs were predefined. I noticed that I was using the same names in my code as local variables. FSTAT, FCCOB, etc which were already defined ( I know, I should have used lower case ).

Once I changed the names the problem went away.

I am using the MK64F12.h definitions now for other things now.

Thanks for the adventure! I learned a lot.

Question relating to:

Example of a Serial bootloader for the K64F platform bootloader, FreescaleIAP, K64F

1 Answer

5 years, 9 months ago.

I haven't checked the SWAP mechanism myself.

Since you are using ethernet, I assume you have a quite large program, how many bytes is it total? I would think the most likely reason for this happening is that your flash update code tries to access code which is removed. My bootloader example is very simple, so it was relative easy to make sure it only accesses functions which were moved to the bootloader area. If you for example still access ethernet functions, those will not have been placed in a safe area (well unless you used the attribute trick also for every function there, although even then there is the risk that it uses for example standard C functions which are not inlined, and are placed in the area which you are erasing).

When I looked into it I of course also had initially issues with it not working properly, so I also did a quite extensive search on protection mechanisms, and I didn't find any which should be enabled by default with mbed code. And indeed you should get those violations in the FSTAT registers if that was the case.

Accepted Answer

Thanks for the quick response,

As I mentioned in my post, I eliminated all the size and ethernet issues by simply reducing the essential code to a single page without the RTOS in an experimental project. I am just erasing a sector (4K) and writing 64 bytes (8 phrases) to induce the problem. The reset occurs with the EraseSector.

FCCOB[0..3] = 090E0000 this works

FCCOB[0..3] = 09070000 this throws the core lockup reset

I made the code as primitive as possible to eliminate compiler quirks ( I assume "*(unsigned char *) FSTAT " works properly if I used "unsigned char *FSTAT = (unsigned char *)0x40020000;" to define it? ). I would really like to see the generated assembler so I can verify the byte,word,dword instructions being used (or not).

I do this sort of thing all the time in S12 processors ( previously HC12, HC11) and in assembler (to get away from the compiler trying to "help me" write better code - but i'm not bitter! ).

I have everything working in the main project ( with ethernet and RTOS) capable of receiving 100K bin files then burning to location 0xeE0000 as a test. Once I can figure out why I can't burn the entire lower half of memory, I should be done.

posted by Tony Diodato 27 Nov 2015

My bad, I missed you already had it greatly reduced. Do you use printf after the erasing has started? Since that won't be moved to other memory. Although you shouldn't need that much space for a simple program. So the question is still relevant: How large is your test program?

For FSTAT that should work yes, however it is also predefined, see the FreescaleIAP library on how to use the predefined one. Also if I am correct you are using your own code? How about if you use FreescaleIAP code, do you get the same error?

posted by Erik - 27 Nov 2015