Lots of tidying
This commit is contained in:
@@ -28,10 +28,11 @@ namespace Bloom
|
|||||||
if (this->arguments.size() > 1) {
|
if (this->arguments.size() > 1) {
|
||||||
auto& firstArg = this->arguments.at(1);
|
auto& firstArg = this->arguments.at(1);
|
||||||
const auto commandHandlersByCommandName = this->getCommandHandlersByCommandName();
|
const auto commandHandlersByCommandName = this->getCommandHandlersByCommandName();
|
||||||
|
const auto commandHandlerIt = commandHandlersByCommandName.find(firstArg);
|
||||||
|
|
||||||
if (commandHandlersByCommandName.contains(firstArg)) {
|
if (commandHandlerIt != commandHandlersByCommandName.end()) {
|
||||||
// User has passed an argument that maps to a command callback - invoke the callback and shutdown
|
// User has passed an argument that maps to a command callback - invoke the callback and shutdown
|
||||||
const auto returnValue = commandHandlersByCommandName.at(firstArg)();
|
const auto returnValue = commandHandlerIt->second();
|
||||||
|
|
||||||
this->shutdown();
|
this->shutdown();
|
||||||
return returnValue;
|
return returnValue;
|
||||||
@@ -272,13 +273,14 @@ namespace Bloom
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate the selected environment
|
// Validate the selected environment
|
||||||
if (!this->projectConfig->environments.contains(this->selectedEnvironmentName)) {
|
const auto selectedEnvironmentIt = this->projectConfig->environments.find(this->selectedEnvironmentName);
|
||||||
|
if (selectedEnvironmentIt == this->projectConfig->environments.end()) {
|
||||||
throw InvalidConfig(
|
throw InvalidConfig(
|
||||||
"Environment (\"" + this->selectedEnvironmentName + "\") not found in configuration."
|
"Environment (\"" + this->selectedEnvironmentName + "\") not found in configuration."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->environmentConfig = this->projectConfig->environments.at(this->selectedEnvironmentName);
|
this->environmentConfig = selectedEnvironmentIt->second;
|
||||||
|
|
||||||
if (this->environmentConfig->insightConfig.has_value()) {
|
if (this->environmentConfig->insightConfig.has_value()) {
|
||||||
this->insightConfig = this->environmentConfig->insightConfig.value();
|
this->insightConfig = this->environmentConfig->insightConfig.value();
|
||||||
|
|||||||
@@ -66,13 +66,13 @@ namespace Bloom::DebugServer
|
|||||||
);
|
);
|
||||||
|
|
||||||
static const auto availableServersByName = this->getAvailableServersByName();
|
static const auto availableServersByName = this->getAvailableServersByName();
|
||||||
if (!availableServersByName.contains(this->debugServerConfig.name)) {
|
const auto selectedServerIt = availableServersByName.find(this->debugServerConfig.name);
|
||||||
throw Exceptions::InvalidConfig(
|
|
||||||
"DebugServer \"" + this->debugServerConfig.name + "\" not found."
|
if (selectedServerIt == availableServersByName.end()) {
|
||||||
);
|
throw Exceptions::InvalidConfig("DebugServer \"" + this->debugServerConfig.name + "\" not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->server = availableServersByName.at(this->debugServerConfig.name)();
|
this->server = selectedServerIt->second();
|
||||||
Logger::info("Selected DebugServer: " + this->server->getName());
|
Logger::info("Selected DebugServer: " + this->server->getName());
|
||||||
|
|
||||||
this->server->init();
|
this->server->init();
|
||||||
|
|||||||
@@ -65,8 +65,9 @@ namespace Bloom::DebugServer::Gdb::AvrGdb::CommandPackets
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const auto& memoryDescriptorsByType = debugSession.gdbTargetDescriptor.targetDescriptor.memoryDescriptorsByType;
|
const auto& memoryDescriptorsByType = debugSession.gdbTargetDescriptor.targetDescriptor.memoryDescriptorsByType;
|
||||||
|
const auto memoryDescriptorIt = memoryDescriptorsByType.find(this->memoryType);
|
||||||
|
|
||||||
if (!memoryDescriptorsByType.contains(this->memoryType)) {
|
if (memoryDescriptorIt == memoryDescriptorsByType.end()) {
|
||||||
throw Exception("Target does not support the requested memory type.");
|
throw Exception("Target does not support the requested memory type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +76,7 @@ namespace Bloom::DebugServer::Gdb::AvrGdb::CommandPackets
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& memoryDescriptor = memoryDescriptorsByType.at(this->memoryType);
|
const auto& memoryDescriptor = memoryDescriptorIt->second;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In AVR targets, RAM is mapped to many registers and peripherals - we don't want to block GDB from
|
* In AVR targets, RAM is mapped to many registers and peripherals - we don't want to block GDB from
|
||||||
|
|||||||
@@ -73,8 +73,9 @@ namespace Bloom::DebugServer::Gdb::AvrGdb::CommandPackets
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const auto& memoryDescriptorsByType = debugSession.gdbTargetDescriptor.targetDescriptor.memoryDescriptorsByType;
|
const auto& memoryDescriptorsByType = debugSession.gdbTargetDescriptor.targetDescriptor.memoryDescriptorsByType;
|
||||||
|
const auto memoryDescriptorIt = memoryDescriptorsByType.find(this->memoryType);
|
||||||
|
|
||||||
if (!memoryDescriptorsByType.contains(this->memoryType)) {
|
if (memoryDescriptorIt == memoryDescriptorsByType.end()) {
|
||||||
throw Exception("Target does not support the requested memory type.");
|
throw Exception("Target does not support the requested memory type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +99,7 @@ namespace Bloom::DebugServer::Gdb::AvrGdb::CommandPackets
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& memoryDescriptor = memoryDescriptorsByType.at(this->memoryType);
|
const auto& memoryDescriptor = memoryDescriptorIt->second;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In AVR targets, RAM is mapped to many registers and peripherals - we don't want to block GDB from
|
* In AVR targets, RAM is mapped to many registers and peripherals - we don't want to block GDB from
|
||||||
|
|||||||
@@ -31,23 +31,29 @@ namespace Bloom::DebugServer::Gdb::AvrGdb
|
|||||||
}
|
}
|
||||||
|
|
||||||
const RegisterDescriptor& TargetDescriptor::getRegisterDescriptorFromNumber(GdbRegisterNumber number) const {
|
const RegisterDescriptor& TargetDescriptor::getRegisterDescriptorFromNumber(GdbRegisterNumber number) const {
|
||||||
if (this->registerDescriptorsByGdbNumber.contains(number)) {
|
const auto registerDescriptorIt = this->registerDescriptorsByGdbNumber.find(number);
|
||||||
return this->registerDescriptorsByGdbNumber.at(number);
|
if (registerDescriptorIt.has_value()) {
|
||||||
|
return (*registerDescriptorIt)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Exception("Unknown register from GDB - register number (" + std::to_string(number)
|
throw Exception(
|
||||||
+ ") not mapped to any GDB register descriptor.");
|
"Unknown register from GDB - register number (" + std::to_string(number)
|
||||||
|
+ ") not mapped to any GDB register descriptor."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TargetRegisterDescriptor& TargetDescriptor::getTargetRegisterDescriptorFromNumber(
|
const TargetRegisterDescriptor& TargetDescriptor::getTargetRegisterDescriptorFromNumber(
|
||||||
GdbRegisterNumber number
|
GdbRegisterNumber number
|
||||||
) const {
|
) const {
|
||||||
if (this->targetRegisterDescriptorsByGdbNumber.contains(number)) {
|
const auto targetRegisterDescriptorIt = this->targetRegisterDescriptorsByGdbNumber.find(number);
|
||||||
return this->targetRegisterDescriptorsByGdbNumber.at(number);
|
if (targetRegisterDescriptorIt.has_value()) {
|
||||||
|
return (*targetRegisterDescriptorIt)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Exception("Unknown register from GDB - register number (" + std::to_string(number)
|
throw Exception(
|
||||||
+ ") not mapped to any target register descriptor.");
|
"Unknown register from GDB - register number (" + std::to_string(number)
|
||||||
|
+ ") not mapped to any target register descriptor."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<GdbRegisterNumber>& TargetDescriptor::getRegisterNumbers() const {
|
const std::vector<GdbRegisterNumber>& TargetDescriptor::getRegisterNumbers() const {
|
||||||
@@ -55,7 +61,7 @@ namespace Bloom::DebugServer::Gdb::AvrGdb
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TargetDescriptor::loadRegisterMappings() {
|
void TargetDescriptor::loadRegisterMappings() {
|
||||||
auto& registerDescriptorsByType = this->targetDescriptor.registerDescriptorsByType;
|
const auto& registerDescriptorsByType = this->targetDescriptor.registerDescriptorsByType;
|
||||||
if (!registerDescriptorsByType.contains(TargetRegisterType::STATUS_REGISTER)) {
|
if (!registerDescriptorsByType.contains(TargetRegisterType::STATUS_REGISTER)) {
|
||||||
throw Exception("Missing status register descriptor");
|
throw Exception("Missing status register descriptor");
|
||||||
}
|
}
|
||||||
@@ -68,7 +74,8 @@ namespace Bloom::DebugServer::Gdb::AvrGdb
|
|||||||
throw Exception("Missing program counter register descriptor");
|
throw Exception("Missing program counter register descriptor");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!registerDescriptorsByType.contains(TargetRegisterType::GENERAL_PURPOSE_REGISTER)
|
if (
|
||||||
|
!registerDescriptorsByType.contains(TargetRegisterType::GENERAL_PURPOSE_REGISTER)
|
||||||
|| registerDescriptorsByType.at(TargetRegisterType::GENERAL_PURPOSE_REGISTER).size() != 32
|
|| registerDescriptorsByType.at(TargetRegisterType::GENERAL_PURPOSE_REGISTER).size() != 32
|
||||||
) {
|
) {
|
||||||
throw Exception("Unexpected general purpose register count");
|
throw Exception("Unexpected general purpose register count");
|
||||||
@@ -136,9 +143,7 @@ namespace Bloom::DebugServer::Gdb::AvrGdb
|
|||||||
"Stack Pointer Register"
|
"Stack Pointer Register"
|
||||||
);
|
);
|
||||||
|
|
||||||
this->registerDescriptorsByGdbNumber.insert(
|
this->registerDescriptorsByGdbNumber.insert(std::pair(stackPointerDescriptor.number, stackPointerDescriptor));
|
||||||
std::pair(stackPointerDescriptor.number, stackPointerDescriptor)
|
|
||||||
);
|
|
||||||
this->targetRegisterDescriptorsByGdbNumber.insert(std::pair(
|
this->targetRegisterDescriptorsByGdbNumber.insert(std::pair(
|
||||||
stackPointerDescriptor.number,
|
stackPointerDescriptor.number,
|
||||||
*(registerDescriptorsByType.at(TargetRegisterType::STACK_POINTER).begin())
|
*(registerDescriptorsByType.at(TargetRegisterType::STACK_POINTER).begin())
|
||||||
|
|||||||
@@ -477,14 +477,13 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
|||||||
const auto startAddress = descriptor.startAddress.value();
|
const auto startAddress = descriptor.startAddress.value();
|
||||||
const auto endAddress = startAddress + (descriptor.size - 1);
|
const auto endAddress = startAddress + (descriptor.size - 1);
|
||||||
|
|
||||||
if (!addressRangeByType.contains(descriptor.type)) {
|
const auto addressRangeit = addressRangeByType.find(descriptor.type);
|
||||||
auto addressRange = AddressRange();
|
|
||||||
addressRange.first = startAddress;
|
if (addressRangeit == addressRangeByType.end()) {
|
||||||
addressRange.second = endAddress;
|
addressRangeByType[descriptor.type] = AddressRange(startAddress, endAddress);
|
||||||
addressRangeByType[descriptor.type] = addressRange;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
auto& addressRange = addressRangeByType[descriptor.type];
|
auto& addressRange = addressRangeit->second;
|
||||||
|
|
||||||
if (startAddress < addressRange.first) {
|
if (startAddress < addressRange.first) {
|
||||||
addressRange.first = startAddress;
|
addressRange.first = startAddress;
|
||||||
@@ -869,14 +868,17 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
|||||||
|
|
||||||
std::optional<Avr8ConfigVariant> EdbgAvr8Interface::resolveConfigVariant() {
|
std::optional<Avr8ConfigVariant> EdbgAvr8Interface::resolveConfigVariant() {
|
||||||
if (this->family.has_value()) {
|
if (this->family.has_value()) {
|
||||||
auto configVariantsByFamily = EdbgAvr8Interface::getConfigVariantsByFamilyAndPhysicalInterface();
|
const auto configVariantsByFamily = EdbgAvr8Interface::getConfigVariantsByFamilyAndPhysicalInterface();
|
||||||
|
const auto configVariantsByPhysicalInterfaceIt = configVariantsByFamily.find(*(this->family));
|
||||||
|
|
||||||
if (configVariantsByFamily.contains(this->family.value())) {
|
if (configVariantsByPhysicalInterfaceIt != configVariantsByFamily.end()) {
|
||||||
auto configVariantsByPhysicalInterface = configVariantsByFamily
|
const auto& configVariantsByPhysicalInterface = configVariantsByPhysicalInterfaceIt->second;
|
||||||
.at(this->family.value());
|
const auto configVariantIt = configVariantsByPhysicalInterface.find(
|
||||||
|
this->targetConfig->physicalInterface
|
||||||
|
);
|
||||||
|
|
||||||
if (configVariantsByPhysicalInterface.contains(this->targetConfig->physicalInterface)) {
|
if (configVariantIt != configVariantsByPhysicalInterface.end()) {
|
||||||
return configVariantsByPhysicalInterface.at(this->targetConfig->physicalInterface);
|
return configVariantIt->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -894,14 +896,15 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
|||||||
* variant. Users are required to specify the exact target name in their config, when using the JTAG
|
* variant. Users are required to specify the exact target name in their config, when using the JTAG
|
||||||
* physical interface. That way, this->family will be set by the time resolveConfigVariant() is called.
|
* physical interface. That way, this->family will be set by the time resolveConfigVariant() is called.
|
||||||
*/
|
*/
|
||||||
static std::map<PhysicalInterface, Avr8ConfigVariant> physicalInterfacesToConfigVariants = {
|
static const std::map<PhysicalInterface, Avr8ConfigVariant> physicalInterfacesToConfigVariants = {
|
||||||
{PhysicalInterface::DEBUG_WIRE, Avr8ConfigVariant::DEBUG_WIRE},
|
{PhysicalInterface::DEBUG_WIRE, Avr8ConfigVariant::DEBUG_WIRE},
|
||||||
{PhysicalInterface::PDI, Avr8ConfigVariant::XMEGA},
|
{PhysicalInterface::PDI, Avr8ConfigVariant::XMEGA},
|
||||||
{PhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
{PhysicalInterface::UPDI, Avr8ConfigVariant::UPDI},
|
||||||
};
|
};
|
||||||
|
const auto configVariantIt = physicalInterfacesToConfigVariants.find(this->targetConfig->physicalInterface);
|
||||||
|
|
||||||
if (physicalInterfacesToConfigVariants.contains(this->targetConfig->physicalInterface)) {
|
if (configVariantIt != physicalInterfacesToConfigVariants.end()) {
|
||||||
return physicalInterfacesToConfigVariants.at(this->targetConfig->physicalInterface);
|
return configVariantIt->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,20 +74,28 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
|||||||
explicit Avr8CommandFailure(
|
explicit Avr8CommandFailure(
|
||||||
const std::string& message,
|
const std::string& message,
|
||||||
const ResponseFrames::Avr8Generic::Avr8GenericResponseFrame& responseFrame
|
const ResponseFrames::Avr8Generic::Avr8GenericResponseFrame& responseFrame
|
||||||
): TargetOperationFailure(message) {
|
)
|
||||||
|
: TargetOperationFailure(message)
|
||||||
|
{
|
||||||
this->message = message;
|
this->message = message;
|
||||||
|
|
||||||
if (
|
if (responseFrame.payload.size() == 3) {
|
||||||
responseFrame.payload.size() == 3
|
/*
|
||||||
&& this->failureCodeToDescription.contains(static_cast<Avr8CommandFailureCode>(responseFrame.payload[2]))
|
* The response includes a failure code - lookup the corresponding description and append it to the
|
||||||
) {
|
* exception message.
|
||||||
this->code = static_cast<Avr8CommandFailureCode>(responseFrame.payload[2]);
|
*/
|
||||||
this->message += " - Failure reason: " + this->failureCodeToDescription.at(*(this->code));
|
const auto failureCode = static_cast<Avr8CommandFailureCode>(responseFrame.payload[2]);
|
||||||
|
const auto failureCodeDescriptionIt = this->failureCodeToDescription.find(failureCode);
|
||||||
|
|
||||||
|
if (failureCodeDescriptionIt != this->failureCodeToDescription.end()) {
|
||||||
|
this->code = failureCode;
|
||||||
|
this->message += " - Failure reason: " + failureCodeDescriptionIt->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static inline auto failureCodeToDescription = std::map<Avr8CommandFailureCode, std::string>({
|
static const inline auto failureCodeToDescription = std::map<Avr8CommandFailureCode, std::string>({
|
||||||
{Avr8CommandFailureCode::DEBUGWIRE_PHYSICAL_ERROR, "debugWIRE physical error"},
|
{Avr8CommandFailureCode::DEBUGWIRE_PHYSICAL_ERROR, "debugWIRE physical error"},
|
||||||
{Avr8CommandFailureCode::JTAGM_FAILED_TO_INITIALISE, "JTAGM failed to initialise"},
|
{Avr8CommandFailureCode::JTAGM_FAILED_TO_INITIALISE, "JTAGM failed to initialise"},
|
||||||
{Avr8CommandFailureCode::UNKNOWN_JTAG_ERROR, "JTAGM did something strange"},
|
{Avr8CommandFailureCode::UNKNOWN_JTAG_ERROR, "JTAGM did something strange"},
|
||||||
|
|||||||
@@ -7,14 +7,17 @@ namespace Bloom
|
|||||||
using namespace Bloom::Events;
|
using namespace Bloom::Events;
|
||||||
|
|
||||||
std::set<Events::EventType> EventListener::getRegisteredEventTypes() {
|
std::set<Events::EventType> EventListener::getRegisteredEventTypes() {
|
||||||
auto lock = this->registeredEventTypes.acquireLock();
|
const auto lock = this->registeredEventTypes.acquireLock();
|
||||||
return this->registeredEventTypes.getValue();
|
return this->registeredEventTypes.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventListener::registerEvent(SharedGenericEventPointer event) {
|
void EventListener::registerEvent(SharedGenericEventPointer event) {
|
||||||
Logger::debug("Event \"" + event->getName() + "\" (" + std::to_string(event->id)
|
Logger::debug(
|
||||||
+ ") registered for listener " + this->name);
|
"Event \"" + event->getName() + "\" (" + std::to_string(event->id) + ") registered for listener "
|
||||||
auto queueLock = this->eventQueueByEventType.acquireLock();
|
+ this->name
|
||||||
|
);
|
||||||
|
|
||||||
|
const auto queueLock = this->eventQueueByEventType.acquireLock();
|
||||||
auto& eventQueueByType = this->eventQueueByEventType.getValue();
|
auto& eventQueueByType = this->eventQueueByEventType.getValue();
|
||||||
|
|
||||||
eventQueueByType[event->getType()].push(std::move(event));
|
eventQueueByType[event->getType()].push(std::move(event));
|
||||||
@@ -26,33 +29,29 @@ namespace Bloom
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EventListener::waitAndDispatch(int msTimeout) {
|
void EventListener::waitAndDispatch(int msTimeout) {
|
||||||
auto queueLock = this->eventQueueByEventType.acquireLock();
|
{
|
||||||
auto& eventQueueByType = this->eventQueueByEventType.getValue();
|
auto queueLock = this->eventQueueByEventType.acquireLock();
|
||||||
auto registeredEventTypes = this->getRegisteredEventTypes();
|
const auto& eventQueueByType = this->eventQueueByEventType.getValue();
|
||||||
std::optional<SharedGenericEventPointer> event;
|
const auto registeredEventTypes = this->getRegisteredEventTypes();
|
||||||
|
std::optional<SharedGenericEventPointer> event;
|
||||||
|
|
||||||
auto eventsFound = [®isteredEventTypes, &event, &eventQueueByType]() -> bool {
|
const auto eventsFound = [®isteredEventTypes, &event, &eventQueueByType]() -> bool {
|
||||||
for (auto& eventQueue: eventQueueByType) {
|
for (auto& eventQueue: eventQueueByType) {
|
||||||
if (registeredEventTypes.contains(eventQueue.first) && !eventQueue.second.empty()) {
|
if (registeredEventTypes.contains(eventQueue.first) && !eventQueue.second.empty()) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (msTimeout > 0) {
|
||||||
|
this->eventQueueByEventTypeCV.wait_for(queueLock, std::chrono::milliseconds(msTimeout), eventsFound);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this->eventQueueByEventTypeCV.wait(queueLock, eventsFound);
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (msTimeout > 0) {
|
|
||||||
this->eventQueueByEventTypeCV.wait_for(queueLock, std::chrono::milliseconds(msTimeout), eventsFound);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
this->eventQueueByEventTypeCV.wait(queueLock, eventsFound);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* We don't want the dispatch to block other threads from registering more events. We don't need the
|
|
||||||
* lock anymore so it's fine to release it here.
|
|
||||||
*/
|
|
||||||
queueLock.unlock();
|
|
||||||
|
|
||||||
this->dispatchCurrentEvents();
|
this->dispatchCurrentEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,9 +59,8 @@ namespace Bloom
|
|||||||
Logger::debug("Dispatching event " + event->getName() + " (" + std::to_string(event->id) + ").");
|
Logger::debug("Dispatching event " + event->getName() + " (" + std::to_string(event->id) + ").");
|
||||||
|
|
||||||
// Dispatch the event to all registered handlers
|
// Dispatch the event to all registered handlers
|
||||||
auto mappingLock = this->eventTypeToCallbacksMapping.acquireLock();
|
const auto mappingLock = this->eventTypeToCallbacksMapping.acquireLock();
|
||||||
auto& callbacks = this->eventTypeToCallbacksMapping.getValue().find(event->getType())->second;
|
const auto& callbacks = this->eventTypeToCallbacksMapping.getValue().find(event->getType())->second;
|
||||||
mappingLock.unlock();
|
|
||||||
|
|
||||||
for (auto& callback : callbacks) {
|
for (auto& callback : callbacks) {
|
||||||
callback(*(event.get()));
|
callback(*(event.get()));
|
||||||
@@ -78,7 +76,7 @@ namespace Bloom
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<SharedGenericEventPointer> EventListener::getEvents() {
|
std::vector<SharedGenericEventPointer> EventListener::getEvents() {
|
||||||
auto queueLock = this->eventQueueByEventType.acquireLock();
|
const auto queueLock = this->eventQueueByEventType.acquireLock();
|
||||||
auto& eventQueueByType = this->eventQueueByEventType.getValue();
|
auto& eventQueueByType = this->eventQueueByEventType.getValue();
|
||||||
std::vector<SharedGenericEventPointer> output;
|
std::vector<SharedGenericEventPointer> output;
|
||||||
|
|
||||||
@@ -101,7 +99,7 @@ namespace Bloom
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EventListener::clearAllCallbacks() {
|
void EventListener::clearAllCallbacks() {
|
||||||
auto lock = this->eventTypeToCallbacksMapping.acquireLock();
|
const auto lock = this->eventTypeToCallbacksMapping.acquireLock();
|
||||||
this->eventTypeToCallbacksMapping.getValue().clear();
|
this->eventTypeToCallbacksMapping.getValue().clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,13 +75,13 @@ namespace Bloom
|
|||||||
*/
|
*/
|
||||||
template<class EventType>
|
template<class EventType>
|
||||||
void registerEventType() {
|
void registerEventType() {
|
||||||
auto registeredEventTypesLock = this->registeredEventTypes.acquireLock();
|
const auto registeredEventTypesLock = this->registeredEventTypes.acquireLock();
|
||||||
this->registeredEventTypes.getValue().insert(EventType::type);
|
this->registeredEventTypes.getValue().insert(EventType::type);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class EventType>
|
template<class EventType>
|
||||||
void deRegisterEventType() {
|
void deRegisterEventType() {
|
||||||
auto registeredEventTypesLock = this->registeredEventTypes.acquireLock();
|
const auto registeredEventTypesLock = this->registeredEventTypes.acquireLock();
|
||||||
this->registeredEventTypes.getValue().erase(EventType::type);
|
this->registeredEventTypes.getValue().erase(EventType::type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ namespace Bloom
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
auto mappingLock = this->eventTypeToCallbacksMapping.acquireLock();
|
const auto mappingLock = this->eventTypeToCallbacksMapping.acquireLock();
|
||||||
auto& mapping = this->eventTypeToCallbacksMapping.getValue();
|
auto& mapping = this->eventTypeToCallbacksMapping.getValue();
|
||||||
|
|
||||||
mapping[EventType::type].push_back(parentCallback);
|
mapping[EventType::type].push_back(parentCallback);
|
||||||
@@ -137,7 +137,7 @@ namespace Bloom
|
|||||||
);
|
);
|
||||||
|
|
||||||
{
|
{
|
||||||
auto mappingLock = this->eventTypeToCallbacksMapping.acquireLock();
|
const auto mappingLock = this->eventTypeToCallbacksMapping.acquireLock();
|
||||||
auto& mapping = this->eventTypeToCallbacksMapping.getValue();
|
auto& mapping = this->eventTypeToCallbacksMapping.getValue();
|
||||||
|
|
||||||
if (mapping.contains(EventType::type)) {
|
if (mapping.contains(EventType::type)) {
|
||||||
@@ -150,7 +150,7 @@ namespace Bloom
|
|||||||
this->registeredEventTypes.getValue().erase(EventType::type);
|
this->registeredEventTypes.getValue().erase(EventType::type);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto queueLock = this->eventQueueByEventType.acquireLock();
|
const auto queueLock = this->eventQueueByEventType.acquireLock();
|
||||||
auto& eventQueueByType = this->eventQueueByEventType.getValue();
|
auto& eventQueueByType = this->eventQueueByEventType.getValue();
|
||||||
|
|
||||||
if (eventQueueByType.contains(EventType::type)) {
|
if (eventQueueByType.contains(EventType::type)) {
|
||||||
|
|||||||
@@ -37,11 +37,22 @@ namespace Bloom
|
|||||||
return this->flippedMap.find(key) != this->flippedMap.end();
|
return this->flippedMap.find(key) != this->flippedMap.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto find(const TypeA& key) const {
|
||||||
|
const auto valueIt = this->map.find(key);
|
||||||
|
return valueIt != this->map.end() ? std::optional(valueIt) : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto find(const TypeB& key) const {
|
||||||
|
const auto valueIt = this->flippedMap.find(key);
|
||||||
|
return valueIt != this->flippedMap.end() ? std::optional(valueIt) : std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<TypeB> valueAt(const TypeA& key) const {
|
std::optional<TypeB> valueAt(const TypeA& key) const {
|
||||||
std::optional<TypeB> output;
|
std::optional<TypeB> output;
|
||||||
|
|
||||||
if (this->contains(key)) {
|
const auto valueIt = this->map.find(key);
|
||||||
output = this->map.find(key)->second;
|
if (valueIt != this->map.end()) {
|
||||||
|
output = valueIt->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
@@ -50,8 +61,9 @@ namespace Bloom
|
|||||||
std::optional<TypeA> valueAt(const TypeB& key) const {
|
std::optional<TypeA> valueAt(const TypeB& key) const {
|
||||||
std::optional<TypeA> output;
|
std::optional<TypeA> output;
|
||||||
|
|
||||||
if (this->contains(key)) {
|
const auto valueIt = this->flippedMap.find(key);
|
||||||
output = this->flippedMap.find(key)->second;
|
if (valueIt != this->flippedMap.end()) {
|
||||||
|
output = valueIt->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|||||||
@@ -42,9 +42,10 @@ namespace Bloom
|
|||||||
}
|
}
|
||||||
|
|
||||||
static auto cachedResultsByProcessId = std::map<::pid_t, bool>();
|
static auto cachedResultsByProcessId = std::map<::pid_t, bool>();
|
||||||
|
const auto cachedResultIt = cachedResultsByProcessId.find(*processId);
|
||||||
|
|
||||||
if (cachedResultsByProcessId.contains(*processId)) {
|
if (cachedResultIt != cachedResultsByProcessId.end()) {
|
||||||
return cachedResultsByProcessId.at(*processId);
|
return cachedResultIt->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start with the parent process and walk the tree until we find CLion
|
// Start with the parent process and walk the tree until we find CLion
|
||||||
|
|||||||
@@ -480,35 +480,41 @@ namespace Bloom
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<QString> previouslySelectedVariantName = (this->previouslySelectedVariant.has_value()) ?
|
std::optional<QString> previouslySelectedVariantName = (this->previouslySelectedVariant.has_value())
|
||||||
std::optional(QString::fromStdString(this->previouslySelectedVariant->name).toLower())
|
? std::optional(QString::fromStdString(this->previouslySelectedVariant->name).toLower())
|
||||||
: std::nullopt;
|
: std::nullopt;
|
||||||
|
|
||||||
if (
|
if (previouslySelectedVariantName.has_value()) {
|
||||||
previouslySelectedVariantName.has_value()
|
const auto previouslySelectedVariantIt = this->supportedVariantsByName.find(*previouslySelectedVariantName);
|
||||||
&& this->supportedVariantsByName.contains(previouslySelectedVariantName.value())
|
|
||||||
) {
|
|
||||||
this->selectVariant(&(this->supportedVariantsByName.at(previouslySelectedVariantName.value())));
|
|
||||||
|
|
||||||
} else if (this->targetConfig.variantName.has_value()) {
|
if (previouslySelectedVariantIt != this->supportedVariantsByName.end()) {
|
||||||
auto selectedVariantName = QString::fromStdString(this->targetConfig.variantName.value());
|
this->selectVariant(&(previouslySelectedVariantIt->second));
|
||||||
if (this->supportedVariantsByName.contains(selectedVariantName)) {
|
return;
|
||||||
// The user has specified a valid variant name in their config file, so use that as the default
|
|
||||||
this->selectVariant(&(this->supportedVariantsByName.at(selectedVariantName)));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
Logger::error("Invalid target variant name \"" + this->targetConfig.variantName.value()
|
|
||||||
+ "\" - no such variant with the given name was found.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->selectedVariant == nullptr) {
|
if (this->targetConfig.variantName.has_value()) {
|
||||||
/*
|
const auto variantIt = this->supportedVariantsByName.find(
|
||||||
* Given that we haven't been able to select a variant at this point, we will just fall back to the first
|
QString::fromStdString(*this->targetConfig.variantName)
|
||||||
* one that is available.
|
);
|
||||||
*/
|
|
||||||
this->selectVariant(&(this->supportedVariantsByName.begin()->second));
|
if (variantIt != this->supportedVariantsByName.end()) {
|
||||||
|
// The user has specified a valid variant name in their config file, so use that as the default
|
||||||
|
this->selectVariant(&(variantIt->second));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Logger::error(
|
||||||
|
"Invalid target variant name \"" + this->targetConfig.variantName.value()
|
||||||
|
+ "\" - no such variant with the given name was found."
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given that we haven't been able to select a variant at this point, we will just fall back to the first
|
||||||
|
* one that is available.
|
||||||
|
*/
|
||||||
|
this->selectVariant(&(this->supportedVariantsByName.begin()->second));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsightWindow::selectVariant(const TargetVariant* variant) {
|
void InsightWindow::selectVariant(const TargetVariant* variant) {
|
||||||
@@ -598,19 +604,22 @@ namespace Bloom
|
|||||||
|
|
||||||
// Target memory inspection panes
|
// Target memory inspection panes
|
||||||
auto* bottomPanelLayout = this->bottomPanel->layout();
|
auto* bottomPanelLayout = this->bottomPanel->layout();
|
||||||
if (this->targetDescriptor.memoryDescriptorsByType.contains(TargetMemoryType::RAM)) {
|
|
||||||
|
// We only support inspection of RAM and EEPROM, for now.
|
||||||
|
const auto ramDescriptorIt = this->targetDescriptor.memoryDescriptorsByType.find(TargetMemoryType::RAM);
|
||||||
|
const auto eepromDescriptorIt = this->targetDescriptor.memoryDescriptorsByType.find(TargetMemoryType::EEPROM);
|
||||||
|
|
||||||
|
if (ramDescriptorIt != this->targetDescriptor.memoryDescriptorsByType.end()) {
|
||||||
if (!this->insightProjectSettings.ramInspectionPaneState.has_value()) {
|
if (!this->insightProjectSettings.ramInspectionPaneState.has_value()) {
|
||||||
this->insightProjectSettings.ramInspectionPaneState = PaneState(false, true, std::nullopt);
|
this->insightProjectSettings.ramInspectionPaneState = PaneState(false, true, std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& ramDescriptor = this->targetDescriptor.memoryDescriptorsByType.at(TargetMemoryType::RAM);
|
|
||||||
|
|
||||||
if (!memoryInspectionPaneSettingsByMemoryType.contains(TargetMemoryType::RAM)) {
|
if (!memoryInspectionPaneSettingsByMemoryType.contains(TargetMemoryType::RAM)) {
|
||||||
memoryInspectionPaneSettingsByMemoryType[TargetMemoryType::RAM] = TargetMemoryInspectionPaneSettings();
|
memoryInspectionPaneSettingsByMemoryType[TargetMemoryType::RAM] = TargetMemoryInspectionPaneSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->ramInspectionPane = new TargetMemoryInspectionPane(
|
this->ramInspectionPane = new TargetMemoryInspectionPane(
|
||||||
ramDescriptor,
|
ramDescriptorIt->second,
|
||||||
memoryInspectionPaneSettingsByMemoryType[TargetMemoryType::RAM],
|
memoryInspectionPaneSettingsByMemoryType[TargetMemoryType::RAM],
|
||||||
*(this->insightProjectSettings.ramInspectionPaneState),
|
*(this->insightProjectSettings.ramInspectionPaneState),
|
||||||
this->bottomPanel
|
this->bottomPanel
|
||||||
@@ -641,19 +650,17 @@ namespace Bloom
|
|||||||
this->onRamInspectionPaneStateChanged();
|
this->onRamInspectionPaneStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->targetDescriptor.memoryDescriptorsByType.contains(TargetMemoryType::EEPROM)) {
|
if (eepromDescriptorIt != this->targetDescriptor.memoryDescriptorsByType.end()) {
|
||||||
if (!this->insightProjectSettings.eepromInspectionPaneState.has_value()) {
|
if (!this->insightProjectSettings.eepromInspectionPaneState.has_value()) {
|
||||||
this->insightProjectSettings.eepromInspectionPaneState = PaneState(false, true, std::nullopt);
|
this->insightProjectSettings.eepromInspectionPaneState = PaneState(false, true, std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& eepromDescriptor = this->targetDescriptor.memoryDescriptorsByType.at(TargetMemoryType::EEPROM);
|
|
||||||
|
|
||||||
if (!memoryInspectionPaneSettingsByMemoryType.contains(TargetMemoryType::EEPROM)) {
|
if (!memoryInspectionPaneSettingsByMemoryType.contains(TargetMemoryType::EEPROM)) {
|
||||||
memoryInspectionPaneSettingsByMemoryType[TargetMemoryType::EEPROM] = TargetMemoryInspectionPaneSettings();
|
memoryInspectionPaneSettingsByMemoryType[TargetMemoryType::EEPROM] = TargetMemoryInspectionPaneSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
this->eepromInspectionPane = new TargetMemoryInspectionPane(
|
this->eepromInspectionPane = new TargetMemoryInspectionPane(
|
||||||
eepromDescriptor,
|
eepromDescriptorIt->second,
|
||||||
memoryInspectionPaneSettingsByMemoryType[TargetMemoryType::EEPROM],
|
memoryInspectionPaneSettingsByMemoryType[TargetMemoryType::EEPROM],
|
||||||
*(this->insightProjectSettings.eepromInspectionPaneState),
|
*(this->insightProjectSettings.eepromInspectionPaneState),
|
||||||
this->bottomPanel
|
this->bottomPanel
|
||||||
|
|||||||
@@ -94,9 +94,11 @@ namespace Bloom
|
|||||||
}
|
}
|
||||||
|
|
||||||
QWidget* UiLoader::createWidget(const QString& className, QWidget* parent, const QString& name) {
|
QWidget* UiLoader::createWidget(const QString& className, QWidget* parent, const QString& name) {
|
||||||
if (this->customWidgetConstructorsByWidgetName.contains(className)) {
|
const auto widgetContructorIt = this->customWidgetConstructorsByWidgetName.find(className);
|
||||||
|
|
||||||
|
if (widgetContructorIt != this->customWidgetConstructorsByWidgetName.end()) {
|
||||||
// This is a custom widget - call the mapped constructor
|
// This is a custom widget - call the mapped constructor
|
||||||
return this->customWidgetConstructorsByWidgetName.at(className)(parent, name);
|
return widgetContructorIt->second(parent, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return QUiLoader::createWidget(className, parent, name);
|
return QUiLoader::createWidget(className, parent, name);
|
||||||
|
|||||||
@@ -312,8 +312,9 @@ namespace Bloom::Widgets
|
|||||||
}
|
}
|
||||||
|
|
||||||
QPointF ByteItemGraphicsScene::getByteItemPositionByAddress(std::uint32_t address) {
|
QPointF ByteItemGraphicsScene::getByteItemPositionByAddress(std::uint32_t address) {
|
||||||
if (this->byteItemsByAddress.contains(address)) {
|
const auto byteItemIt = this->byteItemsByAddress.find(address);
|
||||||
return this->byteItemsByAddress.at(address)->pos();
|
if (byteItemIt != this->byteItemsByAddress.end()) {
|
||||||
|
return byteItemIt->second->pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
return QPointF();
|
return QPointF();
|
||||||
@@ -623,12 +624,13 @@ namespace Bloom::Widgets
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto* annotationItem : this->annotationItems) {
|
for (auto* annotationItem : this->annotationItems) {
|
||||||
if (!this->byteItemsByAddress.contains(annotationItem->startAddress)) {
|
const auto firstByteItemIt = this->byteItemsByAddress.find(annotationItem->startAddress);
|
||||||
|
if (firstByteItemIt == this->byteItemsByAddress.end()) {
|
||||||
annotationItem->hide();
|
annotationItem->hide();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto firstByteItemPosition = this->byteItemsByAddress.at(annotationItem->startAddress)->pos();
|
const auto firstByteItemPosition = firstByteItemIt->second->pos();
|
||||||
|
|
||||||
if (annotationItem->position == AnnotationItemPosition::TOP) {
|
if (annotationItem->position == AnnotationItemPosition::TOP) {
|
||||||
annotationItem->setPos(
|
annotationItem->setPos(
|
||||||
@@ -646,7 +648,6 @@ namespace Bloom::Widgets
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ByteItemGraphicsScene::onTargetStateChanged(Targets::TargetState newState) {
|
void ByteItemGraphicsScene::onTargetStateChanged(Targets::TargetState newState) {
|
||||||
using Targets::TargetState;
|
|
||||||
this->targetState = newState;
|
this->targetState = newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,22 +42,24 @@ namespace Bloom::Widgets
|
|||||||
this->endAddressInput->text().toUInt(nullptr, 16)
|
this->endAddressInput->text().toUInt(nullptr, 16)
|
||||||
);
|
);
|
||||||
this->memoryRegion.addressRangeInputType = this->getSelectedAddressInputType();
|
this->memoryRegion.addressRangeInputType = this->getSelectedAddressInputType();
|
||||||
this->memoryRegion.addressRange =
|
this->memoryRegion.addressRange = this->memoryRegion.addressRangeInputType == AddressType::RELATIVE
|
||||||
this->memoryRegion.addressRangeInputType == AddressType::RELATIVE ?
|
? this->convertRelativeToAbsoluteAddressRange(inputAddressRange)
|
||||||
this->convertRelativeToAbsoluteAddressRange(inputAddressRange) : inputAddressRange;
|
: inputAddressRange;
|
||||||
|
|
||||||
auto selectedDataTypeOptionName = this->dataTypeInput->currentData().toString();
|
const auto selectedDataTypeIt = FocusedRegionItem::dataTypeOptionsByName.find(
|
||||||
if (FocusedRegionItem::dataTypeOptionsByName.contains(selectedDataTypeOptionName)) {
|
this->dataTypeInput->currentData().toString()
|
||||||
this->memoryRegion.dataType = FocusedRegionItem::dataTypeOptionsByName.at(
|
);
|
||||||
selectedDataTypeOptionName
|
|
||||||
).dataType;
|
if (selectedDataTypeIt != FocusedRegionItem::dataTypeOptionsByName.end()) {
|
||||||
|
this->memoryRegion.dataType = selectedDataTypeIt->second.dataType;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto selectedEndiannessOptionName = this->endiannessInput->currentData().toString();
|
const auto selectedEndiannessIt = FocusedRegionItem::endiannessOptionsByName.find(
|
||||||
if (FocusedRegionItem::endiannessOptionsByName.contains(selectedEndiannessOptionName)) {
|
this->endiannessInput->currentData().toString()
|
||||||
this->memoryRegion.endianness = FocusedRegionItem::endiannessOptionsByName.at(
|
);
|
||||||
selectedEndiannessOptionName
|
|
||||||
).endianness;
|
if (selectedEndiannessIt != FocusedRegionItem::endiannessOptionsByName.end()) {
|
||||||
|
this->memoryRegion.endianness = selectedEndiannessIt->second.endianness;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -176,9 +176,12 @@ namespace Bloom::Widgets
|
|||||||
}
|
}
|
||||||
|
|
||||||
AddressType RegionItem::getSelectedAddressInputType() const {
|
AddressType RegionItem::getSelectedAddressInputType() const {
|
||||||
auto selectedAddressTypeOptionName = this->addressTypeInput->currentData().toString();
|
const auto selectedAddressTypeIt = RegionItem::addressRangeTypeOptionsByName.find(
|
||||||
if (RegionItem::addressRangeTypeOptionsByName.contains(selectedAddressTypeOptionName)) {
|
this->addressTypeInput->currentData().toString()
|
||||||
return RegionItem::addressRangeTypeOptionsByName.at(selectedAddressTypeOptionName).addressType;
|
);
|
||||||
|
|
||||||
|
if (selectedAddressTypeIt != RegionItem::addressRangeTypeOptionsByName.end()) {
|
||||||
|
return selectedAddressTypeIt->second.addressType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return AddressType::ABSOLUTE;
|
return AddressType::ABSOLUTE;
|
||||||
|
|||||||
@@ -395,7 +395,8 @@ namespace Bloom::Widgets
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (const auto& focusedRegion : this->settings.focusedMemoryRegions) {
|
for (const auto& focusedRegion : this->settings.focusedMemoryRegions) {
|
||||||
if (!this->targetMemoryDescriptor.addressRange.contains(focusedRegion.addressRange)
|
if (
|
||||||
|
!this->targetMemoryDescriptor.addressRange.contains(focusedRegion.addressRange)
|
||||||
|| regionIntersects(focusedRegion)
|
|| regionIntersects(focusedRegion)
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
@@ -405,7 +406,8 @@ namespace Bloom::Widgets
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& excludedRegion : this->settings.excludedMemoryRegions) {
|
for (const auto& excludedRegion : this->settings.excludedMemoryRegions) {
|
||||||
if (!this->targetMemoryDescriptor.addressRange.contains(excludedRegion.addressRange)
|
if (
|
||||||
|
!this->targetMemoryDescriptor.addressRange.contains(excludedRegion.addressRange)
|
||||||
|| regionIntersects(excludedRegion)
|
|| regionIntersects(excludedRegion)
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -243,10 +243,10 @@ namespace Bloom::Widgets
|
|||||||
const auto& descriptor = targetRegister.descriptor;
|
const auto& descriptor = targetRegister.descriptor;
|
||||||
|
|
||||||
for (const auto& registerGroupWidget : this->registerGroupWidgets) {
|
for (const auto& registerGroupWidget : this->registerGroupWidgets) {
|
||||||
if (registerGroupWidget->registerWidgetsMappedByDescriptor.contains(descriptor)) {
|
const auto registerWidgetit = registerGroupWidget->registerWidgetsMappedByDescriptor.find(descriptor);
|
||||||
registerGroupWidget->registerWidgetsMappedByDescriptor.at(
|
|
||||||
descriptor
|
if (registerWidgetit != registerGroupWidget->registerWidgetsMappedByDescriptor.end()) {
|
||||||
)->setRegisterValue(targetRegister);
|
registerWidgetit->second->setRegisterValue(targetRegister);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,9 +73,10 @@ namespace Bloom::Widgets::InsightTargetWidgets
|
|||||||
|
|
||||||
void TargetPackageWidget::updatePinStates(const Targets::TargetPinStateMapping& pinStatesByNumber) {
|
void TargetPackageWidget::updatePinStates(const Targets::TargetPinStateMapping& pinStatesByNumber) {
|
||||||
for (auto& pinWidget : this->pinWidgets) {
|
for (auto& pinWidget : this->pinWidgets) {
|
||||||
auto pinNumber = pinWidget->getPinNumber();
|
const auto pinStateIt = pinStatesByNumber.find(pinWidget->getPinNumber());
|
||||||
if (pinStatesByNumber.contains(pinNumber)) {
|
|
||||||
pinWidget->updatePinState(pinStatesByNumber.at(pinNumber));
|
if (pinStateIt != pinStatesByNumber.end()) {
|
||||||
|
pinWidget->updatePinState(pinStateIt->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,9 +19,10 @@ namespace Bloom
|
|||||||
if (::sigwait(&signalSet, &signalNumber) == 0) {
|
if (::sigwait(&signalSet, &signalNumber) == 0) {
|
||||||
Logger::debug("SIGNAL " + std::to_string(signalNumber) + " received");
|
Logger::debug("SIGNAL " + std::to_string(signalNumber) + " received");
|
||||||
|
|
||||||
if (this->handlersBySignalNum.contains(signalNumber)) {
|
const auto handlerIt = this->handlersBySignalNum.find(signalNumber);
|
||||||
|
if (handlerIt != this->handlersBySignalNum.end()) {
|
||||||
// We have a registered handler for this signal.
|
// We have a registered handler for this signal.
|
||||||
this->handlersBySignalNum.at(signalNumber)();
|
handlerIt->second();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,12 +355,12 @@ namespace Bloom::TargetController
|
|||||||
|
|
||||||
for (auto mapIt = avr8PdMapping.begin(); mapIt != avr8PdMapping.end(); mapIt++) {
|
for (auto mapIt = avr8PdMapping.begin(); mapIt != avr8PdMapping.end(); mapIt++) {
|
||||||
// Each target signature maps to an array of targets, as numerous targets can possess the same signature.
|
// Each target signature maps to an array of targets, as numerous targets can possess the same signature.
|
||||||
auto targets = mapIt.value().toArray();
|
const auto targets = mapIt.value().toArray();
|
||||||
|
|
||||||
for (auto targetIt = targets.begin(); targetIt != targets.end(); targetIt++) {
|
for (auto targetIt = targets.begin(); targetIt != targets.end(); targetIt++) {
|
||||||
auto targetName = targetIt->toObject().find("targetName").value().toString()
|
const auto targetName = targetIt->toObject().find("targetName").value().toString()
|
||||||
.toLower().toStdString();
|
.toLower().toStdString();
|
||||||
auto targetSignatureHex = mapIt.key().toLower().toStdString();
|
const auto targetSignatureHex = mapIt.key().toLower().toStdString();
|
||||||
|
|
||||||
if (!mapping.contains(targetName)) {
|
if (!mapping.contains(targetName)) {
|
||||||
mapping.insert({
|
mapping.insert({
|
||||||
@@ -395,7 +395,9 @@ namespace Bloom::TargetController
|
|||||||
const auto commandType = command->getType();
|
const auto commandType = command->getType();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!this->commandHandlersByCommandType.contains(commandType)) {
|
const auto commandHandlerIt = this->commandHandlersByCommandType.find(commandType);
|
||||||
|
|
||||||
|
if (commandHandlerIt == this->commandHandlersByCommandType.end()) {
|
||||||
throw Exception("No handler registered for this command.");
|
throw Exception("No handler registered for this command.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,10 +417,7 @@ namespace Bloom::TargetController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->registerCommandResponse(
|
this->registerCommandResponse(commandId, commandHandlerIt->second(*(command.get())));
|
||||||
commandId,
|
|
||||||
this->commandHandlersByCommandType.at(commandType)(*(command.get()))
|
|
||||||
);
|
|
||||||
|
|
||||||
} catch (const Exception& exception) {
|
} catch (const Exception& exception) {
|
||||||
this->registerCommandResponse(
|
this->registerCommandResponse(
|
||||||
@@ -543,23 +542,26 @@ namespace Bloom::TargetController
|
|||||||
auto debugToolName = this->environmentConfig.debugToolConfig.name;
|
auto debugToolName = this->environmentConfig.debugToolConfig.name;
|
||||||
auto targetName = this->environmentConfig.targetConfig.name;
|
auto targetName = this->environmentConfig.targetConfig.name;
|
||||||
|
|
||||||
static auto supportedDebugTools = this->getSupportedDebugTools();
|
static const auto supportedDebugTools = this->getSupportedDebugTools();
|
||||||
static auto supportedTargets = this->getSupportedTargets();
|
static const auto supportedTargets = this->getSupportedTargets();
|
||||||
|
|
||||||
if (!supportedDebugTools.contains(debugToolName)) {
|
const auto debugToolIt = supportedDebugTools.find(debugToolName);
|
||||||
|
const auto targetIt = supportedTargets.find(targetName);
|
||||||
|
|
||||||
|
if (debugToolIt == supportedDebugTools.end()) {
|
||||||
throw Exceptions::InvalidConfig(
|
throw Exceptions::InvalidConfig(
|
||||||
"Debug tool name (\"" + debugToolName + "\") not recognised. Please check your configuration!"
|
"Debug tool name (\"" + debugToolName + "\") not recognised. Please check your configuration!"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!supportedTargets.contains(targetName)) {
|
if (targetIt == supportedTargets.end()) {
|
||||||
throw Exceptions::InvalidConfig(
|
throw Exceptions::InvalidConfig(
|
||||||
"Target name (\"" + targetName + "\") not recognised. Please check your configuration!"
|
"Target name (\"" + targetName + "\") not recognised. Please check your configuration!"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initiate debug tool and target
|
// Initiate debug tool and target
|
||||||
this->debugTool = supportedDebugTools.at(debugToolName)();
|
this->debugTool = debugToolIt->second();
|
||||||
|
|
||||||
Logger::info("Connecting to debug tool");
|
Logger::info("Connecting to debug tool");
|
||||||
this->debugTool->init();
|
this->debugTool->init();
|
||||||
@@ -568,7 +570,7 @@ namespace Bloom::TargetController
|
|||||||
Logger::info("Debug tool name: " + this->debugTool->getName());
|
Logger::info("Debug tool name: " + this->debugTool->getName());
|
||||||
Logger::info("Debug tool serial: " + this->debugTool->getSerialNumber());
|
Logger::info("Debug tool serial: " + this->debugTool->getSerialNumber());
|
||||||
|
|
||||||
this->target = supportedTargets.at(targetName)();
|
this->target = targetIt->second();
|
||||||
|
|
||||||
if (!this->target->isDebugToolSupported(this->debugTool.get())) {
|
if (!this->target->isDebugToolSupported(this->debugTool.get())) {
|
||||||
throw Exceptions::InvalidConfig(
|
throw Exceptions::InvalidConfig(
|
||||||
@@ -634,16 +636,17 @@ namespace Bloom::TargetController
|
|||||||
auto startAddress = registerDescriptor.startAddress.value_or(0);
|
auto startAddress = registerDescriptor.startAddress.value_or(0);
|
||||||
auto endAddress = startAddress + (registerDescriptor.size - 1);
|
auto endAddress = startAddress + (registerDescriptor.size - 1);
|
||||||
|
|
||||||
if (!this->registerAddressRangeByMemoryType.contains(registerDescriptor.memoryType)) {
|
const auto registerAddressRangeIt = this->registerAddressRangeByMemoryType.find(
|
||||||
auto addressRange = TargetMemoryAddressRange();
|
registerDescriptor.memoryType
|
||||||
addressRange.startAddress = startAddress;
|
);
|
||||||
addressRange.endAddress = endAddress;
|
|
||||||
|
if (registerAddressRangeIt == this->registerAddressRangeByMemoryType.end()) {
|
||||||
this->registerAddressRangeByMemoryType.insert(
|
this->registerAddressRangeByMemoryType.insert(
|
||||||
std::pair(registerDescriptor.memoryType, addressRange)
|
std::pair(registerDescriptor.memoryType, TargetMemoryAddressRange(startAddress, endAddress))
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
auto& addressRange = this->registerAddressRangeByMemoryType.at(registerDescriptor.memoryType);
|
auto& addressRange = registerAddressRangeIt->second;
|
||||||
|
|
||||||
if (startAddress < addressRange.startAddress) {
|
if (startAddress < addressRange.startAddress) {
|
||||||
addressRange.startAddress = startAddress;
|
addressRange.startAddress = startAddress;
|
||||||
@@ -666,24 +669,28 @@ namespace Bloom::TargetController
|
|||||||
) {
|
) {
|
||||||
auto output = TargetRegisterDescriptors();
|
auto output = TargetRegisterDescriptors();
|
||||||
|
|
||||||
if (this->registerAddressRangeByMemoryType.contains(memoryType)
|
const auto registerAddressRangeIt = this->registerAddressRangeByMemoryType.find(memoryType);
|
||||||
&& this->registerDescriptorsByMemoryType.contains(memoryType)
|
const auto registerDescriptorsIt = this->registerDescriptorsByMemoryType.find(memoryType);
|
||||||
|
|
||||||
|
if (
|
||||||
|
registerAddressRangeIt != this->registerAddressRangeByMemoryType.end()
|
||||||
|
&& registerDescriptorsIt != this->registerDescriptorsByMemoryType.end()
|
||||||
) {
|
) {
|
||||||
auto& registersAddressRange = this->registerAddressRangeByMemoryType.at(memoryType);
|
const auto& registersAddressRange = registerAddressRangeIt->second;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(startAddress <= registersAddressRange.startAddress && endAddress >= registersAddressRange.startAddress)
|
(startAddress <= registersAddressRange.startAddress && endAddress >= registersAddressRange.startAddress)
|
||||||
|| (startAddress <= registersAddressRange.endAddress && endAddress >= registersAddressRange.startAddress)
|
|| (startAddress <= registersAddressRange.endAddress && endAddress >= registersAddressRange.startAddress)
|
||||||
) {
|
) {
|
||||||
auto& registerDescriptors = this->registerDescriptorsByMemoryType.at(memoryType);
|
const auto& registerDescriptors = this->registerDescriptorsByMemoryType.at(memoryType);
|
||||||
|
|
||||||
for (const auto& registerDescriptor : registerDescriptors) {
|
for (const auto& registerDescriptor : registerDescriptors) {
|
||||||
if (!registerDescriptor.startAddress.has_value() || registerDescriptor.size < 1) {
|
if (!registerDescriptor.startAddress.has_value() || registerDescriptor.size < 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto registerStartAddress = registerDescriptor.startAddress.value();
|
const auto registerStartAddress = registerDescriptor.startAddress.value();
|
||||||
auto registerEndAddress = registerStartAddress + registerDescriptor.size;
|
const auto registerEndAddress = registerStartAddress + registerDescriptor.size;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(startAddress <= registerStartAddress && endAddress >= registerStartAddress)
|
(startAddress <= registerStartAddress && endAddress >= registerStartAddress)
|
||||||
|
|||||||
@@ -454,12 +454,14 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::map<int, TargetPinState> Avr8::getPinStates(int variantId) {
|
std::map<int, TargetPinState> Avr8::getPinStates(int variantId) {
|
||||||
if (!this->targetVariantsById.contains(variantId)) {
|
const auto targetVariantIt = this->targetVariantsById.find(variantId);
|
||||||
|
|
||||||
|
if (targetVariantIt == this->targetVariantsById.end()) {
|
||||||
throw Exception("Invalid target variant ID");
|
throw Exception("Invalid target variant ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<int, TargetPinState> output;
|
std::map<int, TargetPinState> output;
|
||||||
auto& variant = this->targetVariantsById.at(variantId);
|
const auto& variant = targetVariantIt->second;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To prevent the number of memory reads we perform here, we cache the data and map it by start address.
|
* To prevent the number of memory reads we perform here, we cache the data and map it by start address.
|
||||||
@@ -471,24 +473,28 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
|
|||||||
* will be considered when the need for it becomes apparent.
|
* will be considered when the need for it becomes apparent.
|
||||||
*/
|
*/
|
||||||
std::map<std::uint16_t, TargetMemoryBuffer> cachedMemoryByStartAddress;
|
std::map<std::uint16_t, TargetMemoryBuffer> cachedMemoryByStartAddress;
|
||||||
auto readMemoryBitset = [this, &cachedMemoryByStartAddress] (std::uint16_t startAddress) {
|
const auto readMemoryBitset = [this, &cachedMemoryByStartAddress] (std::uint16_t startAddress) {
|
||||||
if (!cachedMemoryByStartAddress.contains(startAddress)) {
|
auto cachedByteIt = cachedMemoryByStartAddress.find(startAddress);
|
||||||
cachedMemoryByStartAddress.insert(
|
|
||||||
|
if (cachedByteIt == cachedMemoryByStartAddress.end()) {
|
||||||
|
cachedByteIt = cachedMemoryByStartAddress.insert(
|
||||||
std::pair(
|
std::pair(
|
||||||
startAddress,
|
startAddress,
|
||||||
this->readMemory(TargetMemoryType::RAM, startAddress, 1)
|
this->readMemory(TargetMemoryType::RAM, startAddress, 1)
|
||||||
)
|
)
|
||||||
);
|
).first;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::bitset<std::numeric_limits<unsigned char>::digits>(
|
return std::bitset<std::numeric_limits<unsigned char>::digits>(
|
||||||
cachedMemoryByStartAddress.at(startAddress).at(0)
|
cachedByteIt->second.at(0)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const auto& [pinNumber, pinDescriptor] : variant.pinDescriptorsByNumber) {
|
for (const auto& [pinNumber, pinDescriptor] : variant.pinDescriptorsByNumber) {
|
||||||
if (this->padDescriptorsByName.contains(pinDescriptor.padName)) {
|
const auto padIt = this->padDescriptorsByName.find(pinDescriptor.padName);
|
||||||
auto& pad = this->padDescriptorsByName.at(pinDescriptor.padName);
|
|
||||||
|
if (padIt != this->padDescriptorsByName.end()) {
|
||||||
|
const auto& pad = padIt->second;
|
||||||
|
|
||||||
if (!pad.gpioPinNumber.has_value()) {
|
if (!pad.gpioPinNumber.has_value()) {
|
||||||
continue;
|
continue;
|
||||||
@@ -526,12 +532,15 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Avr8::setPinState(const TargetPinDescriptor& pinDescriptor, const TargetPinState& state) {
|
void Avr8::setPinState(const TargetPinDescriptor& pinDescriptor, const TargetPinState& state) {
|
||||||
auto variantId = pinDescriptor.variantId;
|
const auto targetVariantIt = this->targetVariantsById.find(pinDescriptor.variantId);
|
||||||
if (!this->targetVariantsById.contains(variantId)) {
|
|
||||||
|
if (targetVariantIt == this->targetVariantsById.end()) {
|
||||||
throw Exception("Invalid target variant ID");
|
throw Exception("Invalid target variant ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this->padDescriptorsByName.contains(pinDescriptor.padName)) {
|
const auto padDescriptorIt = this->padDescriptorsByName.find(pinDescriptor.padName);
|
||||||
|
|
||||||
|
if (padDescriptorIt == this->padDescriptorsByName.end()) {
|
||||||
throw Exception("Unknown pad");
|
throw Exception("Unknown pad");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,8 +548,8 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
|
|||||||
throw Exception("Missing IO direction state");
|
throw Exception("Missing IO direction state");
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& variant = this->targetVariantsById.at(variantId);
|
const auto& variant = targetVariantIt->second;
|
||||||
const auto& padDescriptor = this->padDescriptorsByName.at(pinDescriptor.padName);
|
const auto& padDescriptor = padDescriptorIt->second;
|
||||||
auto ioState = state.ioState;
|
auto ioState = state.ioState;
|
||||||
|
|
||||||
if (state.ioDirection == TargetPinState::IoDirection::INPUT) {
|
if (state.ioDirection == TargetPinState::IoDirection::INPUT) {
|
||||||
|
|||||||
@@ -28,8 +28,10 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Avr8() = default;
|
explicit Avr8() = default;
|
||||||
Avr8(std::string name, const TargetSignature& signature): name(std::move(name)) {
|
Avr8(std::string name, const TargetSignature& signature)
|
||||||
this->id = signature;
|
: name(std::move(name))
|
||||||
|
, Target(signature)
|
||||||
|
{
|
||||||
this->initFromTargetDescriptionFile();
|
this->initFromTargetDescriptionFile();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,11 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto physicalInterfaceName = String::asciiToLower(targetNode["physicalInterface"].as<std::string>());
|
const auto physicalInterfaceName = String::asciiToLower(targetNode["physicalInterface"].as<std::string>());
|
||||||
|
const auto physicalInterfaceIt = Avr8TargetConfig::debugPhysicalInterfacesByConfigName.find(
|
||||||
|
physicalInterfaceName
|
||||||
|
);
|
||||||
|
|
||||||
if (!Avr8TargetConfig::debugPhysicalInterfacesByConfigName.contains(physicalInterfaceName)) {
|
if (physicalInterfaceIt == Avr8TargetConfig::debugPhysicalInterfacesByConfigName.end()) {
|
||||||
throw InvalidConfig(
|
throw InvalidConfig(
|
||||||
"Invalid physical interface provided (\"" + physicalInterfaceName + "\") for AVR8 target. "
|
"Invalid physical interface provided (\"" + physicalInterfaceName + "\") for AVR8 target. "
|
||||||
"See " + Paths::homeDomainName() + "/docs/configuration/avr8-physical-interfaces for valid physical "
|
"See " + Paths::homeDomainName() + "/docs/configuration/avr8-physical-interfaces for valid physical "
|
||||||
@@ -27,7 +30,7 @@ namespace Bloom::Targets::Microchip::Avr::Avr8Bit
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->physicalInterface = Avr8TargetConfig::debugPhysicalInterfacesByConfigName.at(physicalInterfaceName);
|
this->physicalInterface = physicalInterfaceIt->second;
|
||||||
|
|
||||||
// The 'manageDwenFuseBit' param used to be 'updateDwenFuseBit' - we still support the old, for now.
|
// The 'manageDwenFuseBit' param used to be 'updateDwenFuseBit' - we still support the old, for now.
|
||||||
if (targetNode["updateDwenFuseBit"]) {
|
if (targetNode["updateDwenFuseBit"]) {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,9 @@ namespace Bloom::Targets::Microchip::Avr
|
|||||||
class Target: public ::Bloom::Targets::Target
|
class Target: public ::Bloom::Targets::Target
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Target() = default;
|
explicit Target(std::optional<TargetSignature> id = std::nullopt)
|
||||||
|
: id(id)
|
||||||
|
{};
|
||||||
|
|
||||||
std::string getHumanReadableId() override {
|
std::string getHumanReadableId() override {
|
||||||
return this->getId().toHex();
|
return this->getId().toHex();
|
||||||
@@ -21,10 +23,6 @@ namespace Bloom::Targets::Microchip::Avr
|
|||||||
protected:
|
protected:
|
||||||
std::optional<TargetSignature> id;
|
std::optional<TargetSignature> id;
|
||||||
|
|
||||||
virtual void setId(const TargetSignature& id) {
|
|
||||||
this->id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual TargetSignature getId() = 0;
|
virtual TargetSignature getId() = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user