Removed using namespace directive for class member function definitions in source files
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user