Used more specific exception classes to allow the TC to handle device failure errors better

This commit is contained in:
Nav
2021-08-15 01:47:48 +01:00
parent 89b5875132
commit 85fbf1ada4
16 changed files with 228 additions and 115 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -1,11 +1,12 @@
#include "CmsisDapInterface.hpp"
#include <memory>
#include <chrono>
#include <thread>
#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<Response> 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>(Response());
@@ -44,7 +45,7 @@ std::unique_ptr<Response> 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;

View File

@@ -1,9 +1,11 @@
#include "EdbgAvr8Interface.hpp"
#include <cstdint>
#include <thread>
#include <math.h>
#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();

View File

@@ -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<unsigned char, std::string>({
@@ -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();

View File

@@ -1,13 +1,16 @@
#include "EdbgInterface.hpp"
#include <cstdint>
#include <cstring>
#include <memory>
#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<Protocols::CmsisDap::Edbg::Avr::AvrEvent> 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<Protocols::CmsisDap::Edbg::Avr::AvrResponse> 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;

View File

@@ -2,7 +2,6 @@
#include <memory>
#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();

View File

@@ -1,11 +1,12 @@
#include "HidInterface.hpp"
#include <cstdint>
#include <string>
#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<unsigned char> 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()) {
/*

View File

@@ -1,20 +1,22 @@
#include "Interface.hpp"
#include <libusb-1.0/libusb.h>
#include <chrono>
#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)
);
}
}

View File

@@ -1,9 +1,10 @@
#include "UsbDevice.hpp"
#include <cstdint>
#include <libusb-1.0/libusb.h>
#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<libusb_device*> 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<libusb_device*> 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);

View File

@@ -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);
}
};

View File

@@ -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);
}
};
}

View File

@@ -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);
}
};
}

View File

@@ -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);
}
};
}

View File

@@ -1,14 +1,17 @@
#include "TargetController.hpp"
#include <thread>
#include <filesystem>
#include <typeindex>
#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<Events::TargetIoPortsUpdated>());
}
} 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<Events::TargetPinStatesRetrieved>();
@@ -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);