Abstract
MK60 is a popular MCU in Kinetis K family. NXP has prepared some kinds of bootloader for TWR-K60D100. But as we all know, MCUBoot2.0.0 is the most update bootloader for Kinetis family. It is a configurable flash programming utility that operates over a serial connection on Kinetis MCUs. It enables quick and easy programming of Kinetis MCUs through the entire product life cycle, including application development, final product manufacturing, and beyond. But sinceTWR-K60D100 is a relatively old platform compare to K22 and K64/K65/K66, MCUBoot2.0.0 did not add MK60 to its target board. If customer don’t like those old bootloader, they have to port it by themselves. This article tries to guide user to port MCUBoot to TWR-K60D100 base on Chapter 10 in Kinetis Bootloader v2.0.0 Reference Manual. This time we use KDS.
Software requirement:
Kinetis Design Studio 3.2
MCUBootloader 2.0.0 (KBoot 2.0.0)
MCUXpresso Config Tools v4.0
SDK_2.2_TWR-K60D100M
Step 1:
First I copy NXP_Kinetis_Bootloader_2_0_0\targets\MK64F12 to NXP_Kinetis_Bootloader_2_0_0\targets\MK60D100. The reason I select MK64 is more likely to MK60 than other target, especially in clock distribution, system integration module and signal multiplexing. In mk60d100\src directory, rename the following files:
Then copy system_MK60D10.c and system_MK60D10.h from SDK_2.2_TWR-K60D100M to mk60d100\src\startup, copy startup_MK60D10.S from SDK_2.2_TWR-K60D100M to mk60d100\src\startup\gcc.
Step 3:
Then I copy \src\platform\devices\MK64F12 to \src\platform\devices\mk60d100, copy SDK_2.2_TWR-K60D100M\devices\MK60D10\fsl_device_registers.h, MK60D10.h, and MK60D10_features.h to this new directory.
Step 4:
Open the KDS project in MK60D100 and replace above old file with new file. After that, I change some setting.
Figure 1. Target Processor change
K64 has hardware FPU, but K60D100 hasn’t. So, Float ABI must be changed to software.
There is a C/C++ preprocessor define that is used by the bootloader source to configure the bootloader based on the target MCU. This define must be updated to reference the correct set of device-specific header files.
Figure 2. Preprocessor change
As to the link file, it needn’t to be change. We can use K64’s link file.
TWR-K60D100 use an old version PE debugger. So, the debugger setting must be changed.
Figure 3. Debug setting
Step 5:
MK60’s clock distribution structure is different with MK64. We must modify this part. As it is very complex, use MCUXpresso Config Tools to generate this config code is a sensible choice.
Open the tools and step clock structure as below:
Figure 4. clock setting
After that, generate the code and save them to \src\platform\devices\mk60d100. Since MCUBoot2.0.0 is not base on SDK2.x, we must copy some related driver file from SDK2.x package, include fsl_smc.c, fsl_smc.h, fsl_rtc.c, fsl_rtc.h. Then add them to project.
In clock_config_mk60d100.c line 168, the code is
clock_mode_switch(s_currentClockMode, kClockMode_FEI_48MHz);
Replace it with:
BOARD_BootClockUSB(); // this function was generated by MCUXpresso Config Tool
Then add the head file of “clock_config.h”.
Step 6:
TWR-K60D100 use UART5 as the debug UART port. Please refer to https://community.nxp.com/docs/DOC-340954 for detail. MCUBootloader2.0.0 do not support UART5. User must add its code in pinmux_utility_common.c.
Step 7:
Modify usb_clock_init() in hardware_init_MK60D100.c as below
bool usb_clock_init(void)
{
SIM->SCGC4 &= ~SIM_SCGC4_USBOTG_MASK;
SIM->CLKDIV2 = (uint32_t)0x00L;
SIM->SOPT2 |= SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL(0x01); //k60 PLLFLLSEL change from 3 to 1
SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK;
// USB0->CLK_RECOVER_IRC_EN = 0x03;
// USB0->CLK_RECOVER_CTRL |= USB_CLK_RECOVER_CTRL_CLOCK_RECOVER_EN_MASK;
// USB0->CLK_RECOVER_CTRL |= 0x20;
return true;
}
Modify memory_map_MK60D100.c as below:
memory_map_entry_t g_memoryMap[] = {
{ 0x00000000, 0x0007ffff, kMemoryIsExecutable, &g_flashMemoryInterface }, // Flash array (512KB)
{ 0x1fff0000, 0x2000ffff, kMemoryIsExecutable, &g_normalMemoryInterface }, // SRAM (256KB)
{ 0x40000000, 0x4007ffff, kMemoryNotExecutable, &g_deviceMemoryInterface }, // AIPS peripherals
{ 0x400ff000, 0x400fffff, kMemoryNotExecutable, &g_deviceMemoryInterface }, // GPIO
{ 0xe0000000, 0xe00fffff, kMemoryNotExecutable, &g_deviceMemoryInterface }, // M4 private peripherals
{ 0 } // Terminator
};
Modify bl_uart_irq_config_common.c as below:
void UART_SetSystemIRQ(uint32_t instance, PeripheralSystemIRQSetting set)
{
switch (instance)
{
case 0:
#if (FSL_FEATURE_SOC_UART_COUNT > 1)
case 1:
#endif // #if (FSL_FEATURE_SOC_UART_COUNT > 1)
#if (FSL_FEATURE_SOC_UART_COUNT > 2)
case 2:
#endif // #if (FSL_FEATURE_SOC_UART_COUNT > 2)
#if (FSL_FEATURE_SOC_UART_COUNT > 3)
case 3:
#endif // #if (FSL_FEATURE_SOC_UART_COUNT > 3)
#if (FSL_FEATURE_SOC_UART_COUNT > 4)
case 4:
#endif // #if (FSL_FEATURE_SOC_UART_COUNT > 4)
#if (FSL_FEATURE_SOC_UART_COUNT > 5) // add UART5 support
case 5:
#endif // #if (FSL_FEATURE_SOC_UART_COUNT > 5)
if (set == kPeripheralEnableIRQ)
{
NVIC_EnableIRQ(uart_irqs[instance]);
}
else
{
NVIC_DisableIRQ(uart_irqs[instance]);
}
break;
}
}
In target_config.h, modify kMaxCoreClock value to 100.
Step 8:
After all of the above work, compile the project and download to TWR-K60D100 board. You’ll find KinetisFlashTool.exe can recognize the device by UART. If you establish a Tower system with TWR-SER board, KinetisFlashTool can also recognize the device by USB.
K60 is the base of many Kinetis K series MCU, include K10, K20, K61, K70. If you want to port MCUBoot2.0.0 to these MCU, you just want to update the clock_config file.
Hi Jing Pan,
According to the Step 3, you copy files from tower code right? Is this 3 .h files is located in the project. If I didnt use the tower, I use my own board, where can I generate or copy the 3 files?
Thank you.
ila
Hello,
I tried to follow all the steps given, then compile the whole project.
in Step 5, I change the clock_mode_switch() and add #include "clock_config.h" on top. Add in the file clock_config.h in my project as well.
After I build it, the error popup asking the clock_config.h :
fatal error: clock_config.h: No such file or directory.
Is the anything wrong I did or something missing in my steps? Please advise. Thanks.
Regards,
illa
Hi
If you have difficulties with building loaders for the K60s you can find a simple solution here:
https://www.utasker.com/kinetis/TWR-K60N512.html
https://www.utasker.com/kinetis/TWR-K60D100M.html
https://www.utasker.com/kinetis/TWR-K60F120M.html
Almost all Kinetis parts and boards have been ported and have much higher features and loader combination possibilities.
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Dear Mark,
Thank you for the other solution.
I realize something on my code development. As I am using K30, the USB is unavailable in MCUXpresso Config Tool. So that is why the code cant detect the
routine BOARD_BootClockUSB().
Is this clock referring to the UART functional clock? I am not really sure on this.
Regards,
illa
Hi
The K30 is available in 100MH and 72MHz families and the 100MHz is essentially a K40 without USB:
https://www.utasker.com/kinetis/TWR-K40X256.html
https://www.utasker.com/kinetis/TWR-K40D100M.html
USB has nothing to do with the UARTs and so any USB initialision (including USB clock initialisation) should be removed.
It would of course be best to start with a K40 solution rather than a K60 solution when targeting a K30.
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Hi Mark,
I tried to use the K40 as the kick start for my K30 board. After going through all the note in uTasker, why the MODBUS.c and modbus.h file is empty.
Im trying to use Modbus-RTU. Seems like the code not support for the demo. How to use SerialTaskerLoader with Modbus-RTU as medium?
Thanks,
illa
Hi Illa
The Modbus module is not included in the open source project since it is reserved for professional use by companies that fund the project.
The open source version still includes a number of popular loading methods that are available to everyone.
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]