USB MSC device bootloader revision for FRDM-KL25Z (IAR)

Showing results for 
Search instead for 
Did you mean: 

USB MSC device bootloader revision for FRDM-KL25Z (IAR)

USB MSC device bootloader revision for FRDM-KL25Z (IAR)



This document is a supplement and revision of AN4379 Freescale USB Mass Storage Device Bootloader written by dereksnell in 2011. The original version was programmed with CW for Flexis JM/ColdFire MCF522XX/Kinetis K60. It has not been updated for 2 years.

In 2013, I selected FSL MKL25Z as my prefer platform for USB host/OTG application, because it has on chip OTG module, instead of regular device module in its competitors have. I can develop some USB host applications. IAR is selected among commercial compilers for KL2X and other MCU development, since IAR can offer 32KB limited edition for ARM. In order to make AN4379 work on my FRDM-KL25Z, it involves porting efforts between compilers (from CW to IAR EW) and hardware platforms (from K60 to KL25).

Reused Sources

I gave up the original release since I found FSL USB stack has been improved in many ways between v4.0.3/v4.1.1 and Derek's base. The MSD application from USB stack are reused as baseline. I also merge flash and serial port driver from AN2295 Serial bootloader, as well as some helper functions for debug purpose.

The printf( ) sometimes is more helpful than debugger, since it can reveal information during full speed run time. However, don't print out too many characters, since it occupies many resources. Don't print message everywhere, use it only when necessary and remove them in your final release.

Bootloader Project & Sources

A working bootloader project should include following files and paths.

X:\Freescale USB Stack v4.0.3\Source\Device\app\msd_bootloader

X:\Freescale USB Stack v4.0.3\Source\Device\app\common

X:\Freescale USB Stack v4.0.3\Source\Device\source\driver\kinetis

X:\Freescale USB Stack v4.0.3\Source\Device\source\class\usb_msc*.*

X:\Freescale USB Stack v4.0.3\Source\Device\source\common

Since I have not touched any code in Device\source folder and it is part of USB stack. You can unzip them into a separate folder and merge them into your existing USB stack tree.

Be careful, since I have changed some code in common folder. It is up to you to merge them with compare tool. And MSD bootloader and MSD user application indeed have differences in main( ).

Open the attached project in IAR EW, rebuild it and download into debugger.

Then you can connect its user USB port to PC, the OS will prompts MSC device connecting and BOOTLOADER driver is shown later on. You can drag and drop , copy and paste or enter in command prompt to copy any user application S-record file into BOOTLOADER driver.

If your application code is designed for MSD bootloader, it will run after reset. For what is designed for MSD bootloader, please check the following chapter.

First Thing First

The bootloader must have conditional jump to user application. The condition could be push button or timeout counter. As a result, the GPIO and timer must be initialized as first step. According to Cortex-M's nature, MCG should be initialized as well in some cases. However, I find multiple calls to MCG initialization routines may cause system hangs on it. The detail logic has not been recovered so far. But I would like to recommend to initial GPIO and LPTMR only, without touching too much on MCG pll_init( ).

Default Operation

The bootloader will check if PTA2 has been grounded after reset. It will drops to bootloader anyway if it is connected to ground. Otherwise, it will check 0x8000~0x8004 for SP/PC checking. If there is a valid user application, it will transfer control to user application. If not, bootloader will enumerate an MSD driver called BOOTLOADER. There is a file called READY.TXT inside the driver.

Custom Bootloader

The bootloader can be used directly, or you can custom it. That's why I still keep the revised bootloader as open source. You can rename the driver label, download and run, more firmware format like intel hex, use another ISP push button, resize the driver, add CDC for debug purpose, add driver inf file for custom driver installation, add bi-directional communication over file system, add more features.

However, you must understand FAT16 and make modification by yourself. You have to help yourself.

Demo User Application Project

Another attachment FRDM_KL25ZDemo_freedom.srec is demo project from Kinetis L family release and its S19 file, linked with modified ICF link file.

The starting address of an user application is heavily device dependent, which basically related to its 32bit flash protection registers.

Since MKL25Z128VLK4 has 128KB flash memory, the minimal protected flash block is 128K/32=4KB. The existing MSD bootloader release is 22KB (0x597F). So 0x6000 could be the start address of an application. Considering potential integrated features and data storage in future releases, 0x8000 is recommended as application start address.

General Purpose ICF files

