Kinetis Bootloader v2.0.0 Reference Manual
Kinetis Bootloader v2.0.0 Reference Manual
0 Reference
Manual
Rev. 0, 04/2016
Kinetis Bootloader v2.0.0 Reference Manual, Rev. 0, 04/2016
2 Freescale Semiconductor, Inc.
Contents
Section number Title Page
Chapter 1
Introduction
1.1 Introduction.....................................................................................................................................................................9
1.2 Terminology....................................................................................................................................................................9
Chapter 2
Functional description
2.1 Introduction.....................................................................................................................................................................13
Chapter 3
Kinetis bootloader protocol
3.1 Introduction.....................................................................................................................................................................25
Chapter 4
Bootloader packet types
4.1 Introduction.....................................................................................................................................................................31
Chapter 5
Kinetis bootloader command API
5.1 Introduction.....................................................................................................................................................................41
Chapter 6
Supported peripherals
6.1 Introduction.....................................................................................................................................................................67
6.5.2 Endpoints........................................................................................................................................................... 81
6.6.2 Endpoints........................................................................................................................................................... 87
6.8.2 Look-up-table.....................................................................................................................................................95
Chapter 7
Peripheral interfaces
7.1 Introduction.....................................................................................................................................................................101
Chapter 8
Memory interface
8.1 Abstract interface............................................................................................................................................................ 107
Chapter 9
Kinetis Flash Driver API
9.1 Introduction.....................................................................................................................................................................111
9.3.1 flash_config_t.....................................................................................................................................................113
9.4.8 FLASH_VerifyEraseAll.....................................................................................................................................119
9.4.9 FLASH_VerifyErase..........................................................................................................................................120
9.4.10 FLASH_VerifyProgram.....................................................................................................................................121
9.4.12 FLASH_ProgramOnce.......................................................................................................................................124
9.4.15 FLASH_SetCallback..........................................................................................................................................127
Chapter 10
Kinetis bootloader porting
10.1 Introduction.....................................................................................................................................................................131
Chapter 11
Creating a custom flash-resident bootloader
11.1 Introduction.....................................................................................................................................................................141
Chapter 12
Bootloader Reliable Update
12.1 Introduction.....................................................................................................................................................................153
Chapter 13
Appendix A: status and error codes
Chapter 14
Appendix B: GetProperty and SetProperty commands
Chapter 15
Revision history
15.1 Revision History............................................................................................................................................................. 169
1.1 Introduction
The Kinetis bootloader 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. The bootloader is delivered in two ways. The
Kinetis bootloader is provided as full source code that is highly configurable. The
bootloader is also preprogrammed by Freescale into ROM or flash on select Kinetis
devices. Host-side command line and GUI tools are available to communicate with the
bootloader. Users can utilize host tools to upload/download application code via the
bootloader.
1.2 Terminology
target
The device running the bootloader firmware (aka the ROM).
host
The device sending commands to the target for execution.
source
The initiator of a communications sequence. For example, the sender of a command or
data packet.
destination
Receiver of a command or data packet.
incoming
• FlashReadResourceResponse
• ConfigureQuadSPI
• ReliableUpdate
• SB file state machine
• Encrypted image support (AES-128)
• Packet interface
• Framing packetizer
• Command/data packet processor
• Memory interface
• Abstract interface
• Flash Driver Interface
• Low-level flash driver
• QuadSPI interface
• Low-level QuadSPI driver
• On-the-fly QuadSPI decryption engine initialization
• Peripheral drivers
• I2C slave
• SPI slave
• CAN
• Auto-baud detector
• UART
• Auto-baud detector
• USB device
• USB controller driver
• USB framework
• USB HID class
• USB Mass storage class
• CRC check engine
• CRC algorithm
2.1 Introduction
The following subsections describe the Kinetis bootloader functionality.
The first configuration field 'tag' is a tag value or magic number. The tag value must be
set to 'kcfg' for the bootloader configuration data to be recognized as valid. If tag-field
verification fails, the Kinetis bootloader acts as if the configuration data is not present.
The tag value is treated as a character string, so bytes 0-3 must be set as shown in the
table.
Table 2-2. tag Configuration Field
Offset tag Byte Value
0 'k' (0x6B)
1 'c' (0x63)
2 'f' (0x66)
3 'g' (0x67)
The flags in the clockFlags configuration field are enabled if the corresponding bit is
cleared (0).
Table 2-3. clockFlags Configuration Field
Bit Flag Description
0 HighSpeed Enable high-speed mode (i.e., 48 MHz).
1-7 - Reserved.
tag is incorrect, the configuration values are set to default, as if the data was all 0xFF
bytes.
3. Clocks are configured.
4. Enabled peripherals are initialized.
5. The the bootloader waits for communication to begin on a peripheral.
• If detection times out, the bootloader jumps to the user application in flash if the
valid PC and SP addresses are specified in the application vector table.
• If communication is detected, all inactive peripherals are shut down, and the
command phase is entered.
NOTE
Flashloader does not support this feature.
To get the address of the entry point, the user application reads the word containing the
pointer to the bootloader API tree at offset 0x1C of the bootloader's vector table. The
vector table is placed at the base of the bootloader's address range.
The bootloader API tree is a structure that contains pointers to other structures, which
have the function and data addresses for the bootloader. The bootloader entry point is
always the first word of the API tree.
The prototype of the entry point is:
void run_bootloader(void * arg);
The arg parameter is currently unused, and intended for future expansion. For example,
passing options to the bootloader. To ensure future compatibility, a value of NULL
should be passed for arg.
Example code to get the entry pointer address from the ROM and start the bootloader:
// Variables
uint32_t runBootloaderAddress;
runBootloader(NULL);
NOTE
The user application must be executing at Supervisor
(Privileged) level when calling the bootloader entry point.
The application integrity check is an important step in the boot process. The Kinetis
bootloader (KBOOT) provides an option, and when enabled, does not allow the
application code to execute on the device unless it passes the integrity check.
Kinetis bootloader uses CRC-32 as its integrity checker algorithm. To properly configure
this feature, the following fields in the BCA must be set to valid values:
• Set crcStartAddress to the start address that should be used for the CRC check. This
is generally the start address of the application image, where it resides in the flash or
QuadSPI memory.
• Set crcByteCount to the number of bytes to run the CRC check from the start
address. This is generally the length of the application image in bytes.
• Set crcExpectedValue to the checksum. This is the pre-calculated value of the
checksum stored in the BCA for the bootloader to compare with the resultant CRC
calculation. If the resultant value matches with the crcExpectedValue, then the
application image passes the CRC check.
NOTE
See Section 2.3, "The Kinetis Bootloader Configuration Area
(BCA)", in the Kinetis Bootloader v2.0.0 Reference Manual for
details about the BCA.
The following steps describe the flow of execution of the Kinetis bootloader when
integrity check is enabled in the BCA.
• Load BCA data from flash at offset, corresponding to the application image start
address + 0x3C0.
• Initialize the CRC check status. If BCA is invalid (the tag is not set to expected
‘kcfg’ value), or the CRC parameters in valid BCA are not set, then the CRC check
status is set to kStatus_AppCrcCheckInvalid, meaning the integrity check is not
enabled for the device. Otherwise, the CRC check status is set to
kStatus_AppCrcCheckInactive, meaning the integrity check is due for the device.
• If a boot pin is not asserted and application address is a valid address (the address is
not null, the address resides in a valid executable memory range, and the flash is not
blank), then the bootloader begins the CRC check function. Otherwise, the CRC
check function is bypassed.
• The CRC check function. The bootloader checks the CRC check status initialized in
the previous steps, and if it is not kStatus_AppCrcCheckInvalid (integrity check is
enabled for the device), then the bootloader verifies the application resides in internal
flash or external QSPI flash.
a. If the application address range is invalid, then the bootloader sets the status to
kStatus_AppCrcCheckOutOfRange.
b. If the application address range is valid, then the CRC check process begins. If
the CRC check passes, then the bootloader sets the status to
kStatus_AppCrcCheckPassed. Otherwise, the status is set to
kStatus_AppCrcCheckFailed.
• If no active peripheral is found before the end of the detection, the timeout period
expires, and the current CRC check status is either set to
kStatus_AppCrcCheckInvalid (integrity check is not enabled for the device), or
kStatus_AppCrcCheckPassed. Then, the bootloader jumps to the application image.
Otherwise, the bootloader enters the active state and wait for commands from the
host.
The following table provides the CRC algorithm which is used for the application
integrity check. The CRC algorithm is the MPEG2 variant of CRC-32.
The bootloader computes the CRC over each byte in the application range specified in the
BCA, excluding the crcExpectedValue field in the BCA. In addition, Kinetis bootloader
automatically pads the extra byte(s) with zero(s) to finalize CRC calculation if the length
of the image is not 4-bytes aligned.
The following procedure shows the steps in CRC calculation.
1. CRC initialization
• Set the initial CRC as 0xFFFFFFFF, which clears the CRC byte count to 0.
2. CRC calculation
• Check if the crcExpectedValue field in BCA resides in the address range
specified for CRC calculation.
• If the crcExpectedValue does not reside in the address range, then compute
CRC over every byte value in the address range.
• If the crcExpectedValue does reside in the address range, then split the
address range into two parts, splitting at the address of crcExpectedValue
field in BCA excluding crcExpectedValue. Then, compute the CRC on the
two parts.
• Adjust the CRC byte count according to the actual bytes computed.
3. CRC finalization
• Check if the CRC byte count is not 4-bytes aligned. If it is 4-bytes aligned, then
pad it with necessary zeroes to finalize the CRC. Otherwise, return the current
computed CRC.
NOTE
Kinetis bootloader assumes that crcExpectedValue field (4
bytes) resides in the CRC address range completely if it borders
on the CRC address range.
3.1 Introduction
This section explains the general protocol for the packet transfers between the host and
the Kinetis bootloader. The description includes the transfer of packets for different
transactions, such as commands with no data phase and commands with incoming or
outgoing data phase. The next section describes various packet types used in a
transaction.
Each command sent from the host is replied to with a response command.
Commands may include an optional data phase.
• If the data phase is incoming (from the host to Kinetis bootloader ), it is part of the
original command.
• If the data phase is outgoing (from Kinetis bootloader to host), it is part of the
response command.
Notes
• The host may not send any further packets while it is waiting for the response to a
command.
• The data phase is aborted if the Generic Response packet prior to the start of the data
phase does not have a status of kStatus_Success.
• Data phases may be aborted by the receiving side by sending the final Generic
Response early with a status of kStatus_AbortDataPhase. The host may abort the
data phase early by sending a zero-length data packet.
• The final Generic Response packet sent after the data phase includes the status for
the entire operation.
Note
• The data phase is considered part of the response command for the outgoing data
phase sequence.
• The host may not send any further packets while the host is waiting for the response
to a command.
• The data phase is aborted if the ReadMemory Response command packet, prior to
the start of the data phase, does not contain the kCommandFlag_HasDataPhase flag.
• Data phases may be aborted by the host sending the final Generic Response early
with a status of kStatus_AbortDataPhase. The sending side may abort the data phase
early by sending a zero-length data packet.
• The final Generic Response packet sent after the data phase includes the status for
the entire operation.
4.1 Introduction
The Kinetis bootloader device works in slave mode. All data communication is initiated
by a host, which is either a PC or an embedded host. The Kinetis bootloader device is the
target, which receives a command or data packet. All data communication between host
and target is packetized.
NOTE
The term "target" refers to the "Kinetis bootloader device".
There are 6 types of packets used:
• Ping packet
• Ping Response packet
• Framing packet
• Command packet
• Data packet
• Response packet
All fields in the packets are in little-endian byte order.
Host Target
PingResponse Packet:
0x5a 0xa7 0x00 0x02 0x01 0x50 0x00 0x00 0xaa 0xea
The Ping Response packet can be sent from host to target any time the target expects a
command packet. For the UART peripheral, it must be sent by host when a connection is
first established, in order to run autobaud. For other serial peripherals it is optional, but
recommended to determine the serial protocol version. The version number is in the same
format at the bootloader version number returned by the GetProperty command.
A special framing packet that contains only a start byte and a packet type is used for
synchronization between the host and target.
Table 4-4. Special Framing Packet Format
Byte # Value Parameter
0 0x5A start byte
1 0xAn packetType
The Packet Type field specifies the type of the packet from one of the defined types
(below):
Table 4-5. packetType Field
packetType Name Description
0xA1 kFramingPacketType_Ack The previous packet was received successfully; the sending
of more packets is allowed.
0xA2 kFramingPacketType_Nak The previous packet was corrupted and must be re-sent.
0xA3 kFramingPacketType_AckAbort Data phase is being aborted.
0xA4 kFramingPacketType_Command The framing packet contains a command packet payload.
0xA5 kFramingPacketType_Data The framing packet contains a data packet payload.
0xA6 kFramingPacketType_Ping Sent to verify the other side is alive. Also used for UART
autobaud.
0xA7 kFramingPacketType_PingResponse A response to Ping; contains the framing protocol version
number and options.
The check result is computed by running the ASCII character sequence "123456789"
through the algorithm.
uint16_t crc16_update(const uint8_t * src, uint32_t lengthInBytes
{
uint32_t crc = 0;
uint32_t j;
for (j=0; j < lengthInBytes; ++j)
{
uint32_t i;
uint32_t byte = src[j];
crc ^= byte << 8;
for (i = 0; i < 8; ++i)
{
uint32_t temp = crc << 1;
if (crc & 0x8000)
{
temp ^= 0x1021;
}
crc = temp;
}
}
return crc;
}
The header is followed by 32-bit parameters up to the value of the ParameterCount field
specified in the header. Because a command packet is 32 bytes long, only 7 parameters
can fit into the command packet.
Command packets are also used by the target to send responses back to the host. As
mentioned earlier, command packets and data packets are embedded into framing packets
for all of the transfers.
Table 4-8. Command Tags
Command Tag Name
0x01 FlashEraseAll The command tag specifies one of the
commands supported by the Kinetis
0x02 FlashEraseRegion
bootloader. The valid command tags for the
0x03 ReadMemory Kinetis bootloader are listed here.
0x04 WriteMemory
0x05 FillMemory
0x06 FlashSecurityDisable
0x07 GetProperty
0x08 Reserved
0x09 Execute
0x10 FlashReadResource
0x11 Reserved
0x0A Call
0x0B Reset
0x0C SetProperty
0x0D FlashEraseAllUnsecure
0x0E FlashProgramOnce
0x0F FlashReadOnce
0x10 FlashReadResource
0x11 ConfigureQuadSPI
0x12 ReliableUpdate
Flags: Each command packet contains a Flag byte. Only bit 0 of the flag byte is used. If
bit 0 of the flag byte is set to 1, then data packets follow in the command sequence. The
number of bytes that are transferred in the data phase is determined by a command-
specific parameter in the parameters array.
ParameterCount: The number of parameters included in the command packet.
Parameters: The parameters are word-length (32 bits). With the default maximum
packet size of 32 bytes, a command packet can contain up to 7 parameters.
The parameter count field in the header is set to greater than 1, to always include the
status code and one or many property values.
5.1 Introduction
All Kinetis bootloader command APIs follows the command packet format wrapped by
the framing packet as explained in previous sections.
See Table 4-8 for a list of commands supported by Kinetis bootloader.
For a list of status codes returned by Kinetis bootloader see Appendix A.
Host Target
ACK:
0x5a a1
Process command
Generic Response:
0x5a a4 0c 00 07 7a a7 00 00 02 00 00 00 00 00 00 01 4b
ACK:
0x5a a1
Host Target
ACK :
0x5a a1
Process command
GenericResponse:
0x5a a4 00 9e 10 a0 00 0c 02 00 00 00 00 0c 00 00 00
ACK:
0x5a a1
Response: The target returns a GenericResponse packet with one of following status
codes:
Table 5-6. SetProperty Response Status Codes
Status Code
kStatus_Success
kStatus_ReadOnly
kStatus_UnknownProperty
kStatus_InvalidArgument
FlashEraseAll
0x5a a4 08 00 0c 22 01 00 00 01 00 00 00 00
ACK:
0x5a a1
Process command
Generic Response:
0x5a a4 0c 00 66 ce a0 00 00 02 00 00 00 00 01 00 00 00
ACK:
0x5a a1
Response: The target returns a GenericResponse packet with status code either set to
kStatus_Success for successful execution of the command, or set to an appropriate error
status code.
Host Target
FlashEraseAllUnsecure
0x5a a4 04 00 f6 61 0d 00 cc 00
ACK:
0x5a a1
Process command
Generic Response:
0x5a a4 0c 00 61 2c a0 00 04 02 00 00 00 00 0d 00 00 00
ACK:
0x5a a1
Response: The target returns a GenericResponse packet with status code either set to
kStatus_Success for successful execution of the command, or set to an appropriate error
status code.
NOTE
When the MEEN bit in the NVM FSEC register is cleared to
disable the mass erase, the FlashEraseAllUnsecure command
will fail. FlashEraseRegion can be used instead skipping the
protected regions.
Data Phase: The ReadMemory command has a data phase. Because the target works in
slave mode, the host needs to pull data packets until the number of bytes of data specified
in the byteCount parameter of ReadMemory command are received by host.
Response: The target returns a GenericResponse packet with a status code either set to
kStatus_Success upon successful execution of the command, or set to an appropriate
error status code.
Host Target
ACK: 0x5a a1
Process command
Generic Response:
0x5a a4 0c 00 a0 0e 04 01 00 02 00 04 00 20 40 00 00 00
ACK: 0x5a a1
Data packet :
0x5a a5 20 00 CRC16 32 bytes data
Process Data
ACK: 0x5a a1
ACK: 0x5a a1
Data Phase: The WriteMemory command has a data phase; the host sends data packets
until the number of bytes of data specified in the byteCount parameter of the
WriteMemory command are received by the target.
Response: The target returns a GenericResponse packet with a status code set to
kStatus_Success upon successful execution of the command, or to an appropriate error
status code.
• To fill with a byte pattern (8-bit), the byte must be replicated 4 times in the 32-bit
pattern.
• To fill with a short pattern (16-bit), the short value must be replicated 2 times in the
32-bit pattern.
For example, to fill a byte value with 0xFE, the word pattern is 0xFEFEFEFE; to fill a
short value 0x5AFE, the word pattern is 0x5AFE5AFE.
Special care must be taken when writing to flash.
• First, any flash sector written to must have been previously erased with a
FlashEraseAll, FlashEraseRegion, or FlashEraseAllUnsecure command.
• First, any flash sector written to must have been previously erased with a
FlashEraseAll or FlashEraseRegion command.
• Writing to flash requires the start address to be 4-byte aligned ([1:0] = 00).
• If the VerifyWrites property is set to true, then writes to flash also performs a flash
verify program operation.
When writing to RAM, the start address does not need to be aligned, and the data is not
padded.
Host Target
ACK:
0x5a a1
Host Target
ACK:
0x5a a1
Process command
Generic Response:
0x5a a4 0c 00 35 78 a0 00 0c 02 00 00 00 00 06 00 00 00
ACK:
0x5a a1
Response: The target returns a GenericResponse packet with a status code either set to
the return value of the function called or set to kStatus_InvalidArgument (105).
Host Target
Reset
0x5a a4 04 00 6f 46 0b 00 00 00
ACK :
0x5a a1
Process command
GenericResponse:
0x5a a4 0c 00 f8 0b a 0 00 04 02 00 00 00 00 0b 00 00 00
ACK:
0x5a a1
The reset command can also be used to switch boot from flash after successful flash
image provisioning via ROM bootloader. After issuing the reset command, allow 5
seconds for the user application to start running from Flash.
Host Target
ACK:
0x5a a1
Response: upon successful execution of the command, the target (Kinetis bootloader)
returns a GenericResponse packet with a status code set to kStatus_Success, or to an
appropriate error status code.
Host Target
ACK:
0x5a a1
Host Target
Data packet
5a a5 08 00 9c d3 00 08 00 00 00 01 00 06
Process Data
ACK: 0x5a a1
Generic Response
5a a4 0c 00 75 a3 a0 00 00 02 00 00 00 00 10 00 00 00
ACK: 0x5a a1
Data phase: The FlashReadResource command has a data phase. Because the target
(Kinetis bootloader) works in slave mode, the host must pull data packets until the
number of bytes of data specified in the byteCount parameter of FlashReadResource
command are received by the host.
Data Phase: The Receive SB file command has a data phase; the host sends data packets
until the number of bytes of data specified in the byteCount parameter of the Receive SB
File command are received by the target.
Response: The target returns a GenericResponse packet with a status code set to the
kStatus_Success upon successful execution of the command, or set to an appropriate
error code.
Response: The target returns a GenericResponse packet with a status code either set to
kStatus_Success upon successful execution of the command, or set to an appropriate
error status code.
6.1 Introduction
This section describes the peripherals supported by the Kinetis bootloader. To use an
interface for bootloader communications, the peripheral must be enabled in the BCA. If
the BCA is invalid (such as all 0xFF bytes), then all peripherals are enabled by default.
• An outgoing packet is read by the host with a selected I2C slave address and the
direction bit is set as read.
• 0x00 is sent as the response to host if the target is busy with processing or preparing
data.
The following flow charts demonstrate the communication flow of how the host reads
ping packet, ACK and response from the target.
Fetch
Ping response End
No Yes
Figure 6-1. Host reads ping response from target via I2C
No
No
Yes Yes
Figure 6-2. Host reads ACK packet from target via I2C
Fetch
Response End
Read 1 byte
No from target Read
payload data
from target
Reached 0x5A
maximum No Yes
received?
retries?
Yes
Payload length Set payload length
Read 1 byte less than supported No to maximum
from target length? supported length
Yes
Read Read
Report a timeout 0xA4 payload length CRC checksum
received? Yes part from target
error (End) from target
(2 bytes) (2 bytes)
No
The table below provides reference to the expected performance of write speeds to Flash
and RAM memories using Kinetis bootloader I2C interface. The numbers have been
measured on a number of platforms running Kinetis bootloader either from ROM or the
RAM (for flashloaders).
Table 6-1. Performance numbers for I2C
I2C Bus Flash Average Writing Speed (KB/s) Ram
Frequen Average
cy Writing
(KHz) Speed
(KB/s)
KL27 KL28 KL43 KL80 K80 KL03 KL27 KL28 KL43 KL80 K80 KL03
100 6.42 6.29 6.42 6.7 6.39 6.08 7.67 7.27 7.7 7.91 7.38 6.13
200 10.24 10.08 10.13 10.58 9.82 8.75 14.02 13.25 13.78 14.15 13.43 10.1
300 12.86 11.84 11.95 13.11 11.85 9.69 18.04 17.51 17.92 18.98 17.61 11.9
400 15.54 14.06 14.39 14.74 13.44 10.24 23.2 22.39 21.82 24.19 22.04 12.82
500 15.86 16.13 15.96 16.94 14.65 - 24.61 27.9 26.5 30.26 26.93 -
600 18.14 16.51 16.4 17.19 15.19 - 29.44 28.64 27.05 30.96 27.57 -
800 19.5 - 18.51 19.22 16.26 - 34.44 - 33.38 38.36 32.72 -
1000 20.48 - 20.03 21.35 17.71 - 37.64 - 41.04 45.38 33.65 -
NOTE
1. Every test covers all flash or RAM region with 0x0 - 0xf.
2. Run every test three times and calculate the average.
Fetch End
Ping response
No Yes
Send 0x00 to
0x5A 0xA7 Report Error
received? Yes shift out 1 byte received? No
from target
Figure 6-6. Host reads ping packet from target via SPI
No
Send 0x00 to
No shift out 1 byte Process NAK Yes 0xA2
received?
from target
No
Reached
maximum No
retries? Send 0x00 to
0x5A 0xA1
received? Yes shift out 1 byte
received?
from target
Yes
Report a
Next action Yes
timeout error
Send 0x00 to
No shift out 1 byte
from target Write 0x00s to shift
out payload data
from target
Reached 0x5A
maximum No Yes
received?
retries?
Yes
Payload length Set payload length
Send 0x00 to less than supported No to maximum
shift out 1 byte length? supported length
Yes from target
The table below provides reference to the expected performance of write speeds to Flash
and RAM memories using Kinetis bootloader SPI interface. The numbers have been
measured on a number of platforms running Kinetis bootloader either from ROM or the
RAM (for flashloaders).
Table 6-2. Performance numbers SPI
SPI Bus Flash Average Writing Speed (KB/s) Ram
Frequen Average
cy Writing
(KHz) Speed
(KB/s)
KL27 KL28 KL43 KL80 K80 KL03 KL27 KL28 KL43 KL80 K80 KL03
100 7.07 7.46 7.24 6.74 6.71 6.20 8.60 9.25 9.01 8.46 8.04 6.80
200 11.45 12.26 11.88 11.53 10.18 8.87 15.23 17.98 17.04 16.17 14.19 10.64
300 13.84 15.17 14.70 15.08 12.42 - 19.91 25.11 23.06 24.65 18.79 -
400 16.42 18.09 17.23 16.91 13.74 - 25.89 32.95 31.15 28.89 23.95 -
500 18.26 19.82 18.17 18.94 14.98 - 31.47 40.10 36.61 36.61 27.83 -
600 18.72 20.72 19.98 20.63 15.21 - 32.40 44.98 40.96 42.26 27.67 -
800 21.19 22.06 22.27 22.04 16.11 - 39.83 50.00 51.54 49.98 30.15 -
1000 22.07 23.74 23.80 22.92 15.99 - 45.83 61.19 55.92 56.34 29.11 -
NOTE
1. Every test covers all flash or RAM region with 0x0 - 0xf.
2. Run every test three times and calculate the average.
Wait
Report an error
for ACK
No
No
Reached
maximum No 0x5A Yes Wait for 1 byte 0xA1
received? from target received?
retries?
Yes
Yes
Wait for
End
ping response
Wait for
remaining bytes
Wait for 1 byte
from target of ping response
packet
No Yes
Figure 6-12. Host reads a ping response from target via UART
Wait
End
for response
Reached 0x5A
maximum No Yes
received?
retries?
Yes
Payload length Set payload length
less than supported No to maximum
Wait for 1 byte length? supported length
Yes from target
Figure 6-13. Host reads a command response from target via UART
The table below provides reference to the expected performance of write speeds to Flash
and RAM memories using Kinetis bootloader SPI interface. The numbers have been
measured on a number of platforms running Kinetis bootloader either from ROM or the
RAM (in case of flashloaders).
UART Flash Average Writing Speed (KB/s) Ram
Baud Avera
Rate ge
Writin
g
Speed
(KB/s)
KL27 KL28 KL43 KL80 K80 KL03 KS22 KL27 KL28 KL43 KL80 K80 KL03 KS22
19200 1.47 1.47 1.43 1.47 1.46 1.43 1.45 1.51 1.52 1.48 1.52 1.52 1.49 1.51
38400 2.81 2.82 2.75 2.82 2.79 2.81 2.75 2.99 3.03 2.95 3.03 3.03 2.9 3.00
57600 4.07 4.07 3.97 4.08 4.01 - 3.93 4.46 4.53 4.4 4.54 4.51 - 4.47
11520 7.3 7.31 7.12 7.35 7.1 - 6.88 8.69 8.97 8.65 8.98 8.85 - 8.73
0
23040 12.14 - 11.83 12.27 11.42 - 11.01 16.57 - 16.77 17.58 16.73 - 16.65
0
Default 48 48 48 48 48 8 48 48 48 48 48 48 8 48
core
Freque
ncy
(MHz)
Default 24 24 24 24 24 4 24 24 24 24 24 24 4 24
bus
Freque
ncy
(MHz)
NOTE
1. Every test covers all flash or RAM region with 0x0 - 0xf.
2. Run every test three times and calculate the average.
usbPid(BCA + 0x16) field of the BCA in flash. To change the USB strings, prepare a
structure (like the one shown below) in the flash, and then write the address of the
structure to the usbStringsPointer(BCA + 0x18) field of the BCA.
g_languages = { USB_STR_0,
sizeof(USB_STR_0),
(uint_16)0x0409,
(const uint_8 **)g_string_descriptors,
g_string_desc_size};
the USB_STR_0, g_string_descriptors and g_string_desc_size are defined as below.
USB_STR_0[4] = {0x02,
0x03,
0x09,
0x04
};
g_string_descriptors[4] =
{ USB_STR_0,
USB_STR_1,
USB_STR_2,
USB_STR_3};
g_string_desc_size[4] =
{ sizeof(USB_STR_0),
sizeof(USB_STR_1),
sizeof(USB_STR_2),
sizeof(USB_STR_3)};
USB_STR_1[] =
{ sizeof(USB_STR_1),
USB_STRING_DESCRIPTOR,
'F',0,
'r',0,
'e',0,
'e',0,
's',0,
'c',0,
'a',0,
'l',0,
'e',0,
' ',0,
'S',0,
'e',0,
'm',0,
'i',0,
'c',0,
'o',0,
'n',0,
'd',0,
'u',0,
'c',0,
't',0,
'o',0,
'r',0,
' ',0,
'I',0,
'n',0,
'c',0,
USB_STR_2[] =
{ sizeof(USB_STR_2),
USB_STRING_DESCRIPTOR,
'M',0,
'K',0,
' ',0,
'M',0,
'a',0,
's',0,
's',0,
' ',0,
'S',0,
't',0,
'o',0,
'r',0,
'a',0,
'g',0,
'e',0
};
USB_STR_3[] =
{ sizeof(USB_STR_3),
USB_STRING_DESCRIPTOR,
'0',0,
'1',0,
'2',0,
'3',0,
'4',0,
'5',0,
'6',0,
'7',0,
'8',0,
'9',0,
'A',0,
'B',0,
'C',0,
'D',0,
'E',0,
'F',0
};
6.5.2 Endpoints
The HID peripheral uses 3 endpoints:
• Control (0)
• Interrupt IN (1)
• Interrupt OUT (2)
The Interrupt OUT endpoint is optional for HID class devices, but the Kinetis bootloader
uses it as a pipe, where the firmware can NAK send requests from the USB host.
Each report has a maximum size of 34 bytes. This is derived from the minimum
bootloader packet size of 32 bytes, plus a 2-byte report header that indicates the length (in
bytes) of the packet sent in the report.
NOTE
In the future, the maximum report size may be increased, to
support transfers of larger packets. Alternatively, additional
reports may be added with larger maximum sizes.
The actual data sent in all of the reports looks like:
0 Report ID
1 Packet Length LSB
2 Packet Length MSB
3 Packet[0]
4 Packet[1]
5 Packet[2]
...
N+3-1 Packet[N-1]
This data includes the Report ID, which is required if more than one report is defined in
the HID report descriptor. The actual data sent and received has a maximum length of 35
bytes. The Packet Length header is written in little-endian format, and it is set to the size
(in bytes) of the packet sent in the report. This size does not include the Report ID or the
Packet Length header itself. During a data phase, a packet size of 0 indicates a data phase
abort request from the receiver.
g_usb_str_1,
g_usb_str_2,
g_usb_str_3,
g_usb_str_n };
usb_language_t g_usb_lang[USB_LANGUAGE_COUNT] = { {
6.6.2 Endpoints
USB MSC device uses 2 endpoints, in addition to the default pipe that is required by USB HID
device
#define USB_MSC_BULK_IN_ENDPOINT (3), which
#define USB_MSC_BULK_OUT_ENDPOINT (4)
Figure 6-16. Host reads ping response from target via FlexCAN
Figure 6-17. Host reads ACK packet from target via FlexCAN
Figure 6-18. Host reads command response from target via FlexCAN
1. If parallel mode is enabled, then page size and sector size must be twice the actual size.
2. These fields are effective only if “need_multi_phase” field is set to 1.
NOTE
It is recommended to configure QSPI to SDR mode with one
QCB during the program and switch to DDR mode with
another QCB after the program completes, where it is possible
to achieve higher program performance with the Kinetis
bootloader.
6.8.2 Look-up-table
The look-up table (LUT) is a part of the QCB, and contains sequences for instructions,
such as read and write instructions. The Kinetis Bootloader defines LUT entries to
support erase, program and read operations.
NOTE
The sequence in each LUT entry is target-specific. See the
datasheet or reference manual of the corresponding serial flash
device.
Table 6-4. Look-up table entries for bootloader
Index Field Description
0 Read Sequence for read instructions
1 WriteEnable Sequence for WriteEnable instructions
2 EraseAll Sequence for EraseAll instructions
3 ReadStatus Sequence for ReadStatus instructions
4 PageProgram Sequence for Page Program instructions
6 PreErase1 Sequence for Pre-Erase instructions
7 SectorErase Sequence for Sector Erase
8 Dummy Sequence for dummy operation if needed.
For example, if continuous read is configured in index 0, then the dummy LUT
should be configured to force the external SPI flash to exit continuous read
mode.
If a dummy operation is not required, then this LUT entry must be set to 0.
9 PreWriteEnable1 Sequence for Pre-WriteEnable instructions
10 PrePageProgram1 Sequence for Pre-PageProgram instructions
11 PreReadStatus1 Sequence for Pre-ReadStatus instructions
5, 12, 13, 14, Undefined1 All of these sequences are free to be used for other purpose. For example,
15 index 5 can be used for enabling Quad mode of SPI flash devices, see
Section 3.3.2 for more details.
1. If these LUT entries are are not required, then they are allowed to be used for other purposes.
NOTE
For most types of SPI flash devices available in the market,
only index 0, 1, 3, 4, 7, and 8 are required. However, for other
types of high-end SPI flash devices, i.e., Cypress Hyperflash,
additional indexes listed above may be required.
NOTE
The user application boot from QuadSPI in XIP mode should
not change the QuadSPI source clock from what ROM has
configured (as shown in the previous table); otherwise a hard
fault may occur. However, the QuadSPI source clocks (listed in
⁄⁄ Seq8: Dummy
⁄*
CMD: 0 - Dummy command, used to force SPI flash to exit continuous
read mode.
unnecessary here because the continuous read mode is not enabled.
*⁄
[32] = 0,
},
};
7.1 Introduction
The block diagram shows connections between components in the architecture of the
peripheral interface.
In this diagram, the byte and packet interfaces are shown to inherit from the control
interface.
All peripheral drivers implement an abstract interface built on top of the driver's internal
interface. The outermost abstract interface is a packet-level interface. It returns the
payload of packets to the caller. Drivers which use framing packets have another abstract
interface layer that operates at the byte level. The abstract interfaces allow the higher
layers to use exactly the same code regardless which peripheral is being used.
The abstract packet interface feeds into the command and data packet processor. This
component interprets the packets returned by the lower layer as command or data
packets.
This control interface provides a common method to initialize and shutdown peripheral
drivers. It also provides the means to perform the active peripheral detection. No data
transfer functionality is provided by this interface. That is handled by the interfaces that
inherit the control interface.
The main reason this interface is separated out from the byte and packet interfaces is to
show the commonality between the two. It also allows the driver to provide a single
control interface structure definition that can be easily shared.
struct PeripheralDescriptor {
//! @brief Bit mask identifying the peripheral type.
//!
//! See #_peripheral_types for a list of valid bits.
uint32_t typeMask;
struct PeripheralControlInterface
{
bool (*pollForActivity)(const PeripheralDescriptor * self);
status_t (*init)(const PeripheralDescriptor * self, BoatloaderInitInfo * info);
void (*shutdown)(const PeripheralDescriptor * self);
This interface exists to give the framing packetizer, which is explained in the later
section, a common interface for the peripherals that use framing packets.
NOTE
The byte interface has no read() member. Interface reads are
performed in an interrupt handler at the packet level.
• The CBW begins on a packet boundary, and ends as a short packet. Exactly 31 bytes
are transferred.
• The CSW begins on a packet boundary, and ends as a short packet. Exactly 13 bytes
are transferred.
• The data packet begins on a packet boundary, and ends as a short packet. Exactly 64
bytes are transferred.
The global bootloader context contains a pointer to the high-level abstract memory
interface, which is one of the MemoryInterface structures. The internal implementation of
this abstract interface uses a memory map table, referenced from the global bootloader
context that describes the various regions of memory that are accessible and provides
region-specific operations.
The high-level functions are implemented to iterate over the memory map entries until it
finds the entry for the specified address range. Read and write operations are not
permitted to cross region boundaries, and an error is returned if such an attempt is made.
The BootloaderContext::memoryMap member is set to an array of these structures:
struct MemoryMapEntry
{
uint32_t startAddress;
uint32_t endAddress;
bool isExecutable;
const MemoryInterface * interface;
};
This array must be terminated with an entry with all fields set to zero.
The same MemoryInterface structure is also used to hold the memory-type-specific
operations.
Note that the MemoryMapEntry::endAddress field must be set to the address of the last
byte of the region, because a <= comparison is used.
During bootloader startup, the memory map is copied into RAM and modified to match
the actual sizes of flash and RAM on the chip.
The flash driver uses the common memory interface to simplify the interaction with flash.
It takes care of high level features such as read back verification, flash protection
awareness, and so on. The flash memory functions map to the interface functions as so:
const memory_region_interface_t g_flashMemoryInterface = {
.read = &flash_mem_read,
.write = &flash_mem_write,
.fill = &flash_mem_fill,
.flush = NULL,
.erase = flash_mem_erase
};
9.1 Introduction
The main purpose of these APIs is to simplify the use of flash driver APIs exported from
Kinetis bootloader ROM. With APIs, the user does not need to care about the differences
among various version of flash drivers.
A set of parameters are required to ensure all APIs work properly.
This section describes how to use each flash driver API proivded in the Kinetis flash
driver API tree.
For all flash driver APIs require the driver parameter.
There are three versions of the flash driver API among different targets with ROM
bootloader. See the following table for more details.
Table 9-1. Different versions of the flash driver
Flash driver API version Supported targets
V1.0 KL03Z4, KL43Z4, KL33Z4, KL27Z4, KL17Z4
V1.1 KL27Z644, KL17Z644
V1.2 KL13Z644, KL33Z644, K80F256, K81F256, K82F256,
KL81Z7, KL82Z7, KL28Z7
There are minor differences in the flash driver interface among the above three versions.
See the definitions below for details.
typedef union BootloaderVersion
{
struct
{
#if defined(FLASH_API_TREE_1_0)
status_t (*flash_erase_all)(flash_config_t *config);
status_t (*flash_erase_all_unsecure)(flash_config_t *config);
status_t (*flash_erase)(flash_config_t *config, uint32_t start, uint32_t
lengthInBytes);
#else
status_t (*flash_erase_all)(flash_config_t *config, uint32_t key);
status_t (*flash_erase_all_unsecure)(flash_config_t *config, uint32_t key);
status_t (*flash_erase)(flash_config_t *config, uint32_t start, uint32_t
lengthInBytes, uint32_t key);
#endif
Example code to receive the enter pointer address from the ROM and access the flash
driver API:
flash_config_t flashContext;
const flash_driver_interface_t *s_flashInterface;
s_flashInterface = (const flash_driver_interface_t *)(*(uint32_t**)
0x1c00001c)[4];s_flashInstance->flash_init(&flashContext);
The details for usage of each API are mentioned in the following sections. Example
codes are also provided along with the Kinetis_Bootloader_1.2 or
Kinetis_Bootloader_2.0 release package.
9.3.1 flash_config_t
The flash_config_t data structure is a required argument for all flash driver API
functions. flash_config_t can be initialized by calling FLASH_Init. For other functions,
an initialized instance of this data structure should be passed as an argument.
Table 9-2. flash_driver_t data structure
Offset Size Field Description
0 4 PFlashBlockBase Base address of the first PFlash block
4 4 PFlashTotalSize Size of all combined PFlash blocks
8 4 PFlashBlockCount Number of PFlash blocks
12 4 PFlashSectorSize Size (in bytes) of sector of PFlash
16 4 PFlashCallback Pointer to a callback function used to do extra operations
during erasure (for example, service watchdog)
20 4 PFlashAccessSegmentSize Size of FAC access segment
24 4 PFlashAccessSegmentCount Count of FAC access segment
9.4.1 FLASH_Init
Checks and initializes the flash module for the other flash API functions.
NOTE
FLASH_Init must be always called before calling other API
functions.
Prototype:
status_t FLASH_Init(flash_config_t *config);
Example:
flash_config_t flashInstance;
status_t status = FLASH_Init(&flashInstance);
9.4.2 FLASH_EraseAll
Example:
status_t status = FLASH_EraseAll(&flashInstance, kFLASH_ApiEraseKey);
9.4.3 FLASH_EraseAllUnsecure
Erases the entire flash (including protected sectors) and restores flash to unsecured mode.
Kinetis Bootloader v2.0.0 Reference Manual, Rev. 0, 04/2016
Freescale Semiconductor, Inc. 115
Flash driver API
Prototype:
status_t FLASH_EraseAllUnsecure(flash_config_t *config, uint32_t key);
Example:
status_t status = FLASH_EraseAllUnsecure(&flashInstance, kFLASH_ApiEraseKey);
9.4.4 FLASH_Erase
Erases expected flash sectors specified by parameters. For Kinetis devices, the minimum
erase unit is one sector.
Prototype:
status_t FLASH_Erase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t
key);
Example:
status_t status = FLASH_Erase (&flashInstance, 0x800, 1024, kFLASH_ApiEraseKey);
9.4.5 FLASH_Program
Programs the flash memory with data at locations that are passed in using parameters.
Prototype:
status_t FLASH_Program(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t
lengthInBytes);
Example:
uint32_t m_content[] = {0x01234567, 0x89abcdef};
status_t status = FLASH_Program (&flashInstance, 0x800, &m_content[0], sizeof(m_content));
NOTE
Before calling flash_program, make sure that the region to be
programmed is empty and is not protected.
9.4.6 FLASH_GetSecurityState
Retrieves the current flash security status, including the security enabling state and the
backdoor key enabling state.
Prototype:
status_t FLASH_GetSecurityState(flash_config_t *config, flash_security_state_t *state);
Example:
flash_security_state_t state;
status_t status = FLASH_GetSecurityState (&flashInstance, &state);
9.4.7 FLASH_SecurityBypass
Allows the user to bypass security with a backdoor key. If the MCU is in a secured state,
then the FLASH_SecurityBypass function unsecures the MCU, by comparing the
provided backdoor key with keys in the Flash Configuration Field.
Prototype:
status_t FLASH_SecurityBypass(flash_config_t *config, const uint8_t *backdoorKey);
Example:
Assume that the flash range from 0x400 to 0x40c contains the following content after the
last reset, which means that the backdoor key is valid and the backdoor key access has
been enabled.
0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0xff 0xff 0xff 0xbf
uint8_t backdoorKey[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
status_t status = FLASH_SecurityBypass (&flashInstance, & backdoorKey[0]);
9.4.8 FLASH_VerifyEraseAll
Checks if the entire flash has been erased to the specified read margin level.
Kinetis Bootloader v2.0.0 Reference Manual, Rev. 0, 04/2016
Freescale Semiconductor, Inc. 119
Flash driver API
To verify if the entire flash has been fully erased (after executing an FLASH_EraseAll),
call FLASH_VerifyEraseAll.
Prototype:
status_t FLASH_VerifyEraseAll(flash_config_t *config, flash_margin_value_t margin);
Example:
Assume that flash_erase_all has been successfully executed.
status_t status = flash_verify_erase_all (&flashInstance, kFLASH_MarginValueUser);
NOTE
For the choice of margin, see the FTFA chapter in the reference
manual for detailed information.
9.4.9 FLASH_VerifyErase
Verifies the erasure of the desired flash area at a specified margin level. This function
checks the appropriate number of flash sectors based on the desired start address and
length, to see if the flash has been erased at the specified read margin level.
FLASH_VerifyErase is often called after successfully performing the FLASH_Erase
API.
Prototype:
Example:
Assume that flash region from 0x800 to 0xc00 has been successfully erased.
status_t status = FLASH_VerifyErase(&flashInstance, 0x800, 1024, kFLASH_MarginValueUser);
NOTE
For the choice of margin, see the FTFA chapter in the reference
manual for detailed information.
9.4.10 FLASH_VerifyProgram
Verifies the data programmed in the flash memory (using the Flash Program Check
Command), and compares it with expected data for a given flash area (as determined by
the start address and length).
FLASH_VerifyProgram is often called after successfully doing FLASH_Program().
Prototype:
status_t FLASH_VerifyProgram(flash_config_t *config,
uint32_t start,
uint32_t lengthInBytes,
const uint32_t *expectedData,
flash_margin_value_t margin,
uint32_t *failedAddress,
uint32_t *failedData);
Example:
Assume that flash region from 0x800 to 0x807 is successfully programmed with:
0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef
NOTE
For the choice of margin, see the FTFA chapter in the reference
manual for detailed information.
9.4.11 FLASH_GetProperty
Returns the desired flash property, which includes base address, sector size, and other
options.
Prototype:
status_t flash_get_property(flash_driver_t * driver, flash_property_t whichProperty, uint32_t
* value);
Value Pointer to the value returned for the desired flash property.
Example:
uint32_t propertyValue;
status_t status = FLASH_GetProperty (&flashInstance, kFLASH_PropertyPflashSectorSize,
&propertyValue);
9.4.12 FLASH_ProgramOnce
Programs a certain Program Once Field with the expected data for a given IFR region (as
determined by the index and length).
• For each Program Once Field, FLASH_ProgramOnce can only allowed to be called
once; otherwise, an error code is returned.
• For targets which do not support FLASH_ProgramOnce, the value of the
FLASH_ProgramOnce pointer is 0.
Prototype
status_t flash_program_once (flash_driver_t * driver, uint32_t index, uint32_t *src, uint32_t
lengthInBytes);
Example:
Assume the Program Once Field has not been programmed before.
uint32_t expectedData = 0x78563412;
NOTE
For the choice of index and length, see the FTFA chapter in RM
for detailed information.
9.4.13 FLASH_ReadOnce
Reads a certain flash Program Once Field according to parameters passed by index and
length.
For targets that do not support FLASH_ReadOnce, the value of the FLASH_ReadOnce
pointer is 0.
Prototype:
status_t flash_read_once (flash_driver_t * driver, uint32_t index, uint32_t *dst, uint32_t
lengthInBytes);
Example:
NOTE
For the choice of index and length, see the FTFA chapter in RM
for detailed information.
9.4.14 FLASH_ReadResource
Reads certain regions of IFR determined by the start address, length, and option.
For targets that do not support FLASH_ReadResource, the value of the
FLASH_ReadResource pointer is 0.
Prototype:
status_t FLASH_ReadResource(
flash_config_t *config, uint32_t start, uint32_t *dst, uint32_t lengthInBytes,
flash_read_resource_option_t option);
Example:
uint32_t temp[256];
status_t status = FLASH_ReadResource(&flashInstance, 0, &temp[0], 256, 0);
NOTE
See the FTFA chapter in RM for detailed information regarding
the start, length, and option choices.
9.4.15 FLASH_SetCallback
Registers expected callback functions into the flash driver, for example, like a function
for servicing a watchdog.
Prototype:
status_t FLASH_SetCallback(flash_config_t *config, flash_callback_t callback);
Example:
Assume that there is a function.
void led_toggle(void).
status_t status = FLASH_SetCallback(&flashInstance, led_toggle);
The directory which contains fsl_flash.h should be added to include path. This image
provides an example.
For detailed information, see the demos for KL03, KL43, and KL27. Both fsl_flash.h and
fsl_flash_api_tree.c are attached in the demos.
10.1 Introduction
This chapter discusses the steps required to port the Kinetis bootloader to an unsupported
Kinetis MCU. Each step of the porting process is discussed in detail in the following
sections.
All references to paths in the rest of this chapter are relative to the root of the extracted
Kinetis bootloader package. The container folder is named
FSL_Kinetis_Bootloader_<version>. Before modifying source code, the following tasks
should be performed.
The most manual process in porting the bootloader to a new target is editing the device
header files. This process is very time consuming and error prone, so NXP provides
CMSIS-compatible packages for all Kinetis devices that contain bootloader-compatible
device header files. These packages can be found on the product page for the MCU.
NOTE
It is not recommended to proceed with a port if a package does
not yet exist for the desired target MCU.
In the downloaded package, locate the folder with the header files. The folder is named
after the MCU (for example, “MK64F12”) and contains a unique header file for each
peripheral in addition to system_<device>.h files. Copy the entire folder into the /src/
platform/devices folder of the bootloader tree.
Copy the folder of the MCU that most closely matches the target MCU in the /targets
folder of the bootloader source tree. Rename it to coincide with the target MCU part
number.
Once the files are copied, browse the newly created folder. Rename all files that have
reference to the device from which they were copied. The following files need to be
renamed:
• clock_config_<old_device>.c —> clock_config_<new_device>.c
• hardware_init_<old_device>.c —> hardware_init _<new_device>.c
• memory_map_<old_device>.c —> memory_map _<new_device>.c
• peripherals_<old_device>.c —> peripherals _<new_device>.c
The following files should be copied from their location in /src/platform/devices/
<device> to the new /targets/<device>/src/startup folder:
• system_<device>.c
• system_<device>.h
• <tool chain>/startup_<device>.s
A device-specific startup file is a key piece to the port. The bootloader may not function
correctly without the correct vector table. A startup file from the closest match MCU can
be used as a template, but it is strongly recommended that the file be thoroughly checked
before using it in the port due to differences in interrupt vector mappings between Kinetis
devices.
The startup file should be created and placed into the /targets/<device>/src/startup/<tool
chain> folder. Startup files are always assembly (*.s) and are named startup_<device>.s.
NOTE
The 16-byte Flash Configuration Field should be carefully set
in the bootloader image. The Flash Configuration Field is
placed at the offset 0x400 in the bootloader image. The field is
documented in the SOC reference manual under a the
subsection "Flash Configuration Field" of the "Flash Memory
Module" chapter. To change the default 16-byte value for the
field in the template startup_<device>.s file of the bootloader
project, the following steps are needed:
1. Open the startup_<device>.s file in a text editor.
2. Locate the symbol where Flash Configuration Field is
specified. The symbol name is "__FlashConfig" The 16-
byte Flash Configuration Field data is enclosed with
__FlashConfig and __FlashConfig_End symbols in the
startup_<device>.s file
3. Change the 16-byte value to the desired data. For example
set the flash security byte, enable or disable backdoor
access key, specify the 8-byte backdoor key, and so on.
4. Once the field is updated, save the startup_<device>.s file
and close the text editor.
This example uses the IAR tool chain for the new project. Other supported tool chains
can be used in a similar manner.
The folder copy performed in step 1.2.2 copies more than just source code files. Inside of
the newly created /targets/<device> folder, locate the IAR workspace file
(bootloader.eww) and open it. This image shows an example of what a workspace looks
like and the files that need to be touched.
Once changes have been made, update the project to reference the target MCU. This can
be found in the project options.
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.
The linker file needs to be replaced if the memory configuration of the target MCU
differs from the closest match. This is done in the linker settings, which is also part of the
project options.
There are two steps required to enable and configure the desired peripherals on the target
MCU:
• Choosing which peripherals can be used by the bootloader.
• Configuring the hardware at a low level to enable access to those peripherals.
The bootloader uses the peripherals_<device>.c file to define which peripheral interfaces
are active in the bootloader. The source file itself includes a single table, g_peripherals[],
that contains active peripheral information and pointers to configuration structures. This
file is found in /targets/<device>/src.
It’s important to only place configurations for peripherals that are present on the target
MCU. Otherwise, the processor generates fault conditions when trying to initialize a
peripheral that is not physically present.
In terms of the content of each entry in the g_peripherals[] table, it is recommended to
reuse existing entries and only modify the .instance member. For example, starting with
the following UART0 member, it can be changed to UART1 by simply
changing .instance from “0” to “1”.
{
.typeMask = kPeripheralType_UART,
.instance = 0,
.pinmuxConfig = uart_pinmux_config,
.controlInterface = &g_scuartControlInterface;
.byteInterface = &g_scuartByteInterfacek;
.packetInterface = &g_framingPacketInterface;
}
When the table has all required entries, it must be terminated with a null { 0 } entry.
Once the desired peripheral configuration has been selected, the low level initialization
must be accounted for. The bootloader automatically enables the clock and configures the
peripheral, so the only thing required for the port is to tell the bootloader which pins to
use for each peripheral. This is handled in the peripherals_pinmux.h file in /targets/
<device>/src. The hardware_init_<device>.c file selects the boot pin used by the
bootloader, which may need to be changed for the new target MCU.
These files most likely require significant changes to account for the differences between
devices when it comes to pin routing. Each function should be checked for correctness
and modified as needed.
The Kinetis bootloader typically uses the MCU’s default clock configuration. This is
done to avoid dependencies on external components and simplify use. In some situations,
the default clock configuration cannot be used due to accuracy requirements of supported
peripherals. On devices that have on-chip USB and CAN, the default system
configuration is not suficient and the bootloader configures the device to run from the
high-precision internal reference clock (IRC) if available. Otherwise, it depends on the
external oscillator supply.
The bootloader uses the clock_config_<device>.c file in /targets/<device> to override the
default clock behavior. If the target MCU of the port supports USB, this file can be used.
If not, the functions within clock_config_<device>.c can be stubbed out or set to
whatever the port requires.
The bootloader must be configured in terms of the features it supports and the specific
memory map for the target device. Features can be turned on or off by using #define
statements in the bootloader_config.h file in /targets/<device>/src. Examples of using
these macros can be seen in bl_command.c (g_commandHandlerTable[] table) in
the /src/bootloader/src folder. All checks that reference a BL_* feature can be turned on
or off. Examples of these features are BL_MIN_PROFILE, BL_HAS_MASS_ERASE
and BL_FEATURE_READ_MEMORY.
One of the most important bootloader configuration choices is where to set the start
address (vector table) of the user application. This is determined by the
BL_APP_VECTOR_TABLE_ADDRESS define in bootloader_config.h. Most
bootloader configurations choose to place the user application at address 0xA000 because
that accommodates the full featured bootloader image. It’s possible to move this start
address if the resulting port reduces features (and thus, code size) of the bootloader.
NOTE
Load the Release build of the flash-resident bootloader if you
plan to place the user application at 0xA000. Loading the
Debug build requires you to move the application address
beyond the end of the bootloader image. This address can be
determined from the bootloader map file.
The MCU device memory map and flash configuration must be defined for proper
operation of the bootloader. The device memory map is defined in the g_memoryMap[]
structure of the memory_map_<device>.c file, which can be found in /targets/<device>/
src. An example memory map configuration is shown.
memory_map_entry_t g_memoryMap[] = {
{0x00000000, 0x000fffff, kMemoryIsExecutable, &g_flashMemoryInterface}, // Flash array
(1024KB)
{0x1fff0000, 0x2002ffff, 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
};
In addition to the device memory map, the correct SRAM initialization file must be
selected according to the target device. This file is split based on ARM® Cortex®-M4 and
Cortex-M0+ based devices, so the likelihood of having to change it is low.
The sram_init_cm4.c file is located in /src/memory/src and its alternative is
sram_init_cm0plus.c.
11.1 Introduction
In some situations the ROM-based or full-featured flash-resident bootloader cannot meet
the requirements of a use application. Examples of such situations include special
signaling requirements on IO, peripherals not supported by the bootloader, or the more
basic need to have as small of a code footprint as possible (for the flash-resident
bootloader). This section discusses how to customize the flash-resident bootloader for a
specific use case. The IAR tool chain is used for this example. Other supported tool
chains can be similarly configured.
Each of the projects in the workspace is configured to support all features of the
bootloader. This means every peripheral interface that the MCU supports is enabled. This
makes the bootloader very rich in features, but it also has the largest code footprint,
which can be considerable on MCUs with smaller flash configurations.
There are two folders in each bootloader project: a MCU-specific folder and a “src”
folder. All files in the MCU-specific folder are located in the <install_dir>/targets/
<mcu>/src folder, and are very specific to the target MCU. The “src” folder is located at the
top level of the bootloader tree, and the subfolders in the project correspond to the real
folder/file structure on the PC. The files in the “src” folder are the core files of the
bootloader, and include everything from peripheral drivers to individual commands.
The bootloader source is separated in a way that creates a clear line between what a user
needs to modify and what they do not. Among other things, the files in the MCU-specific
folder allow the application to select which peripherals are active as well as how to
configure the clock, and are intended to be modified by the user. The files in the “src”
folder can be modified, but should only require modification where very specific
customization is needed in the bootloader.
11.5 Example
One of the most common customizations performed on the Kinetis bootloader is
removing unused or unwanted peripheral interfaces. The default configuration of the
bootloader enables multiple interfaces, including UART, SPI, I2C and (on some devices)
USB and CAN. This example will describe how to modify the provided bootloader
projects remove the SPI0 interface. The same methodology can be used to select any of
the supported interfaces.
To remove an interface, either modify this file to set the macro to (0), or pass the macro
define to the toolchain compiler in the project settings. For example:
BL_CONFIG_SPI0=0
Setting this macro to zero removes the interface from the g_peripherals table and
prevents related code from linking into the bootloader image.
The following figure shows that the driver has been added to the K80F256
bootloader project
The location offset of the MMCAU algorithm is x020. The BCA start is 0x3C0, and
the mmcau_function_info address is 0x3E0. For decryption to work properly, the
mmcau_function_info must contain valid values for all the fields in this structure. This
structure size is 20 bytes (0x14 bytes).
• Tag
The tag field must equal 'kcau'
• Length
It is the total length of all MMCAU AES algorithms. See mmcau_aes_functions.lst.
It is 1212 bytes (0x4BC).
• aes_init_start
• aes_encrypt_start
12.1 Introduction
Reliable update is an optional but an important feature of Kinetis bootloader. During a
firmware update, an unexpected loss of power or device disconnect from the host can
happen. This may result in a corrupted image or non-responsive devices. The reliable
update feature is designed to solve this problem.
There are two methods to initiate reliable update process. The first method is to reset the
device to enter the bootloader startup process, causing Kinetis bootloader to detect the
presence of a valid image in the backup region, and kicking off the reliable update
process. The second method is by issuing a reliable-update command from host using
BLHOST.EXE while the bootloader is running on the device.
Using the first method, the reliable update process starts before all interfaces are
configured. The figure below shows the call to reliable update process during startup flow
of the Kinetis bootloader.
Yes
IS
Timeout Check
Enter Bootloader Enabled and
Has Timeout
Occurred?
Init hardware No
Has
USB entered Yes
Init flash driver Interrupt state?
No
Load user-config
data
Was a
Ping packet received on Yes
CANn?
Configure clocks
Init microseconds No
driver,memory & No
property interface
Was a
Reliable Ping packet Shutdown unused
Yes
application update received on Peipherals
if needed SPIn?
No
Init
UARTn,CANn,SPI
n,I2Cn, USB Was a Enter Bootloader
Use the enabledPeripherals field Ping packet State machine
Yes
in user config data to enable(or received on
not) UARTn (or CANn or SPIn or I2Cn?
I2Cn or USB)
No
Is BootPin
asserted? Yes
Was a
Ping packet Yes
Is received on
No direct boot UARTn?
valid?
Is user
Yes application No
valid? Yes
Enable Timeout
Check and enable
No Timeout value
Disable Timeout
detection
The second method occurs while the bootloader state machine is running. The reliable
update process is triggered when the host sends the reliable update bootloader command..
There are two kinds of reliable update implementations. They can be classified as either
the software version or hardware version. The main differences between software and
hardware implementation are listed below:
Table 12-1. Software and hardware implementation
Item Software implementation Hardware implementation
Applicable device All Kinetis devices Devices with flash swap support
Device memory distribution Bootloader + main application + backup Main bootloader + main application +
application backup bootloader + backup application
Backup application address Flexible Fixed
The ability to keep two applications No Yes
The most obvious difference is that software implementation copies the backup
application to the main application region, while hardware implementation swaps two
half flash blocks to make the backup application become the main application. The
detailed differences will be reflected in the chapter titled “Reliable update flow”.
See Section 12.3, “Configuration macros” on how to enable different implementations of
the reliable update.
This chapter describes in detail both the software and hardware implementation of the
reliable update process.
For the software implementation, the backup application address is not fixed. Therefore,
the application address must be specified. There are two ways for the bootloader to
receive the backup application address. If the reliable update process is issued by the
host, the bootloader receives the specified application address from the host itself.
Otherwise, the bootloader makes use of the predefined application address.
After the reliable update process is started, the first thing for the bootloader is to check
the backup application region to determine if the reliable update feature is active by
checking:
1. Whether the application pointer in the backup application is valid.
2. Whether the Bootloader Configuration Area is enabled.
If above conditions are not met, the bootloader exits the reliable update process
immediately. Otherwise, the bootloader continues to validate the integrity of the backup
application by checking:
1. Whether the crcStartAddress is equal to the start address of the vector table of the
application.
2. Whether the crcByteCount (considered as the size of backup application) is less than
or equal to the maximum allowed backup application size.
3. Whether the calculated CRC checksum is equal to the checksum provided in backup
application, given that the above conditions are met.
If the backup application is determined to be valid, the remaining process is described in
the following figure.
NOTE
Not all details are shown in the above figure.
Once the main application region is updated, the bootloader must erase the backup
application region before exiting the reliable update process. This prevents the bootloader
to update the main application image on subsequent boots.
For the hardware implementation, the backup application address is fixed and predefined
in the bootloader, but a swap indicator address is required to swap the flash system. There
are two ways for the bootloader to get the swap indicator address. If the reliable update
process is issued by the host, the bootloader receives the specified swap indicator address
from the host itself. Otherwise, the bootloader tries to receive the swap indicator address
from the IFR, if the swap system is in the ready state.
The top level behavior of the reliable update process depends on how the bootloader gets
the swap indicator address:
• If the reliable update process is issued by the host, the bootloader does the same thing
as software implementation until the validity of the backup application is verified.
• If the reliable update process is from the bootloader startup sequence, the bootloader
first checks the main application. If the main application is valid, then the bootloader
exits the reliable update process immediately, and jumps to the main application.
Otherwise, the bootloader receives the swap indicator address from IFR, then
continues to validate the integrity of the backup application as the software
implementation does.
NOTE
It is expected that the user erases the main application region
when reliable update process is intended with the next startup
sequence. Otherwise, the reliable update process assumes no
update is needed, exits the process, and boots the image from
the main application region
If the backup application is valid, see the remaining operations in the following figure.
NOTE
Not all details are shown in the above figure.
Once the flash system is swapped (upper flash block becomes lower flash block), the
bootloader naturally treats the backup application as the main application. In the
hardware implementation, after the swap, it is not necessary to erase the image from the
backup region.
The configuration macros defined in bootloader_config.h are used to enable the reliable
update feature. For Kinetis bootloader v2.0.0, the feature is only enabled in the K65
Freedom and Tower flash target builds. All code added for this feature should be enabled
only if the macros are defined. Currently, these macros are defined as:
• BL_FEATURE_RELIABLE_UPDATE – Used to enable or disable the reliable
update feature.
• BL_FEATURE_HARDWARE_SWAP_UPDATE – Used to switch the hardware or
software implementation of reliable update.
• BL_BACKUP_APP_START – Used to define the start address of the backup
application if the reliable update feature is enabled.
The following table lists all of the error and status codes.
Table 13-2. Error and status codes
Name Value Description
kStatus_Success 0 Operation succeeded without error.
kStatus_Fail 1 Operation failed with a generic error.
kStatus_ReadOnly 2 Property cannot be changed because it is read-only.
kStatus_OutOfRange 3 Requested value is out of range.
kStatus_InvalidArgument 4 The requested command's argument is undefined.
kStatus_Timeout 5 A timeout occurred.