Hi
Does anyone try to port KBOOT on KE0X (e.g.: KE02) platform? I have read reference manual and view source code and seems this platform is not supported. In chapter 10, porting bootloader: header fsl_flash_features.h has to be correctly adopted. This seems to be a first challenge.
Would be nice if NXP provide such definitions..
Does anyone has some expirence with porting KBOOT to KE02 platform?
Best Regards
/Greg
Hi
What do you mean "is available"? What I read on web page is "KBOOT compatible UART loader" what for me obviously is not KBOOT but something what is "UART compatible". Am I correct? Is it based on KBOOT source code?
I need fully featured KBOOT due special requirements. Is your project something what may help me to port KBOOT on KE02?
Regards
/Greg
Hi Greg
The KE02 loader in the link is a USB/UART implementation compatible with the KBOOT utility which supports also USB-MSD, SD card, Ethernet and a few other UART loading protocols (of course the Ethernet and USB parts are disabled when the KE02 is selected due to missing peripherals).
It is not KBOOT source code ported to KE02 but a processor independent implementation (operates on all KE, KL, K, KW, KV etc.) that can be build using any of the popular development environments as well as full simulation for reviews as well as professional support for critical projects or where customised features are desired.
KBOOT source is quite processor and IDE specific and so complicated to maintain. This means that if you need to use actual KBOOT code you will need to either do a pure porting excercise or request NXP to invest in a port to the particular device.
Regards
Mark
Hi Mark
Make sense! really nice.
Is it fully supported KBOOT UART protocol? so I can use PC application from NXP?
/Greg
Hi
It works with the KBOOT PC appliation to load new code (USB or UART) - there are two binary files at the link which can be used to verify this.
Below I have copied the actual KBOOT handling (generic for any processor on any interface). Some KBOOT specified commands are not handled because there is no need to for SW loading. The KBOOT protocol is specified in quite an abstract way (foreseeing various potential possibilities that would probably never be of much practical use) but it is visible that such things can also be added easily if ever required.
Regards
Mark
extern int fnHandleKboot(QUEUE_HANDLE hInterface, int iInterfaceType, KBOOT_PACKET *ptrKBOOT_packet)
{
int iReturn = 0;
KBOOT_PACKET KBOOT_response;
uMemset(&KBOOT_response, 0, sizeof(KBOOT_response));
switch (ptrKBOOT_packet->ucCommandType) { // the command
case KBOOT_REPORT_ID_COMMAND_OUT:
KBOOT_response.ucCommandType = KBOOT_REPORT_ID_COMMAND_IN;
switch (ptrKBOOT_packet->ucData[0]) {
case KBOOT_COMMAND_TAG_GET_PROPERTY: // 0x07 this routine is partly prepared for multiple parameters but assumes only a single one
{
int iParameters = ptrKBOOT_packet->ucData[3];
unsigned long ulValue = 0;
unsigned char *prType = &ptrKBOOT_packet->ucData[4];
if (iParameters > 1) {
_EXCEPTION("only one parameter tested!");
}
while (iParameters--) { // for each requested parameter (presently only one parameter is ever received)
fnHandlePropertyGet(*prType, &ulValue);
}
KBOOT_response.ucLength[0] = 12;
KBOOT_response.ucData[0] = (ptrKBOOT_packet->ucData[0] | 0xa0);
KBOOT_response.ucData[3] = (ptrKBOOT_packet->ucData[3] + 1); // status plus requested parameters
KBOOT_response.ucData[8] = (unsigned char)ulValue;
KBOOT_response.ucData[9] = (unsigned char)(ulValue >> 8);
KBOOT_response.ucData[10] = (unsigned char)(ulValue >> 16);
KBOOT_response.ucData[11] = (unsigned char)(ulValue >> 24);
}
break;
case KBOOT_COMMAND_TAG_WRITE_MEMORY: // 0x04
case KBOOT_COMMAND_TAG_ERASE_REGION: // 0x02
{
unsigned long ulStartAddress;
unsigned long ulLength;
ulStartAddress = (ptrKBOOT_packet->ucData[4] | (ptrKBOOT_packet->ucData[5] << 8) | (ptrKBOOT_packet->ucData[6] << 16) | (ptrKBOOT_packet->ucData[7] << 24));
ulLength = (ptrKBOOT_packet->ucData[8] | (ptrKBOOT_packet->ucData[9] << 8) | (ptrKBOOT_packet->ucData[10] << 16) | (ptrKBOOT_packet->ucData[11] << 24));
if (KBOOT_COMMAND_TAG_ERASE_REGION == ptrKBOOT_packet->ucData[0]) { // command to delete an area in flash
if ((ulStartAddress >= UTASKER_APP_START) && (ulStartAddress < (unsigned long)UTASKER_APP_END)) {
if ((ulStartAddress + ulLength) > (unsigned long)UTASKER_APP_END) {
ulLength = ((unsigned long)UTASKER_APP_END - ulStartAddress);
}
fnEraseFlashSector((unsigned char *)ulStartAddress, (MAX_FILE_LENGTH)ulLength);
#if defined ADD_FILE_OBJECT_AFTER_LOADING
fileObjInfo.ptrLastAddress = 0;
#endif
#if defined DEBUG_CODE
fnDebugMsg("ERASING: ");
fnDebugHex(ulStartAddress, (sizeof(ulStartAddress) | WITH_LEADIN));
fnDebugHex(ulLength, (sizeof(ulLength) | WITH_SPACE | WITH_LEADIN | WITH_CR_LF));
#endif
}
}
else { // command to write following data to flash
ptrFlashAddress = (unsigned char *)ulStartAddress;
ulProg_length = ulLength;
#if defined ADD_FILE_OBJECT_AFTER_LOADING
if ((ptrFlashAddress + ulLength) > fileObjInfo.ptrLastAddress) {
fileObjInfo.ptrLastAddress = (ptrFlashAddress + ulLength); // keep a track of the highest program address
}
#endif
#if defined DEBUG_CODE
fnDebugMsg("PROGRAMMING: ");
fnDebugHex(ulProg_length, (sizeof(ulLength) | WITH_LEADIN | WITH_CR_LF));
#endif
}
KBOOT_response.ucLength[0] = 12; // generic response
KBOOT_response.ucData[0] = 0xa0;
if (iInterfaceType == KBOOT_UART) {
KBOOT_response.ucData[3] = 2;
}
else {
KBOOT_response.ucData[2] = 2;
}
KBOOT_response.ucData[8] = ptrKBOOT_packet->ucData[0];
}
break;
case KBOOT_COMMAND_TAG_RESET: // 0x0b
iReturn = 1; // reset is required
KBOOT_response.ucLength[0] = 12; // generic response
KBOOT_response.ucData[0] = 0xa0;
if (iInterfaceType == KBOOT_UART) {
KBOOT_response.ucData[3] = 2;
fnDriver(hInterface, (RX_OFF), 0); // disable rx since we are resetting (to stop the host's ack triggering receive timer and losing reset timer)
#if defined ADD_FILE_OBJECT_AFTER_LOADING
fileObjInfo.ptrShortFileName = "KBOOTSERBIN"; // define a name for the file (with default time/date)
#endif
}
else {
KBOOT_response.ucData[2] = 2;
#if defined ADD_FILE_OBJECT_AFTER_LOADING
fileObjInfo.ptrShortFileName = "KBOOTUSBBIN"; // define a name for the file (with default time/date)
#endif
}
KBOOT_response.ucData[8] = ptrKBOOT_packet->ucData[0];
#if defined ADD_FILE_OBJECT_AFTER_LOADING
if (fileObjInfo.ptrLastAddress != 0) {
fnAddSREC_file(&fileObjInfo); // add a file object with name and size
}
#endif
#if defined DEBUG_CODE
fnDebugMsg("RESETTING\r\n");
#endif
break;
case KBOOT_COMMAND_TAG_ERASE_ALL: // the following are not yet used by KBOOT
break;
case KBOOT_COMMAND_TAG_READ_MEMORY:
break;
case KBOOT_COMMAND_TAG_FILL_MEMORY:
break;
case KBOOT_COMMAND_TAG_FLASH_SECURITY_DISABLE:
break;
case KBOOT_COMMAND_TAG_RECEIVE_SBFILE:
break;
case KBOOT_COMMAND_TAG_EXECUTE:
break;
case KBOOT_COMMAND_TAG_CALL:
break;
case KBOOT_COMMAND_TAG_SET_PROPERTY:
break;
case KBOOT_COMMAND_TAG_MASS_ERASE:
break;
}
fnReturnResponse(hInterface, iInterfaceType, &KBOOT_response);
break;
case KBOOT_REPORT_ID_DATA_OUT: // data to be written
{
unsigned short usBuff_length = ptrKBOOT_packet->ucLength[0];
if ((ptrFlashAddress >= (unsigned char *)UTASKER_APP_START) && (ptrFlashAddress < UTASKER_APP_END)) { // if the sector belongs to the application space
if ((ptrFlashAddress + usBuff_length) > UTASKER_APP_END) { // if the write would be past the end of the application space
usBuff_length = (unsigned short)(ptrFlashAddress - UTASKER_APP_END);
}
if (usBuff_length > ulProg_length) {
usBuff_length = (unsigned short)ulProg_length;
}
fnWriteBytesFlash(ptrFlashAddress, ptrKBOOT_packet->ucData, usBuff_length); // program flash
ptrFlashAddress += usBuff_length;
ulProg_length -= usBuff_length;
if (ulProg_length == 0) { // complete code has been received
KBOOT_response.ucCommandType = KBOOT_REPORT_ID_COMMAND_IN;
KBOOT_response.ucLength[0] = 12; // generic response
KBOOT_response.ucData[0] = 0xa0;
if (iInterfaceType == KBOOT_UART) {
KBOOT_response.ucData[3] = 2;
}
else {
KBOOT_response.ucData[2] = 2;
}
KBOOT_response.ucData[8] = KBOOT_COMMAND_TAG_WRITE_MEMORY;
#if defined FLASH_ROW_SIZE && FLASH_ROW_SIZE > 0
fnWriteBytesFlash(0, 0, 0); // close any outstanding FLASH buffer
#endif
fnReturnResponse(hInterface, iInterfaceType, &KBOOT_response); // send response to inform that all data has been programmed
#if defined DEBUG_CODE
fnDebugMsg("*");
#endif
}
#if defined DEBUG_CODE
fnDebugMsg(".");
#endif
}
#if defined DEBUG_CODE
else {
fnDebugMsg("x");
}
#endif
}
break;
}
return iReturn;
}