diff --git a/src/DebugToolDrivers/Microchip/AtmelICE/AtmelIce.cpp b/src/DebugToolDrivers/Microchip/AtmelICE/AtmelIce.cpp index 5a3414ce..f2a3c5cf 100644 --- a/src/DebugToolDrivers/Microchip/AtmelICE/AtmelIce.cpp +++ b/src/DebugToolDrivers/Microchip/AtmelICE/AtmelIce.cpp @@ -1,5 +1,7 @@ #include "AtmelIce.hpp" -#include "src/Exceptions/Exception.hpp" + +#include "src/TargetController/Exceptions/DeviceFailure.hpp" +#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp" using namespace Bloom::DebugToolDrivers; using namespace Protocols::CmsisDap::Edbg::Avr; @@ -54,7 +56,9 @@ std::string AtmelIce::getSerialNumber() { ); if (response.getResponseId() != CommandFrames::Discovery::ResponseId::OK) { - throw Exception("Failed to fetch serial number from device - invalid Discovery Protocol response ID."); + throw DeviceInitializationFailure( + "Failed to fetch serial number from device - invalid Discovery Protocol response ID." + ); } auto data = response.getPayloadData(); @@ -68,7 +72,7 @@ void AtmelIce::startSession() { if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) { // Failed response returned! - throw Exception("Failed to start session with Atmel-ICE!"); + throw DeviceInitializationFailure("Failed to start session with Atmel-ICE!"); } this->sessionStarted = true; @@ -81,7 +85,7 @@ void AtmelIce::endSession() { if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) { // Failed response returned! - throw Exception("Failed to end session with Atmel-ICE!"); + throw DeviceFailure("Failed to end session with Atmel-ICE!"); } this->sessionStarted = false; diff --git a/src/DebugToolDrivers/Microchip/MplabSnap/MplabSnap.cpp b/src/DebugToolDrivers/Microchip/MplabSnap/MplabSnap.cpp index 9339d55e..857ed812 100644 --- a/src/DebugToolDrivers/Microchip/MplabSnap/MplabSnap.cpp +++ b/src/DebugToolDrivers/Microchip/MplabSnap/MplabSnap.cpp @@ -1,5 +1,7 @@ #include "MplabSnap.hpp" -#include "src/Exceptions/Exception.hpp" + +#include "src/TargetController/Exceptions/DeviceFailure.hpp" +#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp" using namespace Bloom::DebugToolDrivers; using namespace Protocols::CmsisDap::Edbg::Avr; @@ -46,7 +48,9 @@ std::string MplabSnap::getSerialNumber() { ); if (response.getResponseId() != CommandFrames::Discovery::ResponseId::OK) { - throw Exception("Failed to fetch serial number from device - invalid Discovery Protocol response ID."); + throw DeviceInitializationFailure( + "Failed to fetch serial number from device - invalid Discovery Protocol response ID." + ); } auto data = response.getPayloadData(); @@ -60,7 +64,7 @@ void MplabSnap::startSession() { if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) { // Failed response returned! - throw Exception("Failed to start session with MPLAB Snap!"); + throw DeviceInitializationFailure("Failed to start session with MPLAB Snap!"); } this->sessionStarted = true; @@ -73,7 +77,7 @@ void MplabSnap::endSession() { if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) { // Failed response returned! - throw Exception("Failed to end session with MPLAB Snap!"); + throw DeviceFailure("Failed to end session with MPLAB Snap!"); } this->sessionStarted = false; diff --git a/src/DebugToolDrivers/Microchip/PowerDebugger/PowerDebugger.cpp b/src/DebugToolDrivers/Microchip/PowerDebugger/PowerDebugger.cpp index 7b4f6d0c..49a7579b 100644 --- a/src/DebugToolDrivers/Microchip/PowerDebugger/PowerDebugger.cpp +++ b/src/DebugToolDrivers/Microchip/PowerDebugger/PowerDebugger.cpp @@ -1,5 +1,7 @@ #include "PowerDebugger.hpp" -#include "src/Exceptions/Exception.hpp" + +#include "src/TargetController/Exceptions/DeviceFailure.hpp" +#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp" using namespace Bloom::DebugToolDrivers; using namespace Protocols::CmsisDap::Edbg::Avr; @@ -54,7 +56,9 @@ std::string PowerDebugger::getSerialNumber() { ); if (response.getResponseId() != CommandFrames::Discovery::ResponseId::OK) { - throw Exception("Failed to fetch serial number from device - invalid Discovery Protocol response ID."); + throw DeviceInitializationFailure( + "Failed to fetch serial number from device - invalid Discovery Protocol response ID." + ); } auto data = response.getPayloadData(); @@ -68,7 +72,9 @@ void PowerDebugger::startSession() { if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) { // Failed response returned! - throw Exception("Failed to start session with the Power Debugger - device returned failed response ID"); + throw DeviceInitializationFailure( + "Failed to start session with the Power Debugger - device returned failed response ID" + ); } this->sessionStarted = true; @@ -81,7 +87,7 @@ void PowerDebugger::endSession() { if (response.getResponseId() == CommandFrames::HouseKeeping::ResponseId::FAILED) { // Failed response returned! - throw Exception("Failed to end session with the Power Debugger - device returned failed response ID"); + throw DeviceFailure("Failed to end session with the Power Debugger - device returned failed response ID"); } this->sessionStarted = false; diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/CmsisDapInterface.cpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/CmsisDapInterface.cpp index f89efbac..203d95fc 100644 --- a/src/DebugToolDrivers/Protocols/CMSIS-DAP/CmsisDapInterface.cpp +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/CmsisDapInterface.cpp @@ -1,11 +1,12 @@ +#include "CmsisDapInterface.hpp" + #include #include #include -#include "CmsisDapInterface.hpp" #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/Command.hpp" #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/Response.hpp" -#include "src/Exceptions/Exception.hpp" +#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp" using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap; using namespace Bloom::Exceptions; @@ -30,7 +31,7 @@ std::unique_ptr CmsisDapInterface::getResponse() { auto rawResponse = this->getUsbHidInterface().read(10000); if (rawResponse.size() == 0) { - throw Exception("Empty CMSIS-DAP response received"); + throw DeviceCommunicationFailure("Empty CMSIS-DAP response received"); } auto response = std::make_unique(Response()); @@ -44,7 +45,7 @@ std::unique_ptr CmsisDapInterface::sendCommandAndWaitForResponse(const if (response->getResponseId() != cmsisDapCommand.getCommandId()) { // This response is not what we were expecting - throw Exception("Unexpected response to CMSIS-DAP command."); + throw DeviceCommunicationFailure("Unexpected response to CMSIS-DAP command."); } return response; diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.cpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.cpp index b8814e41..9a87b702 100644 --- a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.cpp +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/EdbgAvr8Interface.cpp @@ -1,9 +1,11 @@ +#include "EdbgAvr8Interface.hpp" + #include #include #include -#include "EdbgAvr8Interface.hpp" #include "src/Exceptions/InvalidConfig.hpp" +#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp" #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Exceptions/Avr8CommandFailure.hpp" #include "src/Logger/Logger.hpp" @@ -218,59 +220,59 @@ void EdbgAvr8Interface::setDebugWireAndJtagParameters() { void EdbgAvr8Interface::setPdiParameters() { if (!this->targetParameters.appSectionPdiOffset.has_value()) { - throw Exception("Missing required parameter: APPL_BASE_ADDR"); + throw DeviceInitializationFailure("Missing required parameter: APPL_BASE_ADDR"); } if (!this->targetParameters.bootSectionPdiOffset.has_value()) { - throw Exception("Missing required parameter: BOOT_BASE_ADDR"); + throw DeviceInitializationFailure("Missing required parameter: BOOT_BASE_ADDR"); } if (!this->targetParameters.bootSectionSize.has_value()) { - throw Exception("Missing required parameter: BOOT_BYTES"); + throw DeviceInitializationFailure("Missing required parameter: BOOT_BYTES"); } if (!this->targetParameters.flashSize.has_value()) { - throw Exception("Missing required parameter: APPLICATION_BYTES"); + throw DeviceInitializationFailure("Missing required parameter: APPLICATION_BYTES"); } if (!this->targetParameters.eepromPdiOffset.has_value()) { - throw Exception("Missing required parameter: EEPROM_BASE_ADDR"); + throw DeviceInitializationFailure("Missing required parameter: EEPROM_BASE_ADDR"); } if (!this->targetParameters.fuseRegistersPdiOffset.has_value()) { - throw Exception("Missing required parameter: FUSE_BASE_ADDR"); + throw DeviceInitializationFailure("Missing required parameter: FUSE_BASE_ADDR"); } if (!this->targetParameters.lockRegistersPdiOffset.has_value()) { - throw Exception("Missing required parameter: LOCKBIT_BASE_ADDR"); + throw DeviceInitializationFailure("Missing required parameter: LOCKBIT_BASE_ADDR"); } if (!this->targetParameters.userSignaturesPdiOffset.has_value()) { - throw Exception("Missing required parameter: USER_SIGN_BASE_ADDR"); + throw DeviceInitializationFailure("Missing required parameter: USER_SIGN_BASE_ADDR"); } if (!this->targetParameters.productSignaturesPdiOffset.has_value()) { - throw Exception("Missing required parameter: PROD_SIGN_BASE_ADDR"); + throw DeviceInitializationFailure("Missing required parameter: PROD_SIGN_BASE_ADDR"); } if (!this->targetParameters.ramPdiOffset.has_value()) { - throw Exception("Missing required parameter: DATA_BASE_ADDR"); + throw DeviceInitializationFailure("Missing required parameter: DATA_BASE_ADDR"); } if (!this->targetParameters.flashPageSize.has_value()) { - throw Exception("Missing required parameter: FLASH_PAGE_BYTES"); + throw DeviceInitializationFailure("Missing required parameter: FLASH_PAGE_BYTES"); } if (!this->targetParameters.eepromSize.has_value()) { - throw Exception("Missing required parameter: EEPROM_SIZE"); + throw DeviceInitializationFailure("Missing required parameter: EEPROM_SIZE"); } if (!this->targetParameters.eepromPageSize.has_value()) { - throw Exception("Missing required parameter: EEPROM_PAGE_SIZE"); + throw DeviceInitializationFailure("Missing required parameter: EEPROM_PAGE_SIZE"); } if (!this->targetParameters.nvmBaseAddress.has_value()) { - throw Exception("Missing required parameter: NVM_BASE"); + throw DeviceInitializationFailure("Missing required parameter: NVM_BASE"); } Logger::debug("Setting APPL_BASE_ADDR AVR8 parameter"); @@ -360,7 +362,7 @@ void EdbgAvr8Interface::setPdiParameters() { void EdbgAvr8Interface::setUpdiParameters() { if (!this->targetParameters.signatureSegmentStartAddress.has_value()) { - throw Exception("Missing required parameter: SIGNATURE BASE ADDRESS"); + throw DeviceInitializationFailure("Missing required parameter: SIGNATURE BASE ADDRESS"); } if (this->targetParameters.programMemoryUpdiStartAddress.has_value()) { @@ -537,28 +539,29 @@ void EdbgAvr8Interface::setTargetParameters(const Avr8Bit::TargetParameters& con this->targetParameters = config; if (!config.stackPointerRegisterLowAddress.has_value()) { - throw Exception("Failed to find stack pointer register start address"); + throw DeviceInitializationFailure("Failed to find stack pointer register start address"); } if (!config.stackPointerRegisterSize.has_value()) { - throw Exception("Failed to find stack pointer register size"); + throw DeviceInitializationFailure("Failed to find stack pointer register size"); } if (!config.statusRegisterStartAddress.has_value()) { - throw Exception("Failed to find status register start address"); + throw DeviceInitializationFailure("Failed to find status register start address"); } if (!config.statusRegisterSize.has_value()) { - throw Exception("Failed to find status register size"); + throw DeviceInitializationFailure("Failed to find status register size"); } if (this->configVariant == Avr8ConfigVariant::NONE) { auto configVariant = this->resolveConfigVariant(); if (!configVariant.has_value()) { - throw Exception("Failed to resolve config variant for the selected " + throw DeviceInitializationFailure("Failed to resolve config variant for the selected " "physical interface and AVR8 family. The selected physical interface is not known to be supported " - "by the AVR8 family."); + "by the AVR8 family." + ); } this->configVariant = configVariant.value(); diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Exceptions/Avr8CommandFailure.hpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Exceptions/Avr8CommandFailure.hpp index 392bf95e..85f40961 100644 --- a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Exceptions/Avr8CommandFailure.hpp +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/Exceptions/Avr8CommandFailure.hpp @@ -1,11 +1,11 @@ #pragma once -#include "src/Exceptions/Exception.hpp" +#include "src/TargetController/Exceptions/TargetOperationFailure.hpp" #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/ResponseFrames/AVR8Generic/Avr8GenericResponseFrame.hpp" namespace Bloom::Exceptions { - class Avr8CommandFailure: public Exception + class Avr8CommandFailure: public TargetOperationFailure { private: static inline auto failureCodeToDescription = std::map({ @@ -59,18 +59,18 @@ namespace Bloom::Exceptions }); public: - explicit Avr8CommandFailure(const std::string& message): Exception(message) { + explicit Avr8CommandFailure(const std::string& message): TargetOperationFailure(message) { this->message = message; } - explicit Avr8CommandFailure(const char* message): Exception(message) { + explicit Avr8CommandFailure(const char* message): TargetOperationFailure(message) { this->message = std::string(message); } explicit Avr8CommandFailure( const std::string& message, DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::ResponseFrames::Avr8Generic::Avr8GenericResponseFrame& responseFrame - ): Exception(message) { + ): TargetOperationFailure(message) { this->message = message; auto responsePayload = responseFrame.getPayload(); diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/EdbgInterface.cpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/EdbgInterface.cpp index d396e3c8..bf1cc389 100644 --- a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/EdbgInterface.cpp +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/EdbgInterface.cpp @@ -1,13 +1,16 @@ +#include "EdbgInterface.hpp" + #include #include #include -#include "EdbgInterface.hpp" +#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp" using namespace Bloom::DebugToolDrivers; using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg; using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr; using namespace Bloom::Exceptions; +using namespace Bloom::Exceptions; Protocols::CmsisDap::Response EdbgInterface::sendAvrCommandFrameAndWaitForResponse( const Protocols::CmsisDap::Edbg::Avr::AvrCommandFrame& avrCommandFrame @@ -30,7 +33,9 @@ Protocols::CmsisDap::Response EdbgInterface::sendAvrCommandFrameAndWaitForRespon } // This should never happen - throw Exception("Cannot send AVR command frame - failed to generate CMSIS-DAP Vendor (AVR) commands"); + throw DeviceCommunicationFailure( + "Cannot send AVR command frame - failed to generate CMSIS-DAP Vendor (AVR) commands" + ); } Protocols::CmsisDap::Edbg::Avr::AvrResponse EdbgInterface::getAvrResponse() { @@ -42,7 +47,7 @@ Protocols::CmsisDap::Edbg::Avr::AvrResponse EdbgInterface::getAvrResponse() { avrResponse.init(*cmsisResponse); return avrResponse; } else { - throw Exception("Unexpected response to AvrResponseCommand from device"); + throw DeviceCommunicationFailure("Unexpected response to AvrResponseCommand from device"); } } @@ -56,7 +61,7 @@ std::optional EdbgInterface::requestAv avrEvent.init(*cmsisResponse); return avrEvent.getEventDataSize() > 0 ? std::optional(avrEvent): std::nullopt; } else { - throw Exception("Unexpected response to AvrEventCommand from device"); + throw DeviceCommunicationFailure("Unexpected response to AvrEventCommand from device"); } } @@ -75,11 +80,14 @@ std::vector EdbgInterface::requestA response = this->getAvrResponse(); if (response.getFragmentCount() != fragmentCount) { - throw Exception("Failed to fetch AVRResponse objects - invalid fragment count returned."); + throw DeviceCommunicationFailure( + "Failed to fetch AVRResponse objects - invalid fragment count returned." + ); } if (response.getFragmentCount() == 0 && response.getFragmentNumber() == 0) { - throw Exception("Failed to fetch AVRResponse objects - unexpected empty response"); + throw DeviceCommunicationFailure("Failed to fetch AVRResponse objects - unexpected empty response"); + } else if (response.getFragmentNumber() == 0) { // End of response data ( &this packet can be ignored) break; diff --git a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/EdbgInterface.hpp b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/EdbgInterface.hpp index bae8c60b..0f1bda7b 100644 --- a/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/EdbgInterface.hpp +++ b/src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/EdbgInterface.hpp @@ -2,7 +2,6 @@ #include -#include "src/Exceptions/Exception.hpp" #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/CmsisDapInterface.hpp" #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/AvrCommand.hpp" #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/AvrEventCommand.hpp" @@ -11,6 +10,7 @@ #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/AvrResponseCommand.hpp" #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/ResponseFrames/AvrResponseFrame.hpp" #include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AvrCommandFrame.hpp" +#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp" namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg { @@ -62,8 +62,9 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg if (response.getData()[0] != 0x01) { // The last response packet should always acknowledge receipt of the AvrCommandFrame - throw Exceptions::Exception("Failed to send AvrCommandFrame to device " - "- device did not acknowledge receipt."); + throw Exceptions::DeviceCommunicationFailure( + "Failed to send AvrCommandFrame to device - device did not acknowledge receipt." + ); } auto responses = this->requestAvrResponses(); diff --git a/src/DebugToolDrivers/USB/HID/HidInterface.cpp b/src/DebugToolDrivers/USB/HID/HidInterface.cpp index d7c95ae8..b8bbbdb0 100644 --- a/src/DebugToolDrivers/USB/HID/HidInterface.cpp +++ b/src/DebugToolDrivers/USB/HID/HidInterface.cpp @@ -1,11 +1,12 @@ +#include "HidInterface.hpp" + #include #include -#include "HidInterface.hpp" #include "hidapi.hpp" #include "src/Logger/Logger.hpp" -#include "src/Exceptions/Exception.hpp" -#include "src/Exceptions/DeviceCommunicationFailure.hpp" +#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp" +#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp" using namespace Bloom::Usb; using namespace Bloom::Exceptions; @@ -22,7 +23,7 @@ std::string HidInterface::getDevicePathByInterfaceNumber(const std::uint16_t& in } if (hidDeviceInfoList == nullptr) { - throw Exception("Failed to match interface number with HID interface."); + throw DeviceInitializationFailure("Failed to match interface number with HID interface."); } auto path = std::string(hidDeviceInfoList->path); @@ -32,7 +33,7 @@ std::string HidInterface::getDevicePathByInterfaceNumber(const std::uint16_t& in void HidInterface::init() { if (this->libUsbDevice == nullptr) { - throw Exception("Cannot initialise interface without libusb device pointer."); + throw DeviceInitializationFailure("Cannot initialise interface without libusb device pointer."); } hid_init(); @@ -42,11 +43,13 @@ void HidInterface::init() { Logger::debug("HID device path: " + hidInterfacePath); if ((hidDevice = hid_open_path(hidInterfacePath.c_str())) == nullptr) { - throw Exception("Failed to open HID device via hidapi."); + throw DeviceInitializationFailure("Failed to open HID device via hidapi."); } if (hidDevice->input_ep_max_packet_size < 1) { - throw Exception("Invalid max packet size for USB endpoint, on interface " + std::to_string(this->getNumber())); + throw DeviceInitializationFailure( + "Invalid max packet size for USB endpoint, on interface " + std::to_string(this->getNumber()) + ); } this->setHidDevice(hidDevice); @@ -87,7 +90,9 @@ std::size_t HidInterface::read(unsigned char* buffer, std::size_t maxLength, uns void HidInterface::write(std::vector buffer) { if (buffer.size() > this->getInputReportSize()) { - throw Exception("Cannot send data via HID interface - data exceeds maximum packet size."); + throw DeviceCommunicationFailure( + "Cannot send data via HID interface - data exceeds maximum packet size." + ); } else if (buffer.size() < this->getInputReportSize()) { /* diff --git a/src/DebugToolDrivers/USB/Interface.cpp b/src/DebugToolDrivers/USB/Interface.cpp index 53b10b9e..0339d8b7 100644 --- a/src/DebugToolDrivers/USB/Interface.cpp +++ b/src/DebugToolDrivers/USB/Interface.cpp @@ -1,20 +1,22 @@ +#include "Interface.hpp" + #include #include -#include "Interface.hpp" -#include "src/Exceptions/Exception.hpp" +#include "src/TargetController/Exceptions/DeviceFailure.hpp" +#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp" +#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp" using namespace Bloom::Usb; using namespace Bloom::Exceptions; - void Interface::init() { if (this->libUsbDevice == nullptr) { - throw Exception("Cannot initialise interface without libusb device pointer."); + throw DeviceInitializationFailure("Cannot initialise interface without libusb device pointer."); } if (this->libUsbDeviceHandle == nullptr) { - throw Exception("Cannot initialise interface without libusb device handle."); + throw DeviceInitializationFailure("Cannot initialise interface without libusb device handle."); } this->initialised = true; @@ -34,7 +36,9 @@ void Interface::claim() { this->detachKernelDriver(); if (libusb_claim_interface(this->libUsbDeviceHandle, interfaceNumber) != 0) { - throw Exception("Failed to claim interface {" + std::to_string(interfaceNumber) + "} on USB device\n"); + throw DeviceInitializationFailure( + "Failed to claim interface {" + std::to_string(interfaceNumber) + "} on USB device\n" + ); } this->claimed = true; @@ -48,11 +52,11 @@ void Interface::detachKernelDriver() { if (libUsbStatusCode == 1) { // A kernel driver is active on this interface. Attempt to detach it if (libusb_detach_kernel_driver(this->libUsbDeviceHandle, interfaceNumber) != 0) { - throw Exception("Failed to detach kernel driver from interface " + + throw DeviceInitializationFailure("Failed to detach kernel driver from interface " + std::to_string(interfaceNumber) + "\n"); } } else { - throw Exception("Failed to check for active kernel driver on USB interface."); + throw DeviceInitializationFailure("Failed to check for active kernel driver on USB interface."); } } } @@ -60,7 +64,9 @@ void Interface::detachKernelDriver() { void Interface::release() { if (this->isClaimed()) { if (libusb_release_interface(this->libUsbDeviceHandle, this->getNumber()) != 0) { - throw Exception("Failed to release interface {" + std::to_string(this->getNumber()) + "} on USB device\n"); + throw DeviceFailure( + "Failed to release interface {" + std::to_string(this->getNumber()) + "} on USB device\n" + ); } this->claimed = false; @@ -83,7 +89,9 @@ int Interface::read(unsigned char* buffer, unsigned char endPoint, size_t length ); if (libUsbStatusCode != 0 && libUsbStatusCode != -7) { - throw Exception("Failed to read from USB device. Error code returned: " + std::to_string(libUsbStatusCode)); + throw DeviceCommunicationFailure( + "Failed to read from USB device. Error code returned: " + std::to_string(libUsbStatusCode) + ); } totalTransferred += transferred; @@ -106,6 +114,8 @@ void Interface::write(unsigned char* buffer, unsigned char endPoint, int length) ); if (libUsbStatusCode != 0) { - throw Exception("Failed to read from USB device. Error code returned: " + std::to_string(libUsbStatusCode)); + throw DeviceCommunicationFailure( + "Failed to read from USB device. Error code returned: " + std::to_string(libUsbStatusCode) + ); } } diff --git a/src/DebugToolDrivers/USB/UsbDevice.cpp b/src/DebugToolDrivers/USB/UsbDevice.cpp index c8657ad5..795d2b48 100644 --- a/src/DebugToolDrivers/USB/UsbDevice.cpp +++ b/src/DebugToolDrivers/USB/UsbDevice.cpp @@ -1,9 +1,10 @@ +#include "UsbDevice.hpp" + #include #include -#include "UsbDevice.hpp" #include "src/Logger/Logger.hpp" -#include "src/Exceptions/Exception.hpp" +#include "src/TargetController/Exceptions/DeviceInitializationFailure.hpp" using Bloom::Usb::UsbDevice; using namespace Bloom::Exceptions; @@ -21,8 +22,9 @@ std::vector UsbDevice::findMatchingDevices( auto productIdToMatch = productId.value_or(this->productId); if ((libUsbStatusCode = libusb_get_device_list(libUsbContext, &devices)) < 0) { - throw Exception("Failed to retrieve USB devices - return code: '" + std::to_string(libUsbStatusCode) - + "'"); + throw DeviceInitializationFailure( + "Failed to retrieve USB devices - return code: '" + std::to_string(libUsbStatusCode) + "'" + ); } while ((device = devices[i++]) != nullptr) { @@ -30,7 +32,7 @@ std::vector UsbDevice::findMatchingDevices( if ((libUsbStatusCode = libusb_get_device_descriptor(device, &desc)) < 0) { Logger::warning("Failed to retrieve USB device descriptor - return code: '" - + std::to_string(libUsbStatusCode) + "'"); + + std::to_string(libUsbStatusCode) + "'"); continue; } @@ -49,14 +51,14 @@ void UsbDevice::init() { auto devices = this->findMatchingDevices(); if (devices.empty()) { - throw Exception("Failed to find USB device with matching vendor & product ID."); + throw DeviceInitializationFailure("Failed to find USB device with matching vendor & product ID."); } else if (devices.size() > 1) { // TODO: implement support for multiple devices (maybe via serial number?) - throw Exception("Multiple devices of matching vendor & product ID found.\n" - "Yes, as a program I really am too stupid to figure out what to do " - "here, so I'm just going to quit.\n Please ensure that only one debug tool " - "is connected and then try again."); + throw DeviceInitializationFailure( + "Numerous devices of matching vendor & product ID found.\n" + "Please ensure that only one debug tool is connected and then try again." + ); } // For now, just use the first device found. @@ -67,8 +69,9 @@ void UsbDevice::init() { // Obtain a device handle from libusb if ((libUsbStatusCode = libusb_open(libUsbDevice, &this->libUsbDeviceHandle)) < 0) { - throw Exception("Failed to open USB device - error code " + std::to_string(libUsbStatusCode) - + " returned."); + throw DeviceInitializationFailure( + "Failed to open USB device - error code " + std::to_string(libUsbStatusCode) + " returned." + ); } } @@ -88,13 +91,16 @@ void UsbDevice::setConfiguration(int configIndex) { int libUsbStatusCode; if ((libUsbStatusCode = libusb_get_config_descriptor(this->libUsbDevice, 0, &configDescriptor))) { - throw Exception("Failed to obtain USB configuration descriptor - error code " - + std::to_string(libUsbStatusCode) + " returned."); + throw DeviceInitializationFailure( + "Failed to obtain USB configuration descriptor - error code " + std::to_string(libUsbStatusCode) + + " returned." + ); } if ((libUsbStatusCode = libusb_set_configuration(this->libUsbDeviceHandle, configDescriptor->bConfigurationValue))) { - throw Exception("Failed to set USB configuration - error code " - + std::to_string(libUsbStatusCode) + " returned."); + throw DeviceInitializationFailure( + "Failed to set USB configuration - error code " + std::to_string(libUsbStatusCode) + " returned." + ); } libusb_free_config_descriptor(configDescriptor); diff --git a/src/Exceptions/DeviceCommunicationFailure.hpp b/src/TargetController/Exceptions/DeviceCommunicationFailure.hpp similarity index 67% rename from src/Exceptions/DeviceCommunicationFailure.hpp rename to src/TargetController/Exceptions/DeviceCommunicationFailure.hpp index 2018efc8..32cbff8d 100644 --- a/src/Exceptions/DeviceCommunicationFailure.hpp +++ b/src/TargetController/Exceptions/DeviceCommunicationFailure.hpp @@ -1,17 +1,17 @@ #pragma once -#include "Exception.hpp" +#include "DeviceFailure.hpp" namespace Bloom::Exceptions { - class DeviceCommunicationFailure: public Exception + class DeviceCommunicationFailure: public DeviceFailure { public: - explicit DeviceCommunicationFailure(const std::string& message): Exception(message) { + explicit DeviceCommunicationFailure(const std::string& message): DeviceFailure(message) { this->message = message; } - explicit DeviceCommunicationFailure(const char* message): Exception(message) { + explicit DeviceCommunicationFailure(const char* message): DeviceFailure(message) { this->message = std::string(message); } }; diff --git a/src/TargetController/Exceptions/DeviceFailure.hpp b/src/TargetController/Exceptions/DeviceFailure.hpp new file mode 100644 index 00000000..e3d51d7b --- /dev/null +++ b/src/TargetController/Exceptions/DeviceFailure.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "src/Exceptions/Exception.hpp" + +namespace Bloom::Exceptions +{ + class DeviceFailure: public Exception + { + public: + explicit DeviceFailure(const std::string& message): Exception(message) { + this->message = message; + } + + explicit DeviceFailure(const char* message): Exception(message) { + this->message = std::string(message); + } + }; +} diff --git a/src/TargetController/Exceptions/DeviceInitializationFailure.hpp b/src/TargetController/Exceptions/DeviceInitializationFailure.hpp new file mode 100644 index 00000000..901b94e6 --- /dev/null +++ b/src/TargetController/Exceptions/DeviceInitializationFailure.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "DeviceFailure.hpp" + +namespace Bloom::Exceptions +{ + class DeviceInitializationFailure: public DeviceFailure + { + public: + explicit DeviceInitializationFailure(const std::string& message): DeviceFailure(message) { + this->message = message; + } + + explicit DeviceInitializationFailure(const char* message): DeviceFailure(message) { + this->message = std::string(message); + } + }; +} diff --git a/src/TargetController/Exceptions/TargetOperationFailure.hpp b/src/TargetController/Exceptions/TargetOperationFailure.hpp new file mode 100644 index 00000000..ac42de86 --- /dev/null +++ b/src/TargetController/Exceptions/TargetOperationFailure.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "src/Exceptions/Exception.hpp" + +namespace Bloom::Exceptions +{ + class TargetOperationFailure: public Exception + { + public: + explicit TargetOperationFailure(const std::string& message): Exception(message) { + this->message = message; + } + + explicit TargetOperationFailure(const char* message): Exception(message) { + this->message = std::string(message); + } + }; +} diff --git a/src/TargetController/TargetController.cpp b/src/TargetController/TargetController.cpp index e982d6ac..ae5e0936 100644 --- a/src/TargetController/TargetController.cpp +++ b/src/TargetController/TargetController.cpp @@ -1,14 +1,17 @@ +#include "TargetController.hpp" + #include #include #include -#include "TargetController.hpp" -#include "src/Exceptions/InvalidConfig.hpp" -#include "src/Exceptions/TargetControllerStartupFailure.hpp" -#include "src/Exceptions/DeviceCommunicationFailure.hpp" #include "src/Application.hpp" #include "src/Helpers/Paths.hpp" +#include "src/TargetController/Exceptions/DeviceFailure.hpp" +#include "src/TargetController/Exceptions/TargetOperationFailure.hpp" +#include "src/Exceptions/TargetControllerStartupFailure.hpp" +#include "src/Exceptions/InvalidConfig.hpp" + using namespace Bloom; using namespace Bloom::Targets; using namespace Bloom::Events; @@ -29,17 +32,19 @@ void TargetController::run() { this->eventListener->waitAndDispatch(60); - } catch (const DeviceCommunicationFailure& exception) { + } catch (const DeviceFailure& exception) { /* - * Upon a device communication failure, we assume Bloom has lost control of the debug tool. This could - * be the result of the user disconnecting the debug tool, or issuing a soft reset. - * The soft reset could have been issued via another application, without the user's knowledge. + * Upon a device failure, we assume Bloom has lost control of the debug tool. This could be the result + * of the user disconnecting the debug tool, or issuing a soft reset. The soft reset could have been + * issued via another application, without the user's knowledge. * See https://github.com/navnavnav/Bloom/issues/3 for more on that. * * The TC will go into a suspended state and the DebugServer should terminate any active debug * session. When the user attempts to start another debug session, we will try to re-connect to the * debug tool. */ + Logger::error("Device failure detected - " + exception.getMessage()); + Logger::error("Suspending TargetController"); this->suspend(); } } @@ -298,7 +303,7 @@ void TargetController::acquireHardware() { if (promotedTarget == nullptr || std::type_index(typeid(*promotedTarget)) == std::type_index(typeid(*this->target)) - ) { + ) { break; } @@ -426,7 +431,7 @@ void TargetController::onStepTargetExecutionEvent(const Events::StepTargetExecut try { if (this->target->getState() != TargetState::STOPPED) { // We can't step the target if it's already running. - throw Exception("Target is already running"); + throw TargetOperationFailure("Target is already running"); } if (event.fromProgramCounter.has_value()) { @@ -440,7 +445,7 @@ void TargetController::onStepTargetExecutionEvent(const Events::StepTargetExecut executionResumedEvent->correlationId = event.id; this->eventManager.triggerEvent(executionResumedEvent); - } catch (const Exception& exception) { + } catch (const TargetOperationFailure& exception) { Logger::error("Failed to step execution on target - " + exception.getMessage()); this->emitErrorEvent(event.id); } @@ -461,7 +466,7 @@ void TargetController::onResumeTargetExecutionEvent(const Events::ResumeTargetEx executionResumedEvent->correlationId = event.id; this->eventManager.triggerEvent(executionResumedEvent); - } catch (const Exception& exception) { + } catch (const TargetOperationFailure& exception) { Logger::error("Failed to resume execution on target - " + exception.getMessage()); this->emitErrorEvent(event.id); } @@ -478,7 +483,7 @@ void TargetController::onReadRegistersEvent(const Events::RetrieveRegistersFromT this->eventManager.triggerEvent(registersRetrievedEvent); } - } catch (const Exception& exception) { + } catch (const TargetOperationFailure& exception) { Logger::error("Failed to read general registers from target - " + exception.getMessage()); this->emitErrorEvent(event.id); } @@ -492,7 +497,7 @@ void TargetController::onWriteRegistersEvent(const Events::WriteRegistersToTarge registersWrittenEvent->correlationId = event.id; this->eventManager.triggerEvent(registersWrittenEvent); - } catch (const Exception& exception) { + } catch (const TargetOperationFailure& exception) { Logger::error("Failed to write registers to target - " + exception.getMessage()); this->emitErrorEvent(event.id); } @@ -506,7 +511,7 @@ void TargetController::onReadMemoryEvent(const Events::RetrieveMemoryFromTarget& this->eventManager.triggerEvent(memoryReadEvent); - } catch (const Exception& exception) { + } catch (const TargetOperationFailure& exception) { Logger::error("Failed to read memory from target - " + exception.getMessage()); this->emitErrorEvent(event.id); } @@ -529,7 +534,7 @@ void TargetController::onWriteMemoryEvent(const Events::WriteMemoryToTarget& eve this->eventManager.triggerEvent(std::make_shared()); } - } catch (const Exception& exception) { + } catch (const TargetOperationFailure& exception) { Logger::error("Failed to write memory to target - " + exception.getMessage()); this->emitErrorEvent(event.id); } @@ -543,7 +548,7 @@ void TargetController::onSetBreakpointEvent(const Events::SetBreakpointOnTarget& this->eventManager.triggerEvent(breakpointSetEvent); - } catch (const Exception& exception) { + } catch (const TargetOperationFailure& exception) { Logger::error("Failed to set breakpoint on target - " + exception.getMessage()); this->emitErrorEvent(event.id); } @@ -557,7 +562,7 @@ void TargetController::onRemoveBreakpointEvent(const Events::RemoveBreakpointOnT this->eventManager.triggerEvent(breakpointRemovedEvent); - } catch (const Exception& exception) { + } catch (const TargetOperationFailure& exception) { Logger::error("Failed to remove breakpoint on target - " + exception.getMessage()); this->emitErrorEvent(event.id); } @@ -566,7 +571,9 @@ void TargetController::onRemoveBreakpointEvent(const Events::RemoveBreakpointOnT void TargetController::onSetProgramCounterEvent(const Events::SetProgramCounterOnTarget& event) { try { if (this->target->getState() != TargetState::STOPPED) { - throw Exception("Invalid target state - target must be stopped before the program counter can be updated"); + throw TargetOperationFailure( + "Invalid target state - target must be stopped before the program counter can be updated" + ); } this->target->setProgramCounter(event.address); @@ -575,7 +582,7 @@ void TargetController::onSetProgramCounterEvent(const Events::SetProgramCounterO this->eventManager.triggerEvent(programCounterSetEvent); - } catch (const Exception& exception) { + } catch (const TargetOperationFailure& exception) { Logger::error("Failed to set program counter on target - " + exception.getMessage()); this->emitErrorEvent(event.id); } @@ -597,7 +604,9 @@ void TargetController::onInsightStateChangedEvent(const Events::InsightThreadSta void TargetController::onRetrieveTargetPinStatesEvent(const Events::RetrieveTargetPinStates& event) { try { if (this->target->getState() != TargetState::STOPPED) { - throw Exception("Invalid target state - target must be stopped before pin states can be retrieved"); + throw TargetOperationFailure( + "Invalid target state - target must be stopped before pin states can be retrieved" + ); } auto pinStatesRetrieved = std::make_shared(); @@ -607,7 +616,7 @@ void TargetController::onRetrieveTargetPinStatesEvent(const Events::RetrieveTarg this->eventManager.triggerEvent(pinStatesRetrieved); - } catch (const Exception& exception) { + } catch (const TargetOperationFailure& exception) { Logger::error("Failed to retrieve target pin states - " + exception.getMessage()); this->emitErrorEvent(event.id); } @@ -616,7 +625,9 @@ void TargetController::onRetrieveTargetPinStatesEvent(const Events::RetrieveTarg void TargetController::onSetPinStateEvent(const Events::SetTargetPinState& event) { try { if (this->target->getState() != TargetState::STOPPED) { - throw Exception("Invalid target state - target must be stopped before pin state can be set"); + throw TargetOperationFailure( + "Invalid target state - target must be stopped before pin state can be set" + ); } this->target->setPinState(event.variantId, event.pinDescriptor, event.pinState); @@ -630,7 +641,7 @@ void TargetController::onSetPinStateEvent(const Events::SetTargetPinState& event this->eventManager.triggerEvent(pinStatesUpdateEvent); - } catch (const Exception& exception) { + } catch (const TargetOperationFailure& exception) { Logger::error("Failed to set target pin state for pin " + event.pinDescriptor.name + " - " + exception.getMessage()); this->emitErrorEvent(event.id);