During my development with AN2295(Serial) / AN4370(DFU) / AN4379(MSC device) bootloaders, I prepared more linker file. The only differences are the starting addresses, aka relocated vector address, ranges from 0x4000 / 0x8000 / 0xA000. The attachment Pflash_128KB_0x8000.icf explains itself from its name

You can easily find necessary modifications for your ICF files in AN2295/AN4370/AN4379 documets.

We can put three versions of ICF file in your linker script folder for easy development.

Unnecessary Flash Protection Bytes

By inspecting the S-Record file, I found the flash protection bytes are still reserved in user applications. Furthermore, the area between 0x80C0 and 0x83FF is kept as 0xFF, blank bytes. The flash protection bytes from 0x8410 to 0x841F are unnecessary since these flash protection bytes are useless in a relocated flash address besides 0x410~0x41F. We can remove the definitions and free some flash memories for user code and EEPROM emulation.

In order to free these bytes, we must search source file and icf file who might hold them. This topic has not been covered here.

Debug Skills

You can debug both bootloader as well as user application with FRDM-KL25Z. Amazing !

It is easy for debug bootloader, since it is a regular application. How to debug a relocated user application? You can download the firmware by bootloader. After bootloader transfers control to the user application, you have to debug it in disassembly Window.

Or you can download the user firmware as a regular application in debugger. The debugger will stop at main( ) of user application. If you want to debug the code before running main. Simply add more breakpoint, press reset. The debugger will tell you if you want to stop running to main. Click "stop", you will be forwarded to the address of user PC points to.

By using these skills, I found my bootloader pll_init( ) has some side-effects on user application's pll_init( ). The debugger is very helpful in debugging both bootloader and relocated user firmware. Compare to IAR's debugger, Eclipse's debug Window is a mess. It has not reset button at all. That is why I usually use IAR for development and port to GCC later on.

More Features

FSL bootloaders only offers a basic framework. The users will need more features in future development. I am preparing following features when I am available.

License file

Including SNR and installation, activation, authentication as well as user API. By this license program, the firmware developers can monetize their IPR investment.

User files

Support emulated file with on-chip flash memories, Including drivers, html and other files. It is a handy feature since the users can access the related driver easily. And these files can be read-only and virus-proof. This files can also be used as keys for access control and other security applications.


Since bootloader can be used as part of user application, we can integrate some important ROM API, like authentication, serial communication, and any other algorithms. It is simple to implement, define a dedicated code section, and use KEEP directive avoid optimization by the compilers.


I have changed some code during this release. Like bootloader_task.c .FlashConfig should be updated to protect 32KB or 24KB. The current figure 0xFFFFFFFE only protects one block, aka 4KB.  And it is heavily device dependent. (Please correct me if I am wrong)

So maybe there are still a lot of bugs. Feel free to leave your comment.

I only tested it with S-record file, you are free to test it with CW binary and raw binary files. Even the S-record file, I have not tested those files with memory gaps in the file. Maybe you should padding the gaps with 0xFF before download.


Nice work, Kai.  Thanks for sharing this.

Nice to hear from you. I find another MSD bootloader from FSL.K20 USB device MSD bootloader.

Interesting, the content is released in Chinese by an FSL employee.

Out of necessity, the Connectivity & IoT team built MSD bootloaders for KW24D512 and K64F, based on this project.

See the following documents:

USB-KW24D512 MSD Bootloader

USB MSD device bootloader revision for FRDM-K64F (IAR)

Hope they can be of use to someone else as well.

wonderfull KAI!! It's work fine on Windows Xp and WIN7. Yesterday I test it on a PC  with WINDOWS8 , but an error happens during a downloading.The result is a damage of the old inside application firmware .have you seen this problem?

Thanks for your sharing, it works well on my KL26Z128.

I know this is an old post, but I just recently ran into the Windows 8.1 problem with my boot loader based on AN4368. I found that Windows 8.1 writes an index file to removable drives when inserted. The boot loader starts trying to flash that file.

This can be worked around by going into group policy and enabling. Computer Configuration \ Administrative Templates \ Windows Components \ Search \ Do not allow locations on removable drives to be added to libraries. the rebooting.

I modified the disk.c file MSD_Event_Callback to make sure the file being written is an S19 file so that there is no need for workaround with Windows 8.1

void MSD_Event_Callback
        uint_8 controller_ID,
        uint_8 event_type,
        void* val
    /* Body */
    PTR_LBA_APP_STRUCT lba_data_ptr;
    uint_32 i;
    uint_8_ptr prevent_removal_ptr, load_eject_start_ptr;
    PTR_DEVICE_LBA_INFO_STRUCT device_lba_info_ptr;

     // Added for Windows 8.1

    static int flash_file = 0;
    static uint32_t data_sector = 0;




