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.
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;
}