From c8ee0b2411fba56aa08ab5fa1eea4d20dc075015 Mon Sep 17 00:00:00 2001 From: Dave Cutting Date: Wed, 25 Jan 2023 11:41:01 -0700 Subject: [PATCH] Update bootloader files --- src/ISBootloaderAPP.cpp | 2 +- src/ISBootloaderAPP.h | 2 +- src/ISBootloaderBase.cpp | 59 ++++++++++++++++------ src/ISBootloaderBase.h | 2 +- src/ISBootloaderDFU.cpp | 47 +++-------------- src/ISBootloaderDFU.h | 2 +- src/ISBootloaderISB.cpp | 100 ++++++++++++++++++------------------- src/ISBootloaderISB.h | 2 +- src/ISBootloaderSAMBA.cpp | 4 +- src/ISBootloaderSAMBA.h | 2 +- src/ISBootloaderThread.cpp | 92 +++++++++++++++++++++++++++++----- src/ISBootloaderThread.h | 3 +- 12 files changed, 188 insertions(+), 129 deletions(-) diff --git a/src/ISBootloaderAPP.cpp b/src/ISBootloaderAPP.cpp index 0cb648e05..cc20af3c3 100644 --- a/src/ISBootloaderAPP.cpp +++ b/src/ISBootloaderAPP.cpp @@ -8,7 +8,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : diff --git a/src/ISBootloaderAPP.h b/src/ISBootloaderAPP.h index e8ebde64c..011998831 100644 --- a/src/ISBootloaderAPP.h +++ b/src/ISBootloaderAPP.h @@ -8,7 +8,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : diff --git a/src/ISBootloaderBase.cpp b/src/ISBootloaderBase.cpp index 12310b907..e7341b337 100644 --- a/src/ISBootloaderBase.cpp +++ b/src/ISBootloaderBase.cpp @@ -8,7 +8,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : @@ -124,7 +124,8 @@ eImageSignature cISBootloaderBase::get_bin_image_signature(std::string filename, fseek(blfile, 0x5FFC, SEEK_SET); unsigned char ver_info[4]; - fread(ver_info, 1, 4, blfile); + size_t n = fread(ver_info, 1, 4, blfile); + (void)n; fclose(blfile); //Check for marker for valid version info @@ -140,7 +141,8 @@ eImageSignature cISBootloaderBase::get_bin_image_signature(std::string filename, // Look in the old location for this info (v5 and earler) fseek(blfile, 0x3DFC, SEEK_SET); - fread(ver_info, 1, 4, blfile); + size_t n = fread(ver_info, 1, 4, blfile); + (void)n; fclose(blfile); //Check for marker for valid version info @@ -234,13 +236,9 @@ is_operation_result cISBootloaderBase::mode_device_app } } - char msg[120] = { 0 }; - SNPRINTF(msg, sizeof(msg), " | (%s) Incompatible device.", handle->port); - statusfn(NULL, msg, IS_LOG_LEVEL_ERROR); - delete obj; SLEEP_MS(3000); - return IS_OP_OK; + return IS_OP_CLOSED; // Assume we found something besides app mode } is_operation_result cISBootloaderBase::get_device_isb_version( @@ -453,15 +451,29 @@ is_operation_result cISBootloaderBase::update_device (obj)->m_use_progress = true; addMutex->lock(); contexts.push_back(obj); - *new_context = obj; addMutex->unlock(); - if((obj)->download_image(filenames.bl_IMX_5.path) != IS_OP_OK) + + // Retry update up to 3 times, return if cancel flag gets set. + for(size_t i = 0; i < 3; i++) { - (obj)->m_info_callback((obj), "(DFU) Update failed, retrying...", IS_LOG_LEVEL_ERROR); - (obj)->m_use_progress = false; + is_operation_result result = (obj)->download_image(filenames.bl_IMX_5.path); + if(result == IS_OP_CANCELLED) + { + return IS_OP_CLOSED; + } + else if(result != IS_OP_OK) + { + (obj)->m_info_callback((obj), "(DFU) Update failed, retrying...", IS_LOG_LEVEL_ERROR); + (obj)->m_use_progress = false; + (obj)->reboot(); + continue; + } + *new_context = obj; + (obj)->reboot_up(); // Reboot up right away so an App update can happen return IS_OP_CLOSED; } - (obj)->reboot_up(); // Reboot up right away so an App update can happen + + (obj)->m_info_callback((obj), "(DFU) Update failed, too many retries", IS_LOG_LEVEL_ERROR); return IS_OP_CLOSED; } else @@ -607,7 +619,12 @@ is_operation_result cISBootloaderBase::update_device contexts.push_back(obj); *new_context = obj; addMutex->unlock(); - if((obj)->download_image(filenames.fw_EVB_2.path) != IS_OP_OK) + is_operation_result result = (obj)->download_image(filenames.fw_EVB_2.path); + if(result == IS_OP_CANCELLED) + { + return IS_OP_CLOSED; + } + else if(result != IS_OP_OK) { (obj)->m_info_callback((obj), "(ISB) Update failed, retrying...", IS_LOG_LEVEL_ERROR); (obj)->m_use_progress = false; @@ -631,7 +648,12 @@ is_operation_result cISBootloaderBase::update_device contexts.push_back(obj); *new_context = obj; addMutex->unlock(); - if((obj)->download_image(filenames.fw_IMX_5.path) != IS_OP_OK) + is_operation_result result = (obj)->download_image(filenames.fw_IMX_5.path); + if(result == IS_OP_CANCELLED) + { + return IS_OP_CLOSED; + } + else if(result != IS_OP_OK) { (obj)->m_info_callback((obj), "(ISB) Update failed, retrying...", IS_LOG_LEVEL_ERROR); (obj)->m_use_progress = false; @@ -655,7 +677,12 @@ is_operation_result cISBootloaderBase::update_device contexts.push_back(obj); *new_context = obj; addMutex->unlock(); - if((obj)->download_image(filenames.fw_uINS_3.path) != IS_OP_OK) + is_operation_result result = (obj)->download_image(filenames.fw_uINS_3.path); + if(result == IS_OP_CANCELLED) + { + return IS_OP_CLOSED; + } + else if(result != IS_OP_OK) { (obj)->m_info_callback((obj), "(ISB) Update failed, retrying...", IS_LOG_LEVEL_ERROR); (obj)->m_use_progress = false; diff --git a/src/ISBootloaderBase.h b/src/ISBootloaderBase.h index c71ef969d..5223c8990 100644 --- a/src/ISBootloaderBase.h +++ b/src/ISBootloaderBase.h @@ -8,7 +8,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : diff --git a/src/ISBootloaderDFU.cpp b/src/ISBootloaderDFU.cpp index 17938ca63..27f0124ac 100644 --- a/src/ISBootloaderDFU.cpp +++ b/src/ISBootloaderDFU.cpp @@ -8,7 +8,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : @@ -190,10 +190,6 @@ is_operation_result cISBootloaderDFU::get_serial_number_libusb(libusb_device_han SLEEP_MS(100); - // Reset the device -// ret_libusb = libusb_reset_device(*handle); -// if (ret_libusb < LIBUSB_SUCCESS) { return IS_OP_ERROR; } - ret_libusb = libusb_claim_interface(*handle, 0); if (ret_libusb < LIBUSB_SUCCESS) { libusb_release_interface(*handle, 0); return IS_OP_ERROR; } @@ -282,13 +278,6 @@ is_operation_result cISBootloaderDFU::download_image(std::string filename) ihex_image_section_t image[MAX_NUM_IHEX_SECTIONS]; size_t image_sections; - // Reset the device -// ret_libusb = libusb_reset_device(m_dfu.handle_libusb); -// if(ret_libusb < LIBUSB_SUCCESS) -// { -// return IS_OP_ERROR; -// } - SLEEP_MS(100); ret_libusb = libusb_claim_interface(m_dfu.handle_libusb, 0); @@ -496,18 +485,6 @@ is_operation_result cISBootloaderDFU::reboot() ret_dfu = dfu_wait_for_state(&m_dfu.handle_libusb, DFU_STATE_IDLE); if (ret_dfu < DFU_ERROR_NONE) { libusb_release_interface(m_dfu.handle_libusb, 0); return IS_OP_ERROR; } - // Set address pointer to flash - ret_dfu = dfu_set_address_pointer(&m_dfu.handle_libusb, 0x08000000); - if (ret_dfu < DFU_ERROR_NONE) { libusb_release_interface(m_dfu.handle_libusb, 0); return IS_OP_ERROR; } - - // Request DFU leave - ret_libusb = dfu_DNLOAD(&m_dfu.handle_libusb, 0, NULL, 0); - if (ret_libusb < LIBUSB_SUCCESS) { libusb_release_interface(m_dfu.handle_libusb, 0); return IS_OP_ERROR; } - - // Execute DFU leave - ret_dfu = dfu_wait_for_state(&m_dfu.handle_libusb, DFU_STATE_MANIFEST); - if (ret_dfu < DFU_ERROR_NONE) { libusb_release_interface(m_dfu.handle_libusb, 0); return IS_OP_ERROR; } - // Reset USB device ret_libusb = libusb_reset_device(m_dfu.handle_libusb); if (ret_libusb < LIBUSB_SUCCESS) { libusb_release_interface(m_dfu.handle_libusb, 0); return IS_OP_ERROR; } @@ -577,39 +554,27 @@ cISBootloaderDFU::dfu_error cISBootloaderDFU::dfu_set_address_pointer(libusb_dev cISBootloaderDFU::dfu_error cISBootloaderDFU::dfu_wait_for_state(libusb_device_handle** dev_handle, dfu_state required_state) { - int ret_libusb; - - dfu_status status; + dfu_status status = DFU_STATUS_ERR_UNKNOWN; uint32_t waitTime = 0; dfu_state state; uint8_t stringIndex; uint8_t tryCounter = 0; - ret_libusb = dfu_GETSTATUS(dev_handle, &status, &waitTime, &state, &stringIndex); - if (ret_libusb < LIBUSB_SUCCESS) - { - return DFU_ERROR_LIBUSB; - } + dfu_GETSTATUS(dev_handle, &status, &waitTime, &state, &stringIndex); while (status != DFU_STATUS_OK || state != required_state) { if (status != DFU_STATUS_OK) { - ret_libusb = dfu_CLRSTATUS(dev_handle); - if (ret_libusb < LIBUSB_SUCCESS) return DFU_ERROR_LIBUSB; + dfu_CLRSTATUS(dev_handle); } SLEEP_MS(_MAX(waitTime, 10)); - ret_libusb = dfu_GETSTATUS(dev_handle, &status, &waitTime, &state, &stringIndex); - if (ret_libusb < LIBUSB_SUCCESS) - { - return DFU_ERROR_LIBUSB; - } + dfu_GETSTATUS(dev_handle, &status, &waitTime, &state, &stringIndex); - tryCounter++; - if (tryCounter > 4) return DFU_ERROR_TIMEOUT; + if (++tryCounter > 5) return DFU_ERROR_TIMEOUT; } return DFU_ERROR_NONE; diff --git a/src/ISBootloaderDFU.h b/src/ISBootloaderDFU.h index afe5cda8c..844b17d0c 100644 --- a/src/ISBootloaderDFU.h +++ b/src/ISBootloaderDFU.h @@ -9,7 +9,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : diff --git a/src/ISBootloaderISB.cpp b/src/ISBootloaderISB.cpp index 975489136..5d744246a 100644 --- a/src/ISBootloaderISB.cpp +++ b/src/ISBootloaderISB.cpp @@ -9,7 +9,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : @@ -152,6 +152,7 @@ is_operation_result cISBootloaderISB::reboot_up() // send the "reboot to program mode" command and the device should start in program mode serialPortWrite(m_port, (unsigned char*)":020000040300F7", 15); + serialPortFlush(m_port); SLEEP_MS(1000); serialPortClose(m_port); return IS_OP_OK; @@ -198,6 +199,7 @@ is_operation_result cISBootloaderISB::reboot_force() // restart bootloader command if(serialPortWrite(m_port, (unsigned char*)":020000040500F5", 15) != 15) { + status_update("(ISB) Error in reboot force", IS_LOG_LEVEL_ERROR); return IS_OP_ERROR; } @@ -209,6 +211,7 @@ is_operation_result cISBootloaderISB::reboot() rst_serial_list_mutex.lock(); if(find(rst_serial_list.begin(), rst_serial_list.end(), m_sn) != rst_serial_list.end()) { + status_update("(ISB) Could not find serial port", IS_LOG_LEVEL_ERROR); rst_serial_list_mutex.unlock(); return IS_OP_ERROR; } @@ -356,7 +359,6 @@ int cISBootloaderISB::checksum(int checkSum, uint8_t* ptr, int start, int end, i is_operation_result cISBootloaderISB::erase_flash() { // give the device 60 seconds to erase flash before giving up - static const int eraseFlashTimeoutMilliseconds = 60000; unsigned char selectFlash[24]; serial_port_t* s = m_port; @@ -369,9 +371,29 @@ is_operation_result cISBootloaderISB::erase_flash() // Erase memcpy(selectFlash, ":0200000400FFFBCC\0", 18); checksum(0, selectFlash, 1, 15, 15, 1); - if (serialPortWriteAndWaitForTimeout(s, selectFlash, 17, (unsigned char*)".\r\n", 3, eraseFlashTimeoutMilliseconds) == 0) return IS_OP_ERROR; + serialPortWrite(s, selectFlash, 17); + + // Check for response and allow quit (up to 60 seconds) + uint8_t buf[128]; + uint8_t *bufPtr = buf; + int count = 0; + for(size_t i = 0; i < 600; i++) + { + count += serialPortReadTimeout(s, bufPtr, 3, 100); + bufPtr = buf + count; - return IS_OP_OK; + if (m_update_callback(this, 0.0f) != IS_OP_OK) + { + return IS_OP_CANCELLED; + } + if (count == 3 && memcmp(buf, ".\r\n", 3) == 0) + { + return IS_OP_OK; + } + } + + status_update("(ISB) Error in erase flash", IS_LOG_LEVEL_ERROR); + return IS_OP_ERROR; } is_operation_result cISBootloaderISB::select_page(int page) @@ -498,31 +520,13 @@ is_operation_result cISBootloaderISB::upload_hex_page(unsigned char* hexData, in { break; } - // Some debug code -// else if(count == 0) -// { -// continue; -// } -// else -// { -// continue; -// } + if (i == 9) { return IS_OP_ERROR; } } - - - - -// if (serialPortWriteAndWaitForTimeout(s, checkSumHex, 2, (unsigned char*)".\r\n", 3, BOOTLOADER_TIMEOUT_DEFAULT) == 0) -// { -// status_update("(ISB) Failed to write checksum to device", IS_LOG_LEVEL_ERROR); -// return IS_OP_ERROR; -// } - *totalBytes += byteCount; *currentOffset += byteCount; *verifyCheckSum = newVerifyChecksum; @@ -558,15 +562,6 @@ is_operation_result cISBootloaderISB::upload_hex(unsigned char* hexData, int cha hexData += (pageByteCount * 2); charCount -= (pageByteCount * 2); - - // // change to the next page - // *currentOffset = 0; - // (*currentPage)++; - // if (select_page(*currentPage) != IS_OP_OK || begin_program_for_current_page(0, FLASH_PAGE_SIZE - 1) != IS_OP_OK) - // { - // status_update("(ISB) Failed to issue select page or to start programming", IS_LOG_LEVEL_ERROR); - // return IS_OP_ERROR; - // } } if (charCount != 0 && upload_hex_page(hexData, charCount / 2, currentOffset, totalBytes, verifyCheckSum) != IS_OP_OK) @@ -611,7 +606,7 @@ is_operation_result cISBootloaderISB::download_data(int startOffset, int endOffs serial_port_t* s = m_port; // Atmel download data command is 0x03, different from standard intel hex where command 0x03 is start segment address - unsigned char programLine[24]; + unsigned char programLine[25]; int n; n = SNPRINTF((char*)programLine, 24, ":0500000300%.4X%.4XCC", startOffset, endOffset); programLine[n] = 0; @@ -860,6 +855,7 @@ is_operation_result cISBootloaderISB::process_hex_file(FILE* file) // upload this chunk if (upload_hex(output, _MIN(MAX_SEND_COUNT, outputSize), ¤tOffset, ¤tPage, &totalBytes, &verifyCheckSum) != IS_OP_OK) { + status_update("(ISB) Error in upload chunk", IS_LOG_LEVEL_ERROR); return IS_OP_ERROR; } @@ -905,11 +901,13 @@ is_operation_result cISBootloaderISB::process_hex_file(FILE* file) // flush the remainder of data to the page if (upload_hex(output, outputSize, ¤tOffset, ¤tPage, &totalBytes, &verifyCheckSum) != IS_OP_OK) { + status_update("(ISB) Error in upload hex", IS_LOG_LEVEL_ERROR); return IS_OP_ERROR; } // // fill the remainder of the current page, the next time that bytes try to be written the page will be automatically incremented if (fill_current_page(¤tPage, ¤tOffset, &totalBytes, &verifyCheckSum) != IS_OP_OK) { + status_update("(ISB) Error in fill page", IS_LOG_LEVEL_ERROR); return IS_OP_ERROR; } @@ -931,10 +929,12 @@ is_operation_result cISBootloaderISB::process_hex_file(FILE* file) // flush the remainder of data to the page if (upload_hex(output, outputSize, ¤tOffset, ¤tPage, &totalBytes, &verifyCheckSum) != IS_OP_OK) { + status_update("(ISB) Error in upload hex (last)", IS_LOG_LEVEL_ERROR); return IS_OP_ERROR; } if (currentOffset != 0 && fill_current_page(¤tPage, ¤tOffset, &totalBytes, &verifyCheckSum) != IS_OP_OK) { + status_update("(ISB) Error in fill page (last)", IS_LOG_LEVEL_ERROR); return IS_OP_ERROR; } @@ -954,19 +954,6 @@ is_operation_result cISBootloaderISB::process_hex_file(FILE* file) } } - // upload any left over data -// outputSize = (int)(outputPtr - output); -// if (upload_hex(output, outputSize, ¤tOffset, ¤tPage, &totalBytes, &verifyCheckSum) != IS_OP_OK) -// { -// return IS_OP_ERROR; -// } - - // pad the remainder of the page with fill bytes - // if (currentOffset != 0 && fill_current_page(¤tPage, ¤tOffset, &totalBytes, &verifyCheckSum) != IS_OP_OK) - // { - // return IS_OP_ERROR; - // } - if (m_update_callback != 0 && m_update_progress != 1.0f) { m_update_progress = 1.0f; @@ -983,6 +970,7 @@ is_operation_result cISBootloaderISB::process_hex_file(FILE* file) is_operation_result cISBootloaderISB::download_image(std::string filename) { FILE* firmware_file = 0; + is_operation_result result; #ifdef _MSC_VER fopen_s(&firmware_file, filename.c_str(), "rb"); @@ -990,18 +978,30 @@ is_operation_result cISBootloaderISB::download_image(std::string filename) firmware_file = fopen(filename.c_str(), "rb"); #endif + if (!firmware_file) + { + status_update("(ISB) Error in opening file", IS_LOG_LEVEL_ERROR); + return IS_OP_INCOMPATIBLE; + } + status_update("(ISB) Erasing flash...", IS_LOG_LEVEL_INFO); - if(erase_flash() != IS_OP_OK) return IS_OP_ERROR; - if(select_page(0) != IS_OP_OK) return IS_OP_ERROR; + result = erase_flash(); + if(result != IS_OP_OK) { fclose(firmware_file); return result; } + result = select_page(0); + if(result != IS_OP_OK) { fclose(firmware_file); return result; } status_update("(ISB) Programming flash...", IS_LOG_LEVEL_INFO); - if(begin_program_for_current_page(m_isb_props.app_offset, FLASH_PAGE_SIZE - 1) != IS_OP_OK) return IS_OP_ERROR; - if(process_hex_file(firmware_file) != IS_OP_OK) return IS_OP_ERROR; + result = begin_program_for_current_page(m_isb_props.app_offset, FLASH_PAGE_SIZE - 1); + if(result != IS_OP_OK) { fclose(firmware_file); return result; } + result = process_hex_file(firmware_file); + if(result != IS_OP_OK) { fclose(firmware_file); return result; } fclose(firmware_file); + SLEEP_MS(1000); // Allow some time for commands to be sent in UART mode + return IS_OP_OK; } diff --git a/src/ISBootloaderISB.h b/src/ISBootloaderISB.h index 14f7bc084..606cc3ca2 100644 --- a/src/ISBootloaderISB.h +++ b/src/ISBootloaderISB.h @@ -9,7 +9,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : diff --git a/src/ISBootloaderSAMBA.cpp b/src/ISBootloaderSAMBA.cpp index 492fa3395..a4da3d73d 100644 --- a/src/ISBootloaderSAMBA.cpp +++ b/src/ISBootloaderSAMBA.cpp @@ -9,7 +9,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : @@ -415,7 +415,7 @@ is_operation_result cISBootloaderSAMBA::verify_image(std::string filename) serialPortFlush(m_port); - SAMBA_STATUS("(SAM-BA) Verifying ISB bootloader...", IS_LOG_LEVEL_INFO); + SAMBA_STATUS("(SAM-BA) Verifying ISB bootloader (may take some time)...", IS_LOG_LEVEL_INFO); while (serialPortRead(m_port, buf, 1)); diff --git a/src/ISBootloaderSAMBA.h b/src/ISBootloaderSAMBA.h index 21e41d102..d24e1f3f9 100644 --- a/src/ISBootloaderSAMBA.h +++ b/src/ISBootloaderSAMBA.h @@ -8,7 +8,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : diff --git a/src/ISBootloaderThread.cpp b/src/ISBootloaderThread.cpp index 17e7895ce..0dccd7117 100644 --- a/src/ISBootloaderThread.cpp +++ b/src/ISBootloaderThread.cpp @@ -8,7 +8,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : @@ -288,6 +288,8 @@ void cISBootloaderThread::update_thread_serial(void* context) // Other device } + SLEEP_MS(1000); + serialPortFlush(&port); serialPortClose(&port); @@ -332,6 +334,17 @@ void cISBootloaderThread::update_thread_libusb(void* context) m_libusb_thread_mutex.unlock(); } +bool cISBootloaderThread::true_if_cancelled(void) +{ + if(m_uploadProgress(NULL, 0.0f) == IS_OP_CANCELLED) + { + m_continue_update = false; + return true; + } + + return false; +} + vector cISBootloaderThread::set_mode_and_check_devices( vector& comPorts, int baudRate, @@ -345,7 +358,12 @@ vector cISBootloaderThread::set_mode_an // Only allow one firmware update sequence to happen at a time m_update_mutex.lock(); m_update_in_progress = true; - + + // Clear old entries + m_ctx_mutex.lock(); + ctx.clear(); + m_ctx_mutex.unlock(); + // Copy in the firmware update settings m_firmware = firmware; m_uploadProgress = uploadProgress; @@ -380,7 +398,7 @@ vector cISBootloaderThread::set_mode_an //////////////////////////////////////////////////////////////////////////// // Put all devices in the correct mode - while(m_continue_update) + while(m_continue_update && !true_if_cancelled()) { if (m_waitAction) m_waitAction(); SLEEP_MS(10); @@ -423,7 +441,8 @@ vector cISBootloaderThread::set_mode_an if (!found) { thread_serial_t* new_thread = (thread_serial_t*)malloc(sizeof(thread_serial_t)); - strncpy(new_thread->serial_name, ports[i].c_str(), 100); + memset(new_thread->serial_name, 0, 100); + strncpy(new_thread->serial_name, ports[i].c_str(), _MIN(ports[i].size(),100)); new_thread->ctx = NULL; new_thread->done = false; m_serial_threads.push_back(new_thread); @@ -483,6 +502,15 @@ vector cISBootloaderThread::set_mode_an m_serial_thread_mutex.unlock(); } + if(m_uploadProgress(NULL, 0.0f) == IS_OP_CANCELLED) + { + m_continue_update = false; + m_update_in_progress = false; + m_update_mutex.unlock(); + if(m_waitAction) m_waitAction(); + return vector(); + } + m_continue_update = true; m_timeStart = current_timeMs(); @@ -491,7 +519,7 @@ vector cISBootloaderThread::set_mode_an //////////////////////////////////////////////////////////////////////////// // Put all devices in the correct mode - while(m_continue_update) + while(m_continue_update && !true_if_cancelled()) { if (m_waitAction) m_waitAction(); SLEEP_MS(10); @@ -534,7 +562,8 @@ vector cISBootloaderThread::set_mode_an if (!found) { thread_serial_t* new_thread = (thread_serial_t*)malloc(sizeof(thread_serial_t)); - strncpy(new_thread->serial_name, ports[i].c_str(), 100); + memset(new_thread->serial_name, 0, 100); + strncpy(new_thread->serial_name, ports[i].c_str(), _MIN(ports[i].size(), 100)); new_thread->ctx = NULL; new_thread->done = false; m_serial_threads.push_back(new_thread); @@ -594,6 +623,14 @@ vector cISBootloaderThread::set_mode_an m_serial_thread_mutex.unlock(); } + if(m_uploadProgress(NULL, 0.0f) == IS_OP_CANCELLED) + { + m_continue_update = false; + m_update_in_progress = false; + m_update_mutex.unlock(); + if(m_waitAction) m_waitAction(); + return vector(); + } m_ctx_mutex.lock(); for(size_t i = 0; i < ctx.size(); i++) @@ -654,6 +691,14 @@ is_operation_result cISBootloaderThread::update( comPorts.begin(), comPorts.end(), back_inserter(ports_user_ignore)); + if(m_uploadProgress(NULL, 0.0f) == IS_OP_CANCELLED) + { + m_continue_update = false; + m_update_in_progress = false; + m_update_mutex.unlock(); + if(m_waitAction) m_waitAction(); + return IS_OP_CANCELLED; + } m_continue_update = true; m_timeStart = current_timeMs(); @@ -661,7 +706,7 @@ is_operation_result cISBootloaderThread::update( // Run `mode_thread_serial_isb` to put all ISB devices into DFU/SAM-BA mode //////////////////////////////////////////////////////////////////////////// - while(m_continue_update) + while(m_continue_update && !true_if_cancelled()) { if (m_waitAction) m_waitAction(); SLEEP_MS(10); @@ -695,7 +740,8 @@ is_operation_result cISBootloaderThread::update( if (!found) { thread_serial_t* new_thread = (thread_serial_t*)malloc(sizeof(thread_serial_t)); - strncpy(new_thread->serial_name, ports[i].c_str(), 100); + memset(new_thread->serial_name, 0, 100); + strncpy(new_thread->serial_name, ports[i].c_str(), _MIN(ports[i].size(),100)); new_thread->ctx = NULL; new_thread->done = false; new_thread->force_isb = force_isb_update; @@ -752,7 +798,15 @@ is_operation_result cISBootloaderThread::update( m_serial_thread_mutex.unlock(); } - m_infoProgress(NULL, "Updating... (120 seconds max.)", IS_LOG_LEVEL_INFO); + if(m_uploadProgress(NULL, 0.0f) == IS_OP_CANCELLED) + { + m_continue_update = false; + m_update_in_progress = false; + m_update_mutex.unlock(); + if(m_waitAction) m_waitAction(); + return IS_OP_CANCELLED; + } + m_infoProgress(NULL, "Updating...", IS_LOG_LEVEL_INFO); //////////////////////////////////////////////////////////////////////////// // Run `mgmt_thread_libusb` to update DFU devices @@ -770,7 +824,7 @@ is_operation_result cISBootloaderThread::update( // Run `update_thread_serial` to update devices //////////////////////////////////////////////////////////////////////////// - while (m_continue_update) + while (m_continue_update && !true_if_cancelled()) { if (m_waitAction) m_waitAction(); SLEEP_MS(10); @@ -829,7 +883,8 @@ is_operation_result cISBootloaderThread::update( if (!found) { thread_serial_t* new_thread = (thread_serial_t*)malloc(sizeof(thread_serial_t)); - strncpy(new_thread->serial_name, ports[i].c_str(), 100); + memset(new_thread->serial_name, 0, 100); + strncpy(new_thread->serial_name, ports[i].c_str(), _MIN(ports[i].size(),100)); new_thread->ctx = NULL; new_thread->done = false; new_thread->force_isb = force_isb_update; @@ -856,13 +911,24 @@ is_operation_result cISBootloaderThread::update( m_serial_thread_mutex.unlock(); // Timeout after 60 seconds - if (current_timeMs() - timeoutLong > 120000) + uint32_t timeout = (baudRate < 921600) ? 360000 : 120000; + if (current_timeMs() - timeoutLong > timeout) { m_continue_update = false; + m_infoProgress(NULL, "Update timeout", IS_LOG_LEVEL_ERROR); } } threadJoinAndFree(libusb_thread); + + if(m_uploadProgress(NULL, 0.0f) == IS_OP_CANCELLED) + { + m_continue_update = false; + m_update_in_progress = false; + m_update_mutex.unlock(); + if(m_waitAction) m_waitAction(); + return IS_OP_CANCELLED; + } // Reset all serial devices up a level into APP or ISB mode for (size_t i = 0; i < ctx.size(); i++) @@ -871,7 +937,7 @@ is_operation_result cISBootloaderThread::update( { serial_port_t port; serialPortPlatformInit(&port); - if (!serialPortOpenRetry(&port, ctx[i]->m_port_name.c_str(), 921600, 1)) + if (!serialPortOpenRetry(&port, ctx[i]->m_port_name.c_str(), m_baudRate, 1)) { continue; } diff --git a/src/ISBootloaderThread.h b/src/ISBootloaderThread.h index f860c158c..4a62cee71 100644 --- a/src/ISBootloaderThread.h +++ b/src/ISBootloaderThread.h @@ -8,7 +8,7 @@ /* MIT LICENSE -Copyright (c) 2014-2022 Inertial Sense, Inc. - http://inertialsense.com +Copyright (c) 2014-2023 Inertial Sense, Inc. - http://inertialsense.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : @@ -98,6 +98,7 @@ class cISBootloaderThread static void update_thread_serial(void* context); static void update_thread_libusb(void* context); static void mgmt_thread_libusb(void* context); + static bool true_if_cancelled(void); static ISBootloader::firmwares_t m_firmware;