Removed using namespace directive for class member function definitions in source files

This commit is contained in:
Nav
2022-02-05 15:32:08 +00:00
parent 9bbc534973
commit 53a3c815d7
116 changed files with 13113 additions and 12664 deletions

View File

@@ -6,45 +6,47 @@
#include "src/DebugToolDrivers/Protocols/CMSIS-DAP/Response.hpp"
#include "src/TargetController/Exceptions/DeviceCommunicationFailure.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap
{
using namespace Bloom::Exceptions;
void CmsisDapInterface::sendCommand(const Command& cmsisDapCommand) {
if (this->msSendCommandDelay.count() > 0) {
using namespace std::chrono;
std::int64_t now = duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count();
std::int64_t difference = (now - this->lastCommandSentTimeStamp);
void CmsisDapInterface::sendCommand(const Command& cmsisDapCommand) {
if (this->msSendCommandDelay.count() > 0) {
using namespace std::chrono;
std::int64_t now = duration_cast<milliseconds>(high_resolution_clock::now().time_since_epoch()).count();
std::int64_t difference = (now - this->lastCommandSentTimeStamp);
if (difference < this->msSendCommandDelay.count()) {
std::this_thread::sleep_for(milliseconds(this->msSendCommandDelay.count() - difference));
if (difference < this->msSendCommandDelay.count()) {
std::this_thread::sleep_for(milliseconds(this->msSendCommandDelay.count() - difference));
}
this->lastCommandSentTimeStamp = now;
}
this->lastCommandSentTimeStamp = now;
this->getUsbHidInterface().write(static_cast<std::vector<unsigned char>>(cmsisDapCommand));
}
this->getUsbHidInterface().write(static_cast<std::vector<unsigned char>>(cmsisDapCommand));
}
std::unique_ptr<Response> CmsisDapInterface::getResponse() {
auto rawResponse = this->getUsbHidInterface().read(10000);
std::unique_ptr<Response> CmsisDapInterface::getResponse() {
auto rawResponse = this->getUsbHidInterface().read(10000);
if (rawResponse.empty()) {
throw DeviceCommunicationFailure("Empty CMSIS-DAP response received");
}
if (rawResponse.empty()) {
throw DeviceCommunicationFailure("Empty CMSIS-DAP response received");
auto response = std::make_unique<Response>(Response());
response->init(rawResponse);
return response;
}
auto response = std::make_unique<Response>(Response());
response->init(rawResponse);
return response;
}
std::unique_ptr<Response> CmsisDapInterface::sendCommandAndWaitForResponse(const Command& cmsisDapCommand) {
this->sendCommand(cmsisDapCommand);
auto response = this->getResponse();
std::unique_ptr<Response> CmsisDapInterface::sendCommandAndWaitForResponse(const Command& cmsisDapCommand) {
this->sendCommand(cmsisDapCommand);
auto response = this->getResponse();
if (response->getResponseId() != cmsisDapCommand.getCommandId()) {
// This response is not what we were expecting
throw DeviceCommunicationFailure("Unexpected response to CMSIS-DAP command.");
}
if (response->getResponseId() != cmsisDapCommand.getCommandId()) {
// This response is not what we were expecting
throw DeviceCommunicationFailure("Unexpected response to CMSIS-DAP command.");
return response;
}
return response;
}

View File

@@ -1,11 +1,12 @@
#include "Command.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap
{
Command::operator std::vector<unsigned char>() const {
auto rawCommand = std::vector<unsigned char>(1, this->getCommandId());
auto commandData = this->getData();
rawCommand.insert(rawCommand.end(), commandData.begin(), commandData.end());
Command::operator std::vector<unsigned char> () const {
auto rawCommand = std::vector<unsigned char>(1, this->getCommandId());
auto commandData = this->getData();
rawCommand.insert(rawCommand.end(), commandData.begin(), commandData.end());
return rawCommand;
return rawCommand;
}
}

View File

@@ -2,13 +2,14 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap
{
void Response::init(const std::vector<unsigned char>& rawResponse) {
if (rawResponse.empty()) {
throw Exceptions::Exception("Failed to process CMSIS-DAP response - invalid response");
}
void Response::init(const std::vector<unsigned char>& rawResponse) {
if (rawResponse.empty()) {
throw Exceptions::Exception("Failed to process CMSIS-DAP response - invalid response");
this->setResponseId(rawResponse[0]);
this->setData(std::vector<unsigned char>(rawResponse.begin() + 1, rawResponse.end()));
}
this->setResponseId(rawResponse[0]);
this->setData(std::vector<unsigned char>(rawResponse.begin() + 1, rawResponse.end()));
}

View File

@@ -1,22 +1,23 @@
#include "AvrCommand.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
std::vector<unsigned char> AvrCommand::getData() const {
std::vector<unsigned char> data;
auto commandPacket = this->getCommandPacket();
std::size_t commandPacketSize = commandPacket.size();
data.resize(3 + commandPacketSize);
// FragmentInfo byte
data[0] = static_cast<unsigned char>((this->getFragmentNumber() << 4) | this->getFragmentCount());
std::vector<unsigned char> AvrCommand::getData() const {
std::vector<unsigned char> data;
auto commandPacket = this->getCommandPacket();
std::size_t commandPacketSize = commandPacket.size();
data.resize(3 + commandPacketSize);
// FragmentInfo byte
data[0] = static_cast<unsigned char>((this->getFragmentNumber() << 4) | this->getFragmentCount());
// Size byte
data[1] = static_cast<unsigned char>(commandPacketSize >> 8);
data[2] = static_cast<unsigned char>(commandPacketSize & 0xFF);
// Size byte
data[1] = (unsigned char) (commandPacketSize >> 8);
data[2] = (unsigned char) (commandPacketSize & 0xFF);
if (commandPacketSize > 0) {
data.insert(data.begin() + 3, commandPacket.begin(), commandPacket.end());
}
if (commandPacketSize > 0) {
data.insert(data.begin() + 3, commandPacket.begin(), commandPacket.end());
return data;
}
return data;
}

View File

@@ -2,48 +2,50 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
using namespace Bloom::Exceptions;
void AvrEvent::init(const std::vector<unsigned char>& rawResponse) {
Response::init(rawResponse);
void AvrEvent::init(const std::vector<unsigned char>& rawResponse) {
Response::init(rawResponse);
if (this->getResponseId() != 0x82) {
throw Exception("Failed to construct AvrEvent object - invalid response ID.");
}
if (this->getResponseId() != 0x82) {
throw Exception("Failed to construct AvrEvent object - invalid response ID.");
}
auto& responseData = this->getData();
const auto& responseData = this->getData();
if (responseData.size() < 2) {
// All AVR_EVT responses should consist of at least two bytes (excluding the AVR_EVT ID)
throw Exception("Failed to construct AvrEvent object - AVR_EVT response "
"returned no additional data.");
}
if (responseData.size() < 2) {
// All AVR_EVT responses should consist of at least two bytes (excluding the AVR_EVT ID)
throw Exception("Failed to construct AvrEvent object - AVR_EVT response "
"returned no additional data.");
}
// Response size is two bytes, MSB
auto responsePacketSize = static_cast<std::size_t>((responseData[0] << 8) | responseData[1]);
// Response size is two bytes, MSB
auto responsePacketSize = static_cast<std::size_t>((responseData[0] << 8) | responseData[1]);
if (responseData.size() < 2) {
// All AVR_EVT responses should consist of at least two bytes (excluding the AVR_EVT ID)
throw Exception("Failed to construct AvrEvent object - AVR_EVT response "
"contained invalid event data size.");
}
if (responseData.size() < 2) {
// All AVR_EVT responses should consist of at least two bytes (excluding the AVR_EVT ID)
throw Exception("Failed to construct AvrEvent object - AVR_EVT response "
"contained invalid event data size.");
}
auto eventData = std::vector<unsigned char>();
auto eventData = std::vector<unsigned char>();
/*
* Ignore the SOF, protocol version &handler id and sequence ID (with all make up 5 bytes in total, 7 when
* you include the two size bytes)
*/
eventData.insert(
eventData.end(),
responseData.begin() + 7,
responseData.begin() + 7 + static_cast<long>(responsePacketSize)
);
/*
* Ignore the SOF, protocol version &handler id and sequence ID (with all make up 5 bytes in total, 7 when
* you include the two size bytes)
*/
eventData.insert(
eventData.end(),
responseData.begin() + 7,
responseData.begin() + 7 + static_cast<long>(responsePacketSize)
);
this->setEventData(eventData);
this->setEventData(eventData);
if (!eventData.empty()) {
this->eventId = eventData[0];
if (!eventData.empty()) {
this->eventId = eventData[0];
}
}
}

View File

@@ -2,40 +2,42 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
using namespace Bloom::Exceptions;
void AvrResponse::init(const std::vector<unsigned char>& rawResponse) {
Response::init(rawResponse);
void AvrResponse::init(const std::vector<unsigned char>& rawResponse) {
Response::init(rawResponse);
if (this->getResponseId() != 0x81) {
throw Exception("Failed to construct AvrResponse object - invalid response ID.");
if (this->getResponseId() != 0x81) {
throw Exception("Failed to construct AvrResponse object - invalid response ID.");
}
const auto& responseData = this->getData();
if (responseData.empty()) {
// All AVR responses should contain at least one byte (the fragment info byte)
throw Exception("Failed to construct AvrResponse object - AVR_RSP response "
"returned no additional data");
}
if (responseData[0] == 0x00) {
// This AVR Response contains no data (the device had no data to send), so we can stop here.
return;
}
this->setFragmentCount(static_cast<std::uint8_t>(responseData[0] & 0x0FU));
this->setFragmentNumber(static_cast<std::uint8_t>(responseData[0] >> 4));
// Response size is two bytes, MSB
const auto responsePacketSize = static_cast<std::size_t>((responseData[1] << 8U) + responseData[2]);
std::vector<unsigned char> responsePacket;
responsePacket.resize(responsePacketSize);
for (std::size_t i = 0; i < responsePacketSize; i++) {
responsePacket[i] = responseData[i + 3];
}
this->setResponsePacket(responsePacket);
}
auto& responseData = this->getData();
if (responseData.empty()) {
// All AVR responses should contain at least one byte (the fragment info byte)
throw Exception("Failed to construct AvrResponse object - AVR_RSP response "
"returned no additional data");
}
if (responseData[0] == 0x00) {
// This AVR Response contains no data (the device had no data to send), so we can stop here.
return;
}
this->setFragmentCount(static_cast<std::uint8_t>(responseData[0] & 0x0Fu));
this->setFragmentNumber(static_cast<std::uint8_t>(responseData[0] >> 4));
// Response size is two bytes, MSB
std::size_t responsePacketSize = static_cast<std::size_t>((responseData[1] << 8u) + responseData[2]);
std::vector<unsigned char> responsePacket;
responsePacket.resize(responsePacketSize);
for (std::size_t i = 0; i < responsePacketSize; i++) {
responsePacket[i] = responseData[i + 3];
}
this->setResponsePacket(responsePacket);
}

View File

@@ -3,54 +3,55 @@
#include <bitset>
#include <cmath>
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::Avr8Generic;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr::CommandFrames::Avr8Generic
{
std::vector<unsigned char> ReadMemory::getPayload() const {
/*
* The read memory command consists of 11/11 + (this->bytes / 8) bytes:
* 1. Command ID (0x21 for the general read memory command, 0x22 for reading with a mask)
* 2. Version (0x00)
* 3. Memory type (Avr8MemoryType)
* 4. Start address (4 bytes)
* 5. Number of bytes to read (4 bytes)
* 6. Mask to apply (this->bytes / 8) - only required if we're using the masked read command (command ID 0x22).
*/
auto output = std::vector<unsigned char>(11, 0x00);
output[0] = this->excludedAddresses.empty() ? 0x21 : 0x22;
output[1] = 0x00;
output[2] = static_cast<unsigned char>(this->type);
output[3] = static_cast<unsigned char>(this->address);
output[4] = static_cast<unsigned char>(this->address >> 8);
output[5] = static_cast<unsigned char>(this->address >> 16);
output[6] = static_cast<unsigned char>(this->address >> 24);
output[7] = static_cast<unsigned char>(this->bytes);
output[8] = static_cast<unsigned char>(this->bytes >> 8);
output[9] = static_cast<unsigned char>(this->bytes >> 16);
output[10] = static_cast<unsigned char>(this->bytes >> 24);
std::vector<unsigned char> ReadMemory::getPayload() const {
/*
* The read memory command consists of 11/11 + (this->bytes / 8) bytes:
* 1. Command ID (0x21 for the general read memory command, 0x22 for reading with a mask)
* 2. Version (0x00)
* 3. Memory type (Avr8MemoryType)
* 4. Start address (4 bytes)
* 5. Number of bytes to read (4 bytes)
* 6. Mask to apply (this->bytes / 8) - only required if we're using the masked read command (command ID 0x22).
*/
auto output = std::vector<unsigned char>(11, 0x00);
output[0] = this->excludedAddresses.empty() ? 0x21 : 0x22;
output[1] = 0x00;
output[2] = static_cast<unsigned char>(this->type);
output[3] = static_cast<unsigned char>(this->address);
output[4] = static_cast<unsigned char>(this->address >> 8);
output[5] = static_cast<unsigned char>(this->address >> 16);
output[6] = static_cast<unsigned char>(this->address >> 24);
output[7] = static_cast<unsigned char>(this->bytes);
output[8] = static_cast<unsigned char>(this->bytes >> 8);
output[9] = static_cast<unsigned char>(this->bytes >> 16);
output[10] = static_cast<unsigned char>(this->bytes >> 24);
if (!this->excludedAddresses.empty()) {
const auto endAddress = this->address + (this->bytes - 1);
if (!this->excludedAddresses.empty()) {
const auto endAddress = this->address + (this->bytes - 1);
constexpr auto byteBitSize = std::numeric_limits<unsigned char>::digits;
auto byteBitset = std::bitset<byteBitSize>();
byteBitset.reset();
constexpr auto byteBitSize = std::numeric_limits<unsigned char>::digits;
auto byteBitset = std::bitset<byteBitSize>();
byteBitset.reset();
for (std::uint32_t address = this->address; address <= endAddress; address++) {
auto addressIndex = address - this->address;
auto bitIndex = static_cast<std::size_t>(
addressIndex - (std::floor(addressIndex / byteBitSize) * byteBitSize)
);
for (std::uint32_t address = this->address; address <= endAddress; address++) {
auto addressIndex = address - this->address;
auto bitIndex = static_cast<std::size_t>(
addressIndex - (std::floor(addressIndex / byteBitSize) * byteBitSize)
);
if (!this->excludedAddresses.contains(address)) {
byteBitset[bitIndex] = 1;
}
if (!this->excludedAddresses.contains(address)) {
byteBitset[bitIndex] = 1;
}
if (address > 0 && (bitIndex == 7 || address == endAddress)) {
output.emplace_back(byteBitset.to_ulong());
byteBitset.reset();
if (address > 0 && (bitIndex == 7 || address == endAddress)) {
output.emplace_back(byteBitset.to_ulong());
byteBitset.reset();
}
}
}
}
return output;
return output;
}
}

View File

@@ -2,62 +2,63 @@
#include <math.h>
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
std::vector<AvrCommand> AvrCommandFrame::generateAvrCommands(std::size_t maximumCommandPacketSize) const {
auto rawCommandFrame = static_cast<std::vector<unsigned char>>(*this);
std::size_t commandFrameSize = rawCommandFrame.size();
auto commandsRequired = static_cast<std::size_t>(
ceil(static_cast<float>(commandFrameSize) / static_cast<float>(maximumCommandPacketSize))
);
std::vector<AvrCommand> avrCommands;
std::size_t copiedPacketSize = 0;
for (std::size_t i = 0; i < commandsRequired; i++) {
AvrCommand avrCommand;
avrCommand.setFragmentCount(commandsRequired);
avrCommand.setFragmentNumber(i + 1);
auto commandPacket = avrCommand.getCommandPacket();
// If we're on the last packet, the packet size will be what ever is left of the AvrCommandFrame
std::size_t commandPacketSize = ((i + 1) != commandsRequired) ? maximumCommandPacketSize
: (commandFrameSize - (maximumCommandPacketSize * i));
commandPacket.insert(
commandPacket.end(),
rawCommandFrame.begin() + static_cast<long>(copiedPacketSize),
rawCommandFrame.begin() + static_cast<long>(copiedPacketSize + commandPacketSize)
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
std::vector<AvrCommand> AvrCommandFrame::generateAvrCommands(std::size_t maximumCommandPacketSize) const {
auto rawCommandFrame = static_cast<std::vector<unsigned char>>(*this);
std::size_t commandFrameSize = rawCommandFrame.size();
auto commandsRequired = static_cast<std::size_t>(
ceil(static_cast<float>(commandFrameSize) / static_cast<float>(maximumCommandPacketSize))
);
avrCommand.setCommandPacket(commandPacket);
avrCommands.push_back(avrCommand);
copiedPacketSize += commandPacketSize;
std::vector<AvrCommand> avrCommands;
std::size_t copiedPacketSize = 0;
for (std::size_t i = 0; i < commandsRequired; i++) {
AvrCommand avrCommand;
avrCommand.setFragmentCount(commandsRequired);
avrCommand.setFragmentNumber(i + 1);
auto commandPacket = avrCommand.getCommandPacket();
// If we're on the last packet, the packet size will be what ever is left of the AvrCommandFrame
std::size_t commandPacketSize = ((i + 1) != commandsRequired) ? maximumCommandPacketSize
: (commandFrameSize - (maximumCommandPacketSize * i));
commandPacket.insert(
commandPacket.end(),
rawCommandFrame.begin() + static_cast<long>(copiedPacketSize),
rawCommandFrame.begin() + static_cast<long>(copiedPacketSize + commandPacketSize)
);
avrCommand.setCommandPacket(commandPacket);
avrCommands.push_back(avrCommand);
copiedPacketSize += commandPacketSize;
}
return avrCommands;
}
return avrCommands;
}
AvrCommandFrame::operator std::vector<unsigned char>() const {
auto data = this->getPayload();
auto dataSize = data.size();
AvrCommandFrame::operator std::vector<unsigned char> () const {
auto data = this->getPayload();
auto dataSize = data.size();
auto rawCommand = std::vector<unsigned char>(5);
auto rawCommand = std::vector<unsigned char>(5);
rawCommand[0] = this->SOF;
rawCommand[1] = this->getProtocolVersion();
rawCommand[0] = this->SOF;
rawCommand[1] = this->getProtocolVersion();
rawCommand[2] = static_cast<unsigned char>(this->getSequenceId());
rawCommand[3] = static_cast<unsigned char>(this->getSequenceId() >> 8);
rawCommand[2] = static_cast<unsigned char>(this->getSequenceId());
rawCommand[3] = static_cast<unsigned char>(this->getSequenceId() >> 8);
rawCommand[4] = static_cast<unsigned char>(this->getProtocolHandlerId());
rawCommand[4] = static_cast<unsigned char>(this->getProtocolHandlerId());
if (dataSize > 0) {
rawCommand.insert(
rawCommand.end(),
data.begin(),
data.end()
);
}
if (dataSize > 0) {
rawCommand.insert(
rawCommand.end(),
data.begin(),
data.end()
);
return rawCommand;
}
return rawCommand;
}

View File

@@ -2,28 +2,33 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Targets;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
using namespace Bloom::Exceptions;
void BreakEvent::init(const AvrEvent& event) {
AvrEvent::init(event);
auto& data = this->getEventData();
using Bloom::Targets::TargetBreakCause;
if (data.size() < 8) {
/*
* All BreakEvent packets must consist of at least 9 bytes:
* 1 byte for event ID
* 4 bytes for program counter
* 1 byte for break cause
* 2 bytes for extended info
*/
throw Exception("Failed to process BreakEvent from AvrEvent - unexpected packet size.");
void BreakEvent::init(const AvrEvent& event) {
AvrEvent::init(event);
const auto& data = this->getEventData();
if (data.size() < 8) {
/*
* All BreakEvent packets must consist of at least 9 bytes:
* 1 byte for event ID
* 4 bytes for program counter
* 1 byte for break cause
* 2 bytes for extended info
*/
throw Exception("Failed to process BreakEvent from AvrEvent - unexpected packet size.");
}
// Program counter consists of 4 bytes
this->programCounter = static_cast<std::uint32_t>(
(data[4] << 24) | (data[3] << 16) | (data[2] << 8) | data[1]
) * 2;
// Break cause is 1 byte, where 0x01 is 'program breakpoint' and 0x00 'unspecified'
this->breakCause = data[7] == 0x01 ? TargetBreakCause::BREAKPOINT : TargetBreakCause::UNKNOWN;
}
// Program counter consists of 4 bytes
this->programCounter = static_cast<std::uint32_t>((data[4] << 24) | (data[3] << 16) | (data[2] << 8) | data[1]) * 2;
// Break cause is 1 byte, where 0x01 is 'program breakpoint' and 0x00 'unspecified'
this->breakCause = data[7] == 0x01 ? TargetBreakCause::BREAKPOINT : TargetBreakCause::UNKNOWN;
}

View File

@@ -2,36 +2,38 @@
#include "src/Exceptions/Exception.hpp"
using namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr;
using namespace Bloom::Exceptions;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg::Avr
{
using namespace Bloom::Exceptions;
void AvrResponseFrame::initFromAvrResponses(const std::vector<AvrResponse>& avrResponses) {
// Build a raw frame buffer from the AVRResponse objects and just call initFromRawFrame()
std::vector<unsigned char> rawFrame;
void AvrResponseFrame::initFromAvrResponses(const std::vector<AvrResponse>& avrResponses) {
// Build a raw frame buffer from the AVRResponse objects and just call initFromRawFrame()
std::vector<unsigned char> rawFrame;
for (auto& avrResponse : avrResponses) {
auto responsePacket = avrResponse.getResponsePacket();
rawFrame.insert(rawFrame.end(), responsePacket.begin(), responsePacket.end());
for (const auto& avrResponse : avrResponses) {
auto responsePacket = avrResponse.getResponsePacket();
rawFrame.insert(rawFrame.end(), responsePacket.begin(), responsePacket.end());
}
return this->initFromRawFrame(rawFrame);
}
return this->initFromRawFrame(rawFrame);
}
void AvrResponseFrame::initFromRawFrame(const std::vector<unsigned char>& rawFrame) {
if (rawFrame.size() < 4) {
// All AVR response frames must consist of at least four bytes (SOF, sequence ID (two bytes) and
// a protocol handler ID)
throw Exception("Failed to construct AvrResponseFrame - unexpected end to raw frame");
}
if (rawFrame[0] != 0x0E) {
// The SOF field must always be 0x0E
throw Exception("Failed to construct AvrResponseFrame - unexpected SOF field value in raw frame");
}
this->setSequenceId(static_cast<std::uint16_t>((rawFrame[2] << 8) + rawFrame[1]));
this->setProtocolHandlerId(rawFrame[3]);
auto& payload = this->getPayload();
payload.insert(payload.begin(), rawFrame.begin() + 4, rawFrame.end());
void AvrResponseFrame::initFromRawFrame(const std::vector<unsigned char>& rawFrame) {
if (rawFrame.size() < 4) {
// All AVR response frames must consist of at least four bytes (SOF, sequence ID (two bytes) and
// a protocol handler ID)
throw Exception("Failed to construct AvrResponseFrame - unexpected end to raw frame");
}
if (rawFrame[0] != 0x0E) {
// The SOF field must always be 0x0E
throw Exception("Failed to construct AvrResponseFrame - unexpected SOF field value in raw frame");
}
this->setSequenceId(static_cast<std::uint16_t>((rawFrame[2] << 8) + rawFrame[1]));
this->setProtocolHandlerId(rawFrame[3]);
auto& payload = this->getPayload();
payload.insert(payload.begin(), rawFrame.begin() + 4, rawFrame.end());
}
}

View File

@@ -4,95 +4,99 @@
#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;
namespace Bloom::DebugToolDrivers::Protocols::CmsisDap::Edbg
{
using namespace Bloom::Exceptions;
Protocols::CmsisDap::Response EdbgInterface::sendAvrCommandFrameAndWaitForResponse(
const Protocols::CmsisDap::Edbg::Avr::AvrCommandFrame& avrCommandFrame
) {
// An AVR command frame can be split into multiple CMSIS-DAP commands. Each command
// containing a fragment of the AvrCommandFrame.
Protocols::CmsisDap::Response EdbgInterface::sendAvrCommandFrameAndWaitForResponse(
const Protocols::CmsisDap::Edbg::Avr::AvrCommandFrame& avrCommandFrame
) {
// An AVR command frame can be split into multiple CMSIS-DAP commands. Each command
// containing a fragment of the AvrCommandFrame.
// Minus 3 to accommodate AVR command meta data
std::size_t maximumCommandPacketSize = (this->getUsbHidInputReportSize() - 3);
// Minus 3 to accommodate AVR command meta data
std::size_t maximumCommandPacketSize = (this->getUsbHidInputReportSize() - 3);
auto avrCommands = avrCommandFrame.generateAvrCommands(maximumCommandPacketSize);
auto avrCommands = avrCommandFrame.generateAvrCommands(maximumCommandPacketSize);
for (auto& avrCommand : avrCommands) {
// Send command to device
auto response = this->sendCommandAndWaitForResponse(avrCommand);
for (auto& avrCommand : avrCommands) {
// Send command to device
auto response = this->sendCommandAndWaitForResponse(avrCommand);
if (&avrCommand ==& avrCommands.back()) {
return* response;
if (&avrCommand == &avrCommands.back()) {
return *response;
}
}
// This should never happen
throw DeviceCommunicationFailure(
"Cannot send AVR command frame - failed to generate CMSIS-DAP Vendor (AVR) commands"
);
}
// This should never happen
throw DeviceCommunicationFailure(
"Cannot send AVR command frame - failed to generate CMSIS-DAP Vendor (AVR) commands"
);
}
Protocols::CmsisDap::Edbg::Avr::AvrResponse EdbgInterface::getAvrResponse() {
auto cmsisResponse = this->getResponse();
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;
}
if (cmsisResponse->getResponseId() == 0x81) {
// This is an AVR_RSP response
auto avrResponse = Protocols::CmsisDap::Edbg::Avr::AvrResponse();
avrResponse.init(*cmsisResponse);
return avrResponse;
} else {
throw DeviceCommunicationFailure("Unexpected response to AvrResponseCommand from device");
}
}
std::optional<Protocols::CmsisDap::Edbg::Avr::AvrEvent> EdbgInterface::requestAvrEvent() {
this->sendCommand(AvrEventCommand());
auto cmsisResponse = this->getResponse();
std::optional<Protocols::CmsisDap::Edbg::Avr::AvrEvent> EdbgInterface::requestAvrEvent() {
this->sendCommand(AvrEventCommand());
auto cmsisResponse = this->getResponse();
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 (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;
} else {
throw DeviceCommunicationFailure("Unexpected response to AvrEventCommand from device");
}
}
std::vector<Protocols::CmsisDap::Edbg::Avr::AvrResponse> EdbgInterface::requestAvrResponses() {
std::vector<Protocols::CmsisDap::Edbg::Avr::AvrResponse> responses;
AvrResponseCommand responseCommand;
std::vector<Protocols::CmsisDap::Edbg::Avr::AvrResponse> EdbgInterface::requestAvrResponses() {
using Protocols::CmsisDap::Edbg::Avr::AvrResponseCommand;
this->sendCommand(responseCommand);
auto response = this->getAvrResponse();
responses.push_back(response);
int fragmentCount = response.getFragmentCount();
std::vector<Protocols::CmsisDap::Edbg::Avr::AvrResponse> responses;
AvrResponseCommand responseCommand;
while (responses.size() < fragmentCount) {
// There are more response packets
this->sendCommand(responseCommand);
response = this->getAvrResponse();
if (response.getFragmentCount() != fragmentCount) {
throw DeviceCommunicationFailure(
"Failed to fetch AVRResponse objects - invalid fragment count returned."
);
}
if (response.getFragmentCount() == 0 && response.getFragmentNumber() == 0) {
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;
}
auto response = this->getAvrResponse();
responses.push_back(response);
}
int fragmentCount = response.getFragmentCount();
return responses;
while (responses.size() < fragmentCount) {
// There are more response packets
this->sendCommand(responseCommand);
response = this->getAvrResponse();
if (response.getFragmentCount() != fragmentCount) {
throw DeviceCommunicationFailure(
"Failed to fetch AVRResponse objects - invalid fragment count returned."
);
}
if (response.getFragmentCount() == 0 && response.getFragmentNumber() == 0) {
throw DeviceCommunicationFailure(
"Failed to fetch AVRResponse objects - unexpected empty response"
);
}
if (response.getFragmentNumber() == 0) {
// End of response data ( &this packet can be ignored)
break;
}
responses.push_back(response);
}
return responses;
}
}