I am trying to implement an OTA upgrade based on the sample project names OTA Programming Demo.
Because this is an MKW21D256 and I don't have an external EEPROM component on my board, I am using the internal flash as EEPROM.
I was able to write the entire image to the internal storage (I can see this because I read-back the entire content of the image via UART to file and compare to the source and they are identical).
After I reset the device it just freezes, does'nt boot back (I need to re-flash it using JTAG).
My questions are:
1. Is this feature (OTAP using internal flash) supported by MKW21D256?
2. What should be the value of the sector bitmap that is written to the flash?
3. What file generated by IAR (bin/out/srec) should be loaded with this procedure?
Any help will be greatly appreciated,
First of all, what codebase are you using? The one from Beekit or the new one that has KSDK and RTOS?
The answers to your questions are:
1. Yes, OTAP is supported for MKW21D256
2. Here we will discuss after I will know the codebase that you are using
3. If you are using TestTool then .srec is the file that have to be loaded. If you are using your own or custom tool, then it can be any format.
Thanks for the answer,
I am using Kinetis MAC Codebase 4.0.1, the one from BeeKit (3.0.2 if that matters).
I have written my own tool that loads the image via UART to the device, I can see that the entire image (basically the file I chose on the PC) is loaded to the internal flash, but my code is largely based on the example I have mentioned above.
My srec file generated by IAR is 146KB, I can see that the internal flash section that simulates the EEPROM is only 64KB, therefore cannot load the srec file, how can I use the bin file instead (or make the internal flash section bigger?)
First of all, the .SREC file must be parsed before it is stored in flash.
Only the actual binary image must be stored from the SREC file!
For the following SREC line S1137AF00A0A0D0000000000000000000000000061, only the selected octets must be stored in flash in the following order:
0x0A 0x0A 0x0D 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
For more information about SREC file visit: https://en.wikipedia.org/wiki/SREC_(file_format)
The OTAP bootloader expects the following image format:
1 = erase sector, and update with new image if available
0 = leave sector unchanged
The internal flash storage used by the OTAP Demo is not the emulated EEPROM but actually the remaining (unused) MCU flash.
For example, if you have 256KB of MCU flash, and current image size is 100KB, you can use the remaining 155KB (256 – 100 - 1) for storing the new image.
If the new image is larger than the remaining flash size, there is no way to store the new image into flash!
The TestTool application can parse the SREC file and discard the last sectors, making the actual binary image smaller.
The last sector of the MCU flash must contain the start address of the internal image storage which will be used by the bootloader (see gHardwareParameters -> internalStorage_StartAddr).
If internalStorage_StartAddr = 0xFFFFFFFF, the bootloader will try to read the image from an external SPI flash!
First of all, thank you very much for your answer, it cleared a lot for me, just a few more questions to see that I got it completely:
1. Regarding the sectors bitmap, the bitmap is 32byte long meaning it can represent 256 sectors, each 2K if I understand correctly so it supports 512K flash but in my case (MKW21D256) I will only use the first 16 bytes?
2. What should the values for the sector bitmap be? I am referring to the linker file MKW21D256V.icf and its definitions there, specifically this table:
| ROM2/FlexNVM |
| region |
| FSL Prod Data |
| NVM Region |
| Int. Storage |
| ROM region |
| Bootloader |
a. Where is the original image stored? I am writing the new image to the section names "Internal storage" in this EEPROM-less example and if the current application resides there wouldn't I override the image and might hurt the process of the running application?
b. In this example, what should be the sector bitmap if I would like to erase the old image and replace it with the new image that resides in Internal Storage section
3. Who will write the EEPROM start address to the last sector of the image? Will the HW know how do identify the HardwareParameters_t structure? It looks to me as if in this example (EEPROM is internal storage), the FSL section is not used (maybe overridden by larger NVM_Storage section?) because when I try to use externs to FSL_PROD_DATA_END_ADDRESS or FSL_PROD_DATA_START_ADDRESS I get a linker error.
4. How can I verify (in code or using IAR) that the image address is located in the right position?
5. Can I debug the bootloader using IAR somehow? After I complete the upgrade and reset the device nothing happens (as if it is powered off) and it will be very helpful for me to understand what exactly is not working
Thank you very much again.
1. For MKW21D256, the first 16 bytes, represent the bitmap for the internal MCU Flash. Some of the remaining bytes are used as an erase bitmap for the FlexNVM region (the emulated EEPOPM).
2. An example of the sector bitmap is: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE00000000000000000000000000000000
This will erase almost all the MCU Flash. The Bootloader itself will not be erased/updated, but the new image must contain the Bootloader code, and it will be skipped at upgrade.
Also, the last Flash sector will remain unchanged (because of the 0xFE value) to not alter the gHardwareParameters structure.
The last 16 zeros means that the FlexNVM will not be erased!
If you are using NVM instead of FlexNvm, and you need to preserve the information stored, then you must modify the sector bitmap, to skip the NVM sectors also.
a) The original image is stored right after the bootloader region. The written image cannot and must not cross over the INTERNAL_STORAGE boundary. The IAR will issue a section placement error if this happens.
The new image will be stored in reserved FLASH region and it will not overwrite the existing application code!
b) See the example from above.
3. In the OTAP demo provided, the gHardwareParameters structure is explicitly placed in the FREESCALE_PROD_DATA section:
#pragma location = "FREESCALE_PROD_DATA"
HardwareParameters_t const gHardwareParameters =
.internalStorage_StartAddr = gDefaultInternalStorage_StartAddress_c,
Then gDefaultInternalStorage_StartAddress_c is defined as:
#define gDefaultInternalStorage_StartAddress_c gEepromParams_StartOffset_c
And if gEepromType_d == gEepromDevice_InternalFlash_c:
#define gEepromParams_StartOffset_c ((uint32_t)INT_STORAGE_END)
The FSL_PROD_DATA_END_ADDRESS and FSL_PROD_DATA_START_ADDRESS symbols are not visible in C source code because they are not defined as “exported symbols”. If you need to use those symbols, you must add the “exported” keyword to their definition.
The bootloader knows the offset of the internalStorage_StartAddr field, and it uses its value to decide from where to read the new image.
4. You must verify that the gHardwareParameters structure is placed at the beginning of the last Flash sector:
gHardwareParameters 0x0003f800 0x50 Data Gb NV_Data.o 
then you must check that the value of the internalStorage_StartAddr is INT_STORAGE_END.
5. Yes, you can debug the bootloader using the provided project: Freescale\Codebases\BeeKit Kinetis MAC Codebase 4.0.1\SSM\FreeScale\V01.00\Generic\Bootloader_OTAP\
You must attach to the running target, before the MCU reset which starts the upgrade process!
Thanks again George for the reply, my question is how do I specifically attach the bootloader process to the running target? I am performing my SW upgrade using my tool and then I build and run the bootloader project and it appears as if all the data that I've written is overridden like the HardwareParameters.
I explicity write the HW parameters again to the last sector (even though I think it is already done by the linker) but I see that in the bootloader application it reads as if the boot image start address is 0 (while it is INTERNAL_STORAGE_END).
I figured out how to attach to a running process and when I debug the bootloader I see that the bootflags are correct, that the image size is read correctly as well as the sector bitmap.
When debugging the bootloader process I notice that it always fails when trying to execute FTFL_EraseSector(flashAddr) and the flashAddr is 8192 (I'm guessing it is the first sector for flash data after the flashAddr >= gUserFlashStart_d condition.
This results in a continuous reset that re-starts the bootloader process and so on.
Do you have any idea why this sector erase would fail? Is there anything I can do to maybe change the source code for the bootloader to overcome this? because currently I have finished loading the image to internal storage and appears all aspects in my application side are OK and still not able to boot the new image.
Can you update the following function and try again:
uint16_t i, size;
// RAM function should have the same alignment as one from ROM
if( ((uint32_t)ExecuteOnStackStart - 1) & 0x03 )
i = 2;
i = 0;
size = sizeof(buffer) - i;
// initialize pointer to ram function
ExecuteOnStack = (void(*)(void))&buffer[i+1];
// copy function from ROM to RAM
for( ; i<size; i++ )
buffer[i] = ((uint8_t*)ExecuteOnStackStart)[i-1];
// inititalization of flash clock module
It is possible that the RAM function is not aligned correctly.
Same behavior, the function fails at exactly the same address (8192)
According to the debugger (don't know if to trust the data there), the value of FTFL_FSTAT is 0x81 thus corresponds to FTFL_FSTAT_MGSTAT0_MASK (don't know what it means though).
You must configure your application's project options to point to the new bootloader binary image:
Project Options -> Linker -> Input -> Raw binary image (must point to the updated bootloader)
Also, if you have enabled Flash protection, then the erase procedure will fail (check FlashConfig: 0x400 - 0x407).
Please provide the value of the FTFL_FSTAT (0x40020000) register, after the failed erase procedure. You can define the "gBootLoaderDebug_c" macro to help with the debug process.
According to the MKW2x Reference Manual, it seams that the Flash erase verification failed!
It is possible that your MCU Flash is broken. Do you have another board to check if this issue persists?
I have tried it on a different board and indeed the process now seems to complete, only issue now is that after entire image is loaded and device is reset following, the application does go now to JumpToApplication, however nothing happens following which makes me think there is something wrong with the image I am loading.
Can you please provide a short guideline how to create a bootable image using the IAR generated srec file (or a different one if needed?)
Thank you very much,
The Bootloader will ignore the first 1/32 of the image (the Flash reserved by the bootloader application):
if ((*pBitmap & bitMask) && (flashAddr >= gUserFlashStart_d))
The new application, must also contain the bootloader binary (even if the bootloader will skip over this section). Check the linker settings of the “OTA Programming Demo Client”
Also the Bootloader Flags section must be present in the application to be loaded!
If you do not want to add the bootloader .bin in the application to be loaded, then you must modify the bootloader code:
Thanks again for your answer, I have all the parameters configured as you described (including the bootloader image). What I am actually trying to do is load the same image that I am running to the target and reset - I expect it to load the same software (and that it will include the bootloader as the initial image does).
What I am doing to do so is going into the Test Tool and under the OTA Beestack page I generate a file based on the srec file that was generated by IAR. Actually I am doing the following:
1. Go to OTA Beestack page
2. Select the SREC file compiled by IAR
3. In the popup window I select KW2x and check the checkbox for "(Do not include NVM firmware in OTA file)"
4. I click "Save"
5. The tool generates a .zigbee file that I am loading to the target as the image via UART.
Can you please explain if this process is indeed the required one and am I missing something?
The .zigbee file contains additional headers and cannot be used as a bootable image.
This file is usually parsed by the client application, and only the image binary information is stored in Flash.
I think that you have to make your own .srec parser and send the binary data over UART to the MCU.
You can use the .bin file generated by IAR, but because the gHardwareParameters structure is placed in the final Flash sector, the file size will be ~256Kb.
You have to discard the final Flash sector, and the padding added by the IAR.