#if (defined MCU_MK60N512VMD100)

                file_size = *(uint_32*)( lba_data_ptr->buff_ptr + i + 28);


                file_size = BYTESWAP32(*(uint_32*)( lba_data_ptr->buff_ptr + i + 28));


                // Verify filename extension is S19

                char *ext = lba_data_ptr->buff_ptr + i + 8;

             if((ext[0] == 's' || ext[0] == 'S') && (ext[1] == '1') && (ext[2] == '9') )


              flash_file = 1;

              // Get data sector for the file - starts with cluster 2 so subtract 2 then 32 sectors per cluster plus starting sector

              data_sector  = (*(uint_16*)( lba_data_ptr->buff_ptr + i + 26) - 2) * 32 + FATDataSec0;



                new_file = FALSE;

            } /* EndIf */

         // Ignore files that are not valid S19

         if(flash_file != 0)


          if((lba_data_ptr->offset>>9)== data_sector)



           filetype = UNKNOWN;

           printf("\n\tOpen Image File");

          } /* EndIf */

          if((lba_data_ptr->offset>>9)>= data_sector)


           // SetOutput(BSP_LED3, TRUE);

           /* parse and flash an array to flash memory */

           if (FLASH_IMAGE_SUCCESS == error)


            error = FlashApplication(lba_data_ptr->buff_ptr,lba_data_ptr->size);


           // SetOutput(BSP_LED3, FALSE);

          } /* EndIf */

          /* rest of file */

          if(((lba_data_ptr->offset>>9) - data_sector) == ((file_size -1)/512))


           boot_complete=TRUE;     //tranfer file done


           if(BootloaderStatus == BootloaderReady)


            BootloaderStatus = BootloaderSuccess;



           /* print flashing status */

           if(BootloaderStatus != BootloaderSuccess)


            printf("\nFlash image file fail!");

           } else


            printf("\nFlash image file complete!");

            printf("\nPress RESET button to enter application mode.");

           } /* EndIf */

          } /* EndIf */

         } // EndIf check valid flash_file

Hello Derek,

I am trying to port AN4379 for MK22DX256VLF5 ,can you tell me how ?

Can the same be done for my custom board with MK22DX256VLF5 ? what are the required changes I need to make in the original AN4379 ?


All code can be ported, but beware that the K22DX256VLF5 and the KL25 are different processor families - you have a Cortex M4 and the KL is a low power cortex-M0+ - they have different Flash programming interfaces, clocking, interrupts, DMA and various peripherals require different handling.
Also this is an IAR project and not a KDS/CW one.

If your assignment is to experience a porting task the original K60 is closer for you than the KL25.



Hello Mark

I'll follow that.I have a doubt about the uTasker openSDA app.I couldnt find it anywhere.Can you tell me how to download uTaskerv1.4.sda?


An *.sda file is something from P&E for programming the boot loader in the openSDA chip (K20).

If you want to load an application to a board you need a *.bin or *srec file.



Thank you Mark.What I actually meant  was ,if there is any uTasker Sda so that I can use my openSDA circuitry to flash the target but I found USBDM and Jlink open sda for that.

Thanks :smileyhappy:


Very nice work, thank for your sharing.


Can you help with compiler error. IAR EWB?  I'm trying to port your bootloader project FRDM-KL25Z back to the TWR-K60 and using your project for the K60 as a starting point i get the following warnings and errors:

​1. missing define of Kinetis model. It sets to default: 'K60_100MHz'

​2. There is selected bad target (currently supported targets are KINETIS_K & KINETIS_L)

both refered to ​kinetis_params.h

​I don't understand where this is set..  I have set processor type in

​options->compiler->preprocessor to TWR_K60N512

​Thanks for your help


Unless you have a student assignment where you need to learn how to solve a porting task, you can download a fully operational USB-MSD loader IAR project for the TWR-K60N512 and TWR-K60D100M at



Thank you for your comments Mark.  Unless I'm wrong I take it its your job to trawl these forums to tout for business?  I know that I could buy a solution from you as you have already made that offer.  However, I have looked at your solution and it does not meet our needs.

I need to target a small footprint USB MSD bootloader to our custom K24 board using IAR's EWB.  The solution you have offered is too big, will cost me £'s and is a CW based project.

Further, since NXP have now closed the ticketed support desk we now have only the community forums from which to elicit help.  In the spirit of this community based forum we expect to share our knowledge "for free"  Also, the USB MSD Bootloader was provided by Derek Snell in the first instance for free with a comprehensive App Note which has since been modified by others (a special thanks to Kai).  i.e. ported to other toolchains, Dev boards and MCU's for free so I'm wondering about your justification for using this forum to sell your solution?

At present there isn't, to my knowledge, a FREE to use ported version (K24/IAR) of Derek Snells bootloader.  The closes starting point for me was Kai Liu's effort.  I thought it would be both informative for me and of benefit to the community if I were to provide such a port, however I have come across a build issue that I thought Kai or others might help me with.

As far as my student assignment ;0) .  I have ported many application in my 20 years of doing this job but sometimes it's just worth asking instead of struggling.

To end if you have something constructive to add I would be glad to hear from you

Thanks Dave

Hi Dave

I prefer to say that I try to help professionals solve problems, when there are profesional needs. Otherwise I am also very involved with the community and invest hundreds of hours a year helping other community members with general Kinetis questions etc.

If your aim is to develop for the community then I may also be able to help with the IAR issue in case the original poster doesn't respond - I will wait a few days to see if there is a quick response before checking it out for you.

Concerning the requirement for a solution for a real project/product I have pointed out the fact that this is available in case it is a more attractive proposition for real work than porting to different platforms (compiler and/or Kinetis target).

To precise this:

Quote: "I need to target a small footprint USB MSD bootloader to our custom K24 board using IAR's EWB.  The solution you have offered is too big, will cost me £'s and is a CW based project."

1. The uTasker K24 USB-MSD loader with Win 8.1/MAC OSX compatibility is 13.1k in size when built with IAR EWS (slightly smaller if the compatibility is disabled). This looks to be 40% smaller that the example here so I think that your figures may not be accurate.

2. If you don't want or need support the project is available as open source at the link (usually it is preferred that commerical users contribute something back since they are benefitting from it to reduce project costs and the public source may not include all latest developments).

3. For a direct commercial support license agreement it costs $242.50 which includes 3 months email and telephone support and also help setting up for custom boards. Where this is still too expensive option 2 is available so there should be a solution for everybody, depending on their priorities and needs. For non-commercial work there is also no fee for use or support at the forum (either this one or the uTasker's own forum).

4. The USB-MSD loader includes tested projects for IAR EWB, Keil, CW, KDS, Green Hills, Rowley Crossworks, Atollic, Coo Cox, Visual Studio simulation and standalone GCC.It is in no way based on CW but can be used by CW if desired. It most certainly does include out-of-the-box IAR EWS support because this is the one that is often preferred.

Therefore my conclusion is that I see no indication that this would not be suitable for you in case your requirement is for the lowest cost solution for a commerical project/product, and the IAR project in the link may still help as reference for you to solve the example issue after which you can then still work on porting the example if the main goal is to contribute an example port back to the community.



P.S. To avoid any friction I will not make any further suggestions to any of your posts unless purely of Kinetis technical nature.

Hi Mark,

Thank you for taking the time to expand on your offer for help. I now have a much clearer understanding of the uTasker project and your effort which I’m sure will be a help to others on the forum.  May I take this opportunity to apologies for my misunderstanding and for any friction that I may have caused?

I hope you don’t mind me offering some constructive feedback regarding the uTasker site, please don’t take this the wrong way but my experience of the uTasker project home page was that it contains a lot of information and for the newcomer can be unclear about what’s on offer. A search facility on the site would be helpful as I found it difficult to locate the source code and also maybe a 'how to use this site' guide?

I have now spent some time exploring your site and have concluded that what you say in your previous post is true and that a 50% reduction of cost for the stand-alone USB MSD bootloader is in fact good value for money and makes good commercial sense.



Hello David:

Just to clarify on your comment:

Further, since NXP have now closed the ticketed support desk we now have only the community forums from which to elicit help.

I am curious about how you got this idea. Since the Freescale/NXP merge we are using a different support system and so the process to submit support requests changed, but it was not closed :smileywink:. Please see the next link for instructions:

How to submit a new question for NXP Support

In addition this community is monitored by the technical support team.

About your question here in particular, I just shared an IAR project in your other post:

Port USB Mass Storage Device Bootloader AN4379 for the TWR-K60 project to the IAR EWB


Jorge Gonzalez

Version history
Revision #:
1 of 1
Last update:
‎10-25-2013 05:16 PM
Updated by: