Refactored CMSIS-DAP Response command classes and introduced the ExpectedResponseType alias in CMSIS-DAP commands.
This commit is contained in:
@@ -5,11 +5,29 @@
|
||||
|
||||
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/Command.hpp"
|
||||
|
||||
#include "AvrResponse.hpp"
|
||||
|
||||
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
{
|
||||
/**
|
||||
* AVR CMSIS-DAP vendor command.
|
||||
*/
|
||||
class AvrCommand: public Command
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* AVR CMSIS-DAP vendor commands *do not* directly result in an AvrResponse object. The device will respond
|
||||
* immediately upon receiving this command, simply acknowledging receipt of the command.
|
||||
*
|
||||
* If a response is expected to follow upon the execution of the AVR command, it must be requested from the
|
||||
* device, using the AvrResponseCommand (see that class declaration for more info).
|
||||
*
|
||||
* For this reason, the ExpectedResponseType for this command is just the standard Response type.
|
||||
*
|
||||
* For more on the purpose of this alias, see the Command class.
|
||||
*/
|
||||
using ExpectedResponseType = Response;
|
||||
|
||||
AvrCommand(
|
||||
std::size_t fragmentCount,
|
||||
std::size_t fragmentNumber,
|
||||
|
||||
@@ -6,9 +6,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
{
|
||||
using namespace Bloom::Exceptions;
|
||||
|
||||
void AvrEvent::init(const std::vector<unsigned char>& rawResponse) {
|
||||
Response::init(rawResponse);
|
||||
|
||||
AvrEvent::AvrEvent(const std::vector<unsigned char>& rawResponse): Response(rawResponse) {
|
||||
if (this->getResponseId() != 0x82) {
|
||||
throw Exception("Failed to construct AvrEvent object - invalid response ID.");
|
||||
}
|
||||
|
||||
@@ -23,20 +23,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
class AvrEvent: public Response
|
||||
{
|
||||
public:
|
||||
AvrEvent() = default;
|
||||
|
||||
/**
|
||||
* Construct an AVRResponse object from a Response object.
|
||||
*
|
||||
* @param response
|
||||
*/
|
||||
void init(const Response& response) {
|
||||
auto rawData = response.getData();
|
||||
rawData.insert(rawData.begin(), response.getResponseId());
|
||||
this->init(rawData);
|
||||
}
|
||||
|
||||
void init(const std::vector<unsigned char>& rawResponse) override;
|
||||
explicit AvrEvent(const std::vector<unsigned char>& rawResponse);
|
||||
|
||||
[[nodiscard]] const std::vector<unsigned char>& getEventData() const {
|
||||
return this->eventData;
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/Command.hpp"
|
||||
#include "AvrEvent.hpp"
|
||||
|
||||
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap
|
||||
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
{
|
||||
class AvrEventCommand: public Command
|
||||
{
|
||||
public:
|
||||
using ExpectedResponseType = AvrEvent;
|
||||
|
||||
AvrEventCommand() {
|
||||
this->setCommandId(0x82);
|
||||
}
|
||||
|
||||
@@ -6,9 +6,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
{
|
||||
using namespace Bloom::Exceptions;
|
||||
|
||||
void AvrResponse::init(const std::vector<unsigned char>& rawResponse) {
|
||||
Response::init(rawResponse);
|
||||
|
||||
AvrResponse::AvrResponse(const std::vector<unsigned char>& rawResponse): Response(rawResponse) {
|
||||
if (this->getResponseId() != 0x81) {
|
||||
throw Exception("Failed to construct AvrResponse object - invalid response ID.");
|
||||
}
|
||||
|
||||
@@ -10,20 +10,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
class AvrResponse: public Response
|
||||
{
|
||||
public:
|
||||
AvrResponse() = default;
|
||||
|
||||
/**
|
||||
* Construct an AVRResponse object from a Response object.
|
||||
*
|
||||
* @param response
|
||||
*/
|
||||
void init(const Response& response) {
|
||||
auto rawData = response.getData();
|
||||
rawData.insert(rawData.begin(), response.getResponseId());
|
||||
this->init(rawData);
|
||||
}
|
||||
|
||||
void init(const std::vector<unsigned char>& rawResponse) override;
|
||||
explicit AvrResponse(const std::vector<unsigned char>& rawResponse);
|
||||
|
||||
[[nodiscard]] std::uint8_t getFragmentNumber() const {
|
||||
return this->fragmentNumber;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/Command.hpp"
|
||||
|
||||
#include "AvrResponse.hpp"
|
||||
|
||||
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
{
|
||||
/**
|
||||
@@ -12,8 +14,9 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
*
|
||||
* Responses to AVR commands are not automatically sent from the device, they must be requested from the device.
|
||||
*
|
||||
* An AvrResponseCommand is a CMSIS-DAP command, used to request a response for an AVR command. In response to an
|
||||
* AvrResponseCommand, the device will send over an AVRResponse, which will contain the response to the AVR command.
|
||||
* An AvrResponseCommand is a CMSIS-DAP vendor command, used to request a response for an AVR command. In response
|
||||
* to an AvrResponseCommand, the device will send over an AvrResponse, which will contain the response to the
|
||||
* AVR command.
|
||||
*
|
||||
* For more information on this, see the 'Embedded Debugger-Based Tools Protocols User's Guide'
|
||||
* document, by Microchip. Link provided in the AtmelICE device class declaration.
|
||||
@@ -23,6 +26,8 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
class AvrResponseCommand: public Command
|
||||
{
|
||||
public:
|
||||
using ExpectedResponseType = AvrResponse;
|
||||
|
||||
AvrResponseCommand() {
|
||||
this->setCommandId(0x81);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
|
||||
using Bloom::Targets::TargetBreakCause;
|
||||
|
||||
void BreakEvent::init(const AvrEvent& event) {
|
||||
AvrEvent::init(event);
|
||||
BreakEvent::BreakEvent(const AvrEvent& event): AvrEvent(event) {
|
||||
const auto& data = this->getEventData();
|
||||
|
||||
if (data.size() < 8) {
|
||||
|
||||
@@ -10,9 +10,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
|
||||
class BreakEvent: public AvrEvent
|
||||
{
|
||||
public:
|
||||
explicit BreakEvent(const AvrEvent& event) {
|
||||
this->init(event);
|
||||
}
|
||||
explicit BreakEvent(const AvrEvent& event);
|
||||
|
||||
[[nodiscard]] std::uint32_t getProgramCounter() const {
|
||||
return this->programCounter;
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg
|
||||
auto response = this->sendCommandAndWaitForResponse(avrCommand);
|
||||
|
||||
if (&avrCommand == &avrCommands.back()) {
|
||||
return *response;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,31 +26,14 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg
|
||||
);
|
||||
}
|
||||
|
||||
Protocols::CmsisDap::Edbg::Avr::AvrResponse EdbgInterface::getAvrResponse() {
|
||||
auto cmsisResponse = this->getResponse();
|
||||
|
||||
if (cmsisResponse->getResponseId() == 0x81) {
|
||||
// This is an AVR_RSP response
|
||||
auto avrResponse = Protocols::CmsisDap::Edbg::Avr::AvrResponse();
|
||||
avrResponse.init(*cmsisResponse);
|
||||
return avrResponse;
|
||||
}
|
||||
|
||||
throw DeviceCommunicationFailure("Unexpected response to AvrResponseCommand from device");
|
||||
}
|
||||
|
||||
std::optional<Protocols::CmsisDap::Edbg::Avr::AvrEvent> EdbgInterface::requestAvrEvent() {
|
||||
this->sendCommand(AvrEventCommand());
|
||||
auto cmsisResponse = this->getResponse();
|
||||
auto avrEventResponse = this->sendCommandAndWaitForResponse(Avr::AvrEventCommand());
|
||||
|
||||
if (cmsisResponse->getResponseId() == 0x82) {
|
||||
// This is an AVR_EVT response
|
||||
auto avrEvent = Protocols::CmsisDap::Edbg::Avr::AvrEvent();
|
||||
avrEvent.init(*cmsisResponse);
|
||||
return avrEvent.getEventDataSize() > 0 ? std::optional(avrEvent) : std::nullopt;
|
||||
if (avrEventResponse.getResponseId() != 0x82) {
|
||||
throw DeviceCommunicationFailure("Unexpected response to AvrEventCommand from device");
|
||||
}
|
||||
|
||||
throw DeviceCommunicationFailure("Unexpected response to AvrEventCommand from device");
|
||||
return avrEventResponse.getEventDataSize() > 0 ? std::optional(avrEventResponse) : std::nullopt;
|
||||
}
|
||||
|
||||
std::vector<Protocols::CmsisDap::Edbg::Avr::AvrResponse> EdbgInterface::requestAvrResponses() {
|
||||
@@ -59,34 +42,32 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg
|
||||
std::vector<Protocols::CmsisDap::Edbg::Avr::AvrResponse> responses;
|
||||
AvrResponseCommand responseCommand;
|
||||
|
||||
this->sendCommand(responseCommand);
|
||||
auto response = this->getAvrResponse();
|
||||
responses.push_back(response);
|
||||
int fragmentCount = response.getFragmentCount();
|
||||
auto avrResponse = this->sendCommandAndWaitForResponse(responseCommand);
|
||||
responses.push_back(avrResponse);
|
||||
const auto fragmentCount = avrResponse.getFragmentCount();
|
||||
|
||||
while (responses.size() < fragmentCount) {
|
||||
// There are more response packets
|
||||
this->sendCommand(responseCommand);
|
||||
response = this->getAvrResponse();
|
||||
auto avrResponse = this->sendCommandAndWaitForResponse(responseCommand);
|
||||
|
||||
if (response.getFragmentCount() != fragmentCount) {
|
||||
if (avrResponse.getFragmentCount() != fragmentCount) {
|
||||
throw DeviceCommunicationFailure(
|
||||
"Failed to fetch AVRResponse objects - invalid fragment count returned."
|
||||
);
|
||||
}
|
||||
|
||||
if (response.getFragmentCount() == 0 && response.getFragmentNumber() == 0) {
|
||||
if (avrResponse.getFragmentCount() == 0 && avrResponse.getFragmentNumber() == 0) {
|
||||
throw DeviceCommunicationFailure(
|
||||
"Failed to fetch AVRResponse objects - unexpected empty response"
|
||||
);
|
||||
}
|
||||
|
||||
if (response.getFragmentNumber() == 0) {
|
||||
if (avrResponse.getFragmentNumber() == 0) {
|
||||
// End of response data ( &this packet can be ignored)
|
||||
break;
|
||||
}
|
||||
|
||||
responses.push_back(response);
|
||||
responses.push_back(avrResponse);
|
||||
}
|
||||
|
||||
return responses;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#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/AvrResponse.hpp"
|
||||
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/AvrEventCommand.hpp"
|
||||
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/AvrEvent.hpp"
|
||||
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/VendorSpecific/EDBG/AVR/CommandFrames/AvrCommandFrame.hpp"
|
||||
@@ -48,8 +49,6 @@ namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg
|
||||
const std::vector<Avr::AvrCommand>& avrCommands
|
||||
);
|
||||
|
||||
Protocols::CmsisDap::Edbg::Avr::AvrResponse getAvrResponse();
|
||||
|
||||
template<class CommandFrameType>
|
||||
typename CommandFrameType::ResponseFrameType sendAvrCommandFrameAndWaitForResponseFrame(
|
||||
const CommandFrameType& avrCommandFrame
|
||||
|
||||
Reference in New Issue
Block a user