Newer
Older
#include "Services/MemoryManagementService.hpp"
// Define the constructors for the classes
MemoryManagementService::MemoryManagementService() : rawDataMemorySubservice(*this) {
serviceType = 6;
}
MemoryManagementService::RawDataMemoryManagement::RawDataMemoryManagement(
MemoryManagementService &parent) : mainService(parent) {}
// Function declarations for the raw data memory management subservice
Dimitrios Stoupis
committed
void MemoryManagementService::RawDataMemoryManagement::loadRawData(Message &request) {
/**
* Bare in mind that there is currently no error checking for invalid parameters.
* A future version will include error checking and the corresponding error report/notification,
* as the manual implies.
*
* @todo Add error checking and reporting for the parameters
* @todo Add failure reporting
*/
Dimitrios Stoupis
committed
// Check if we have the correct packet
assert(request.serviceType == 6);
assert(request.messageType == 2);
// Read the memory ID from the request
auto memoryID = MemoryManagementService::MemoryID(request.readEnum8());
// Check for a valid memory ID first
if (mainService.memoryIdValidator(MemoryManagementService::MemoryID(memoryID))) {
// Variable declaration
uint8_t readData[ECSS_MAX_STRING_SIZE]; // Preallocate the array
uint16_t iterationCount = request.readUint16(); // Get the iteration count
if (memoryID == MemoryManagementService::MemoryID::FLASH) {
// todo: Define FLASH specific access code when we transfer to embedded
} else {
for (std::size_t j = 0; j < iterationCount; j++) {
uint64_t startAddress = request.readUint64(); // Start address of the memory
uint16_t dataLength = request.readOctetString(readData); // Data length to load
uint16_t checksum = request.readBits(16); // Get the CRC checksum from the message
// Continue only if the checksum passes
if (checksum != CRCHelper::validateCRC(readData, dataLength)) {
// todo: Send a failed of execution report
// todo: Remove the print statements in the final version
// todo: The final implementation of exit on failure has to be well defined
std::cout << "We encountered a problem validating CRC!" << std::endl;
return; // Make sure we get out of the loop and no other command is executed
}
if (mainService.addressValidator(memoryID, startAddress) &&
mainService.addressValidator(memoryID, startAddress + dataLength)) {
for (std::size_t i = 0; i < dataLength; i++) {
*(reinterpret_cast<uint8_t *>(startAddress) + i) = readData[i];
}
} else {
// todo: Implement the fail report the correct way when we know all parameters
mainService.requestVerificationService.failExecutionVerification(
request.packetType, true, 1, 1, 10, 6);
// todo: Send a failed of execution report
Dimitrios Stoupis
committed
}
// todo: Send a failed start of execution
Dimitrios Stoupis
committed
}
void MemoryManagementService::RawDataMemoryManagement::dumpRawData(Message &request) {
Dimitrios Stoupis
committed
// Check if we have the correct packet
assert(request.serviceType == 6);
assert(request.messageType == 5);
// Create the report message object of telemetry message subtype 6
Message report = mainService.createTM(6);
uint8_t memoryID = request.readEnum8(); // Read the memory ID from the request
// Check for a valid memory ID first
if (mainService.memoryIdValidator(MemoryManagementService::MemoryID(memoryID))) {
// Variable declaration
uint8_t readData[ECSS_MAX_STRING_SIZE]; // Preallocate the array
uint16_t iterationCount = request.readUint16(); // Get the iteration count
// Append the data to report message
report.appendEnum8(memoryID); // Memory ID
report.appendUint16(iterationCount); // Iteration count
// Iterate N times, as specified in the command message
for (std::size_t j = 0; j < iterationCount; j++) {
uint64_t startAddress = request.readUint64(); // Data length to read
uint16_t readLength = request.readUint16(); // Start address for the memory read
// Read memory data, an octet at a time, checking for a valid address first
if (mainService.addressValidator(MemoryManagementService::MemoryID(memoryID),
startAddress) &&
mainService.addressValidator(MemoryManagementService::MemoryID(memoryID),
startAddress + readLength)) {
for (std::size_t i = 0; i < readLength; i++) {
readData[i] = *(reinterpret_cast<uint8_t *>(startAddress) + i);
}
// This part is repeated N-times (N = iteration count)
report.appendUint64(startAddress); // Start address
report.appendOctetString(readLength, readData); // Save the read data
report.appendBits(16, CRCHelper::calculateCRC(readData, readLength));
mainService.requestVerificationService.failExecutionVerification(request.packetType,
true, 1, 1, 10, 6);
// todo: Send a failed of execution report
mainService.storeMessage(report); // Save the report message
request.resetRead(); // Reset the reading count
} else {
// todo: Send a failed start of execution
void MemoryManagementService::RawDataMemoryManagement::checkRawData(Message &request) {
// Check if we have the correct packet
assert(request.serviceType == 6);
assert(request.messageType == 9);
// Create the report message object of telemetry message subtype 10
Message report = mainService.createTM(10);
uint8_t memoryID = request.readEnum8(); // Read the memory ID from the request
if (mainService.memoryIdValidator(MemoryManagementService::MemoryID(memoryID))) {
// Variable declaration
uint8_t readData[ECSS_MAX_STRING_SIZE]; // Preallocate the array
uint16_t iterationCount = request.readUint16(); // Get the iteration count
// Append the data to report message
report.appendEnum8(memoryID); // Memory ID
report.appendUint16(iterationCount); // Iteration count
// Iterate N times, as specified in the command message
for (std::size_t j = 0; j < iterationCount; j++) {
uint64_t startAddress = request.readUint64(); // Data length to read
uint16_t readLength = request.readUint16(); // Start address for the memory read
// Check whether the first and the last addresses are within the limits
if (mainService.addressValidator(MemoryManagementService::MemoryID(memoryID),
startAddress) &&
mainService.addressValidator(MemoryManagementService::MemoryID(memoryID),
startAddress + readLength)) {
// Read memory data and save them for checksum calculation
for (std::size_t i = 0; i < readLength; i++) {
readData[i] = *(reinterpret_cast<uint8_t *>(startAddress) + i);
}
// This part is repeated N-times (N = iteration count)
report.appendUint64(startAddress); // Start address
report.appendUint16(readLength); // Save the read data
report.appendBits(16, CRCHelper::calculateCRC(readData, readLength)); // Append CRC
mainService.requestVerificationService.failExecutionVerification(request.packetType,
true, 1, 1, 10, 6);
// todo: Send a failed of execution report
mainService.storeMessage(report); // Save the report message
request.resetRead(); // Reset the reading count
} else {
// todo: Send a failed start of execution report
// Private function declaration section
bool MemoryManagementService::addressValidator(
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
MemoryManagementService::MemoryID memId, uint64_t address) {
bool validIndicator = false;
switch (memId) {
case MemoryManagementService::MemoryID::DTCMRAM:
if (address >= DTCMRAM_LOWER_LIM && address <= DTCMRAM_UPPER_LIM) {
validIndicator = true;
}
break;
case MemoryManagementService::MemoryID::ITCMRAM:
if (address >= ITCMRAM_LOWER_LIM && address <= ITCMRAM_UPPER_LIM) {
validIndicator = true;
}
break;
case MemoryManagementService::MemoryID::RAM_D1:
if (address >= RAM_D1_LOWER_LIM && address <= RAM_D1_UPPER_LIM) {
validIndicator = true;
}
break;
case MemoryManagementService::MemoryID::RAM_D2:
if (address >= RAM_D2_LOWER_LIM && address <= RAM_D2_UPPER_LIM) {
validIndicator = true;
}
break;
case MemoryManagementService::MemoryID::RAM_D3:
if (address >= RAM_D3_LOWER_LIM && address <= RAM_D3_UPPER_LIM) {
validIndicator = true;
}
break;
case MemoryManagementService::MemoryID::FLASH:
if (address >= FLASH_LOWER_LIM && address <= FLASH_UPPER_LIM) {
validIndicator = true;
}
break;
default:
validIndicator = true; // todo: Implemented so addresses from PC can be read. Remove.
break;
}
return validIndicator;
}
inline bool MemoryManagementService::memoryIdValidator(
MemoryManagementService::MemoryID memId) {
return (memId == MemoryManagementService::MemoryID::RAM_D1) ||
(memId == MemoryManagementService::MemoryID::RAM_D2) ||
(memId == MemoryManagementService::MemoryID::RAM_D3) ||
(memId == MemoryManagementService::MemoryID::DTCMRAM) ||
(memId == MemoryManagementService::MemoryID::ITCMRAM) ||
(memId == MemoryManagementService::MemoryID::FLASH) ||
(memId == MemoryManagementService::MemoryID::EXTERNAL);