v1.12.0 #269
@ -169,7 +169,7 @@ void initmission::initTasks() {
|
||||
|
||||
#if OBSW_ADD_PLOC_SUPERVISOR == 1
|
||||
PeriodicTaskIF* supvHelperTask = factory->createPeriodicTask(
|
||||
"PLOC_SUPV_HELPER", 10, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.3, missedDeadlineFunc);
|
||||
"PLOC_SUPV_HELPER", 10, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 1.0, missedDeadlineFunc);
|
||||
result = supvHelperTask->addComponent(objects::PLOC_SUPERVISOR_HELPER);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PLOC_SUPV_HELPER", objects::PLOC_SUPERVISOR_HELPER);
|
||||
|
@ -190,3 +190,5 @@
|
||||
13612;0x352c;SUPV_EXE_FAILURE_REPORT;LOW;Supervisor received execution failure report P1: Internal state of supervisor;linux\devices\ploc\PlocSupvHelper.h
|
||||
13613;0x352d;SUPV_ACK_INVALID_APID;LOW;Supervisor expected acknowledgment report but received space packet with other apid P1: Apid of received space packet P2: Internal state of supervisor helper;linux\devices\ploc\PlocSupvHelper.h
|
||||
13614;0x352e;SUPV_EXE_INVALID_APID;LOW;Supervisor helper expected execution report but received space packet with other apid P1: Apid of received space packet P2: Internal state of supervisor helper;linux\devices\ploc\PlocSupvHelper.h
|
||||
13615;0x352f;ACK_RECEPTION_FAILURE;LOW;Failed to receive acknowledgment report P1: Return value P2: Apid of command for which the reception of the acknowledgment report failed;linux\devices\ploc\PlocSupvHelper.h
|
||||
13616;0x3530;EXE_RECEPTION_FAILURE;LOW;Failed to receive execution report P1: Return value P2: Apid of command for which the reception of the execution report failed;linux\devices\ploc\PlocSupvHelper.h
|
||||
|
|
@ -72,7 +72,7 @@ def parse_events(
|
||||
LOGGER.info("EventParser: Parsing events: ")
|
||||
# Small delay for clean printout
|
||||
time.sleep(0.01)
|
||||
event_list = generate_event_list()eive
|
||||
event_list = generate_event_list()
|
||||
if print_events:
|
||||
PrettyPrinter.pprint(event_list)
|
||||
# Delay for clean printout
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 192 translations.
|
||||
* @brief Auto-generated event translation file. Contains 194 translations.
|
||||
* @details
|
||||
* Generated on: 2022-04-16 17:47:08
|
||||
* Generated on: 2022-04-18 16:58:03
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -193,6 +193,8 @@ const char *SUPV_ACK_FAILURE_REPORT_STRING = "SUPV_ACK_FAILURE_REPORT";
|
||||
const char *SUPV_EXE_FAILURE_REPORT_STRING = "SUPV_EXE_FAILURE_REPORT";
|
||||
const char *SUPV_ACK_INVALID_APID_STRING = "SUPV_ACK_INVALID_APID";
|
||||
const char *SUPV_EXE_INVALID_APID_STRING = "SUPV_EXE_INVALID_APID";
|
||||
const char *ACK_RECEPTION_FAILURE_STRING = "ACK_RECEPTION_FAILURE";
|
||||
const char *EXE_RECEPTION_FAILURE_STRING = "EXE_RECEPTION_FAILURE";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@ -572,6 +574,10 @@ const char *translateEvents(Event event) {
|
||||
return SUPV_ACK_INVALID_APID_STRING;
|
||||
case (13614):
|
||||
return SUPV_EXE_INVALID_APID_STRING;
|
||||
case (13615):
|
||||
return ACK_RECEPTION_FAILURE_STRING;
|
||||
case (13616):
|
||||
return EXE_RECEPTION_FAILURE_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 116 translations.
|
||||
* Generated on: 2022-04-16 17:47:17
|
||||
* Generated on: 2022-04-18 16:58:07
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
|
@ -222,6 +222,12 @@ static const uint32_t BOOT_REPORT_SET_ID = BOOT_STATUS_REPORT;
|
||||
static const uint32_t LATCHUP_RPT_ID = LATCHUP_REPORT;
|
||||
static const uint32_t LOGGING_RPT_ID = LOGGING_REQUEST_COUNTERS;
|
||||
|
||||
namespace recv_timeout {
|
||||
// Erase memory can require up to 60 seconds for execution
|
||||
static const uint32_t ERASE_MEMORY = 60000;
|
||||
static const uint32_t UPDATE_STATUS_REPORT = 60000;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This class creates a space packet containing only the header data and the CRC.
|
||||
*/
|
||||
|
@ -243,6 +243,80 @@ void PlocMPSoCHandler::fillCommandAndReplyMap() {
|
||||
this->insertInReplyMap(mpsoc::TM_MEMORY_READ_REPORT, 2, nullptr, mpsoc::SIZE_TM_MEM_READ_REPORT);
|
||||
}
|
||||
|
||||
ReturnValue_t PlocMPSoCHandler::enableReplyInReplyMap(DeviceCommandMap::iterator command,
|
||||
uint8_t expectedReplies, bool useAlternateId,
|
||||
DeviceCommandId_t alternateReplyID) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
uint8_t enabledReplies = 0;
|
||||
|
||||
switch (command->first) {
|
||||
case mpsoc::TC_MEM_WRITE:
|
||||
case mpsoc::TC_FLASHDELETE:
|
||||
case mpsoc::TC_REPLAY_START:
|
||||
case mpsoc::TC_REPLAY_STOP:
|
||||
case mpsoc::TC_DOWNLINK_PWR_ON:
|
||||
case mpsoc::TC_DOWNLINK_PWR_OFF:
|
||||
case mpsoc::TC_REPLAY_WRITE_SEQUENCE:
|
||||
case mpsoc::TC_MODE_REPLAY:
|
||||
enabledReplies = 2;
|
||||
break;
|
||||
case mpsoc::TC_MEM_READ: {
|
||||
enabledReplies = 3;
|
||||
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true,
|
||||
mpsoc::TM_MEMORY_READ_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id "
|
||||
<< mpsoc::TM_MEMORY_READ_REPORT << " not in replyMap" << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case mpsoc::OBSW_RESET_SEQ_COUNT:
|
||||
break;
|
||||
default:
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Unknown command id" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* Every command causes at least one acknowledgment and one execution report. Therefore both
|
||||
* replies will be enabled here.
|
||||
*/
|
||||
result =
|
||||
DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, mpsoc::ACK_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id " << mpsoc::ACK_REPORT
|
||||
<< " not in replyMap" << std::endl;
|
||||
}
|
||||
|
||||
result =
|
||||
DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, mpsoc::EXE_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id " << mpsoc::EXE_REPORT
|
||||
<< " not in replyMap" << std::endl;
|
||||
}
|
||||
|
||||
switch (command->first) {
|
||||
case mpsoc::TC_REPLAY_WRITE_SEQUENCE: {
|
||||
DeviceReplyIter iter = deviceReplyMap.find(mpsoc::EXE_REPORT);
|
||||
// Overwrite delay cycles because replay write sequence command can required up to
|
||||
// 30 seconds for execution
|
||||
iter->second.delayCycles = mpsoc::TC_WRITE_SEQ_EXECUTION_DELAY;
|
||||
break;
|
||||
}
|
||||
case mpsoc::TC_DOWNLINK_PWR_ON: {
|
||||
DeviceReplyIter iter = deviceReplyMap.find(mpsoc::EXE_REPORT);
|
||||
//
|
||||
iter->second.delayCycles = mpsoc::TC_DOWNLINK_PWR_ON;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocMPSoCHandler::scanForReply(const uint8_t* start, size_t remainingSize,
|
||||
DeviceCommandId_t* foundId, size_t* foundLen) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
@ -586,79 +660,7 @@ ReturnValue_t PlocMPSoCHandler::handleMemoryReadReport(const uint8_t* data) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocMPSoCHandler::enableReplyInReplyMap(DeviceCommandMap::iterator command,
|
||||
uint8_t expectedReplies, bool useAlternateId,
|
||||
DeviceCommandId_t alternateReplyID) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
uint8_t enabledReplies = 0;
|
||||
|
||||
switch (command->first) {
|
||||
case mpsoc::TC_MEM_WRITE:
|
||||
case mpsoc::TC_FLASHDELETE:
|
||||
case mpsoc::TC_REPLAY_START:
|
||||
case mpsoc::TC_REPLAY_STOP:
|
||||
case mpsoc::TC_DOWNLINK_PWR_ON:
|
||||
case mpsoc::TC_DOWNLINK_PWR_OFF:
|
||||
case mpsoc::TC_REPLAY_WRITE_SEQUENCE:
|
||||
case mpsoc::TC_MODE_REPLAY:
|
||||
enabledReplies = 2;
|
||||
break;
|
||||
case mpsoc::TC_MEM_READ: {
|
||||
enabledReplies = 3;
|
||||
result = DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true,
|
||||
mpsoc::TM_MEMORY_READ_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id "
|
||||
<< mpsoc::TM_MEMORY_READ_REPORT << " not in replyMap" << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case mpsoc::OBSW_RESET_SEQ_COUNT:
|
||||
break;
|
||||
default:
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Unknown command id" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
/**
|
||||
* Every command causes at least one acknowledgment and one execution report. Therefore both
|
||||
* replies will be enabled here.
|
||||
*/
|
||||
result =
|
||||
DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, mpsoc::ACK_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id " << mpsoc::ACK_REPORT
|
||||
<< " not in replyMap" << std::endl;
|
||||
}
|
||||
|
||||
result =
|
||||
DeviceHandlerBase::enableReplyInReplyMap(command, enabledReplies, true, mpsoc::EXE_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "PlocMPSoCHandler::enableReplyInReplyMap: Reply with id " << mpsoc::EXE_REPORT
|
||||
<< " not in replyMap" << std::endl;
|
||||
}
|
||||
|
||||
switch (command->first) {
|
||||
case mpsoc::TC_REPLAY_WRITE_SEQUENCE: {
|
||||
DeviceReplyIter iter = deviceReplyMap.find(mpsoc::EXE_REPORT);
|
||||
// Overwrite delay cycles because replay write sequence command can required up to
|
||||
// 30 seconds for execution
|
||||
iter->second.delayCycles = mpsoc::TC_WRITE_SEQ_EXECUTION_DELAY;
|
||||
break;
|
||||
}
|
||||
case mpsoc::TC_DOWNLINK_PWR_ON: {
|
||||
DeviceReplyIter iter = deviceReplyMap.find(mpsoc::EXE_REPORT);
|
||||
//
|
||||
iter->second.delayCycles = mpsoc::TC_DOWNLINK_PWR_ON;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void PlocMPSoCHandler::setNextReplyId() {
|
||||
switch (getPendingCommand()) {
|
||||
|
@ -88,7 +88,7 @@ ReturnValue_t PlocSupervisorHandler::executeAction(ActionId_t actionId,
|
||||
switch (actionId) {
|
||||
case TERMINATE_SUPV_HELPER: {
|
||||
supvHelper->stopProcess();
|
||||
break;
|
||||
return EXECUTION_FINISHED;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@ -1145,6 +1145,14 @@ size_t PlocSupervisorHandler::getNextReplyLength(DeviceCommandId_t commandId) {
|
||||
return replyLen;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupervisorHandler::doSendReadHook() {
|
||||
// Prevent DHB from polling UART during commands executed by the supervisor helper task
|
||||
if (plocSupvHelperExecuting) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void PlocSupervisorHandler::handleDeviceTM(const uint8_t* data, size_t dataSize,
|
||||
DeviceCommandId_t replyId) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
@ -55,6 +55,7 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
||||
uint8_t expectedReplies = 1, bool useAlternateId = false,
|
||||
DeviceCommandId_t alternateReplyID = 0) override;
|
||||
size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
|
||||
virtual ReturnValue_t doSendReadHook() override;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#endif
|
||||
|
||||
#include "fsfw/globalfunctions/CRC.h"
|
||||
#include "fsfw/timemanager/Countdown.h"
|
||||
#include "mission/utility/Filenaming.h"
|
||||
#include "mission/utility/ProgressPrinter.h"
|
||||
#include "mission/utility/Timestamp.h"
|
||||
@ -44,7 +45,6 @@ ReturnValue_t PlocSupvHelper::performOperation(uint8_t operationCode) {
|
||||
triggerEvent(SUPV_UPDATE_SUCCESSFUL, result);
|
||||
} else if (result == PROCESS_TERMINATED) {
|
||||
// Event already triggered
|
||||
break;
|
||||
} else {
|
||||
triggerEvent(SUPV_UPDATE_FAILED, result);
|
||||
}
|
||||
@ -109,10 +109,6 @@ ReturnValue_t PlocSupvHelper::startUpdate(std::string file, uint8_t memoryId,
|
||||
update.length = getFileSize(update.file);
|
||||
update.memoryId = memoryId;
|
||||
update.startAddress = startAddress;
|
||||
result = calcImageCrc();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
internalState = InternalState::UPDATE;
|
||||
uartComIF->flushUartTxAndRxBuf(comCookie);
|
||||
semaphore.release();
|
||||
@ -140,6 +136,10 @@ void PlocSupvHelper::stopProcess() { terminate = true; }
|
||||
|
||||
ReturnValue_t PlocSupvHelper::performUpdate() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
result = calcImageCrc();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = prepareUpdate();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
@ -149,8 +149,7 @@ ReturnValue_t PlocSupvHelper::performUpdate() {
|
||||
return result;
|
||||
}
|
||||
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
ProgressPrinter progressPrinter("Supervisor update: ", update.length,
|
||||
ProgressPrinter::ONE_PERCENT);
|
||||
ProgressPrinter progressPrinter("Supervisor update", update.length, ProgressPrinter::ONE_PERCENT);
|
||||
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
||||
uint8_t tempData[supv::WriteMemory::CHUNK_MAX];
|
||||
std::ifstream file(update.file, std::ifstream::binary);
|
||||
@ -166,11 +165,17 @@ ReturnValue_t PlocSupvHelper::performUpdate() {
|
||||
if (remainingSize > supv::WriteMemory::CHUNK_MAX) {
|
||||
dataLength = supv::WriteMemory::CHUNK_MAX;
|
||||
} else {
|
||||
dataLength = remainingSize;
|
||||
dataLength = static_cast<uint16_t>(remainingSize);
|
||||
}
|
||||
if (file.is_open()) {
|
||||
file.seekg(bytesWritten, file.beg);
|
||||
file.read(reinterpret_cast<char*>(tempData), dataLength);
|
||||
if (!file) {
|
||||
sif::warning << "PlocSupvHelper::performUpdate: Read only " << file.gcount() << " of "
|
||||
<< dataLength << " bytes" << std::endl;
|
||||
sif::info << "PlocSupvHelper::performUpdate: Failed when trying to read byte "
|
||||
<< bytesWritten << std::endl;
|
||||
}
|
||||
remainingSize -= dataLength;
|
||||
} else {
|
||||
return FILE_CLOSED_ACCIDENTALLY;
|
||||
@ -236,14 +241,15 @@ ReturnValue_t PlocSupvHelper::prepareUpdate() {
|
||||
ReturnValue_t PlocSupvHelper::eraseMemory() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
supv::EraseMemory eraseMemory(update.memoryId, update.startAddress, update.length);
|
||||
result = handlePacketTransmission(eraseMemory);
|
||||
result = handlePacketTransmission(eraseMemory, supv::recv_timeout::ERASE_MEMORY);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupvHelper::handlePacketTransmission(SpacePacket& packet) {
|
||||
ReturnValue_t PlocSupvHelper::handlePacketTransmission(SpacePacket& packet,
|
||||
uint32_t timeoutExecutionReport) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
result = sendCommand(packet);
|
||||
if (result != RETURN_OK) {
|
||||
@ -253,7 +259,7 @@ ReturnValue_t PlocSupvHelper::handlePacketTransmission(SpacePacket& packet) {
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
result = handleExe();
|
||||
result = handleExe(timeoutExecutionReport);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
@ -302,10 +308,10 @@ void PlocSupvHelper::handleAckApidFailure(uint16_t apid) {
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupvHelper::handleExe() {
|
||||
ReturnValue_t PlocSupvHelper::handleExe(uint32_t timeout) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
supv::TmPacket tmPacket;
|
||||
result = handleTmReception(&tmPacket, supv::SIZE_EXE_REPORT);
|
||||
result = handleTmReception(&tmPacket, supv::SIZE_EXE_REPORT, timeout);
|
||||
if (result != RETURN_OK) {
|
||||
triggerEvent(EXE_RECEPTION_FAILURE, result, static_cast<uint32_t>(rememberApid));
|
||||
sif::warning << "PlocSupvHelper::handleExe: Error in reception of execution report"
|
||||
@ -332,11 +338,13 @@ void PlocSupvHelper::handleExeApidFailure(uint16_t apid) {
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t PlocSupvHelper::handleTmReception(supv::TmPacket* tmPacket, size_t remainingBytes) {
|
||||
ReturnValue_t PlocSupvHelper::handleTmReception(supv::TmPacket* tmPacket, size_t remainingBytes,
|
||||
uint32_t timeout) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
size_t readBytes = 0;
|
||||
size_t currentBytes = 0;
|
||||
for (int retries = 0; retries < RETRIES; retries++) {
|
||||
Countdown countdown(timeout);
|
||||
while (!countdown.hasTimedOut()) {
|
||||
result = receive(tmPacket->getWholeData() + readBytes, ¤tBytes, remainingBytes);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
@ -395,11 +403,21 @@ ReturnValue_t PlocSupvHelper::calcImageCrc() {
|
||||
std::ifstream file(update.file, std::ifstream::binary);
|
||||
uint16_t remainder = CRC16_INIT;
|
||||
uint8_t input;
|
||||
for (uint32_t byteCount = 0; byteCount < update.length; byteCount++) {
|
||||
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
ProgressPrinter progress("Supervisor update crc calculation", update.length);
|
||||
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
||||
uint32_t byteCount = 0;
|
||||
for (byteCount = 0; byteCount < update.length; byteCount++) {
|
||||
file.seekg(byteCount, file.beg);
|
||||
file.read(reinterpret_cast<char*>(&input), 1);
|
||||
remainder = CRC::crc16ccitt(&input, sizeof(input), remainder);
|
||||
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
progress.print(byteCount);
|
||||
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
||||
}
|
||||
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||
progress.print(byteCount);
|
||||
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
||||
file.close();
|
||||
update.crc = remainder;
|
||||
return result;
|
||||
@ -419,7 +437,8 @@ ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() {
|
||||
}
|
||||
supv::UpdateStatusReport updateStatusReport;
|
||||
result = handleTmReception(&updateStatusReport,
|
||||
static_cast<size_t>(updateStatusReport.getNominalSize()));
|
||||
static_cast<size_t>(updateStatusReport.getNominalSize()),
|
||||
supv::recv_timeout::UPDATE_STATUS_REPORT);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
@ -487,7 +506,3 @@ ReturnValue_t PlocSupvHelper::handleEventBufferReception() {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//ReturnValue_t PlocSupervisorHandler::parseStatusCode(std::string* meaning) {
|
||||
//
|
||||
//}
|
||||
|
@ -123,9 +123,6 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
||||
//! [EXPORT] : [COMMENT] Expected event buffer TM but received space packet with other APID
|
||||
static const ReturnValue_t EVENT_BUFFER_REPLY_INVALID_APID = MAKE_RETURN_CODE(0xA3);
|
||||
|
||||
// Maximum number of times the communication interface retries polling data from the reply
|
||||
// buffer
|
||||
static const int RETRIES = 20000;
|
||||
static const uint16_t CRC16_INIT = 0xFFFF;
|
||||
// Event buffer reply will carry 24 space packets with 1016 bytes and one space packet with
|
||||
// 192 bytes
|
||||
@ -180,7 +177,8 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
||||
|
||||
ReturnValue_t performUpdate();
|
||||
ReturnValue_t performEventBufferRequest();
|
||||
ReturnValue_t handlePacketTransmission(SpacePacket& packet);
|
||||
ReturnValue_t handlePacketTransmission(SpacePacket& packet,
|
||||
uint32_t timeoutExecutionReport = 1000);
|
||||
ReturnValue_t sendCommand(SpacePacket& packet);
|
||||
/**
|
||||
* @brief Function which reads form the communication interface
|
||||
@ -191,7 +189,7 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
||||
*/
|
||||
ReturnValue_t receive(uint8_t* data, size_t* readBytes, size_t requestBytes);
|
||||
ReturnValue_t handleAck();
|
||||
ReturnValue_t handleExe();
|
||||
ReturnValue_t handleExe(uint32_t timeout = 1000);
|
||||
void handleAckApidFailure(uint16_t apid);
|
||||
void handleExeApidFailure(uint16_t apid);
|
||||
/**
|
||||
@ -199,8 +197,10 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
||||
*
|
||||
* @param tmPacket Pointer to space packet where received data will be written to
|
||||
* @param reaminingBytes Number of bytes to read in the space packet
|
||||
* @param timeout Receive timeout in milliseconds
|
||||
*/
|
||||
ReturnValue_t handleTmReception(supv::TmPacket* tmPacket, size_t remainingBytes);
|
||||
ReturnValue_t handleTmReception(supv::TmPacket* tmPacket, size_t remainingBytes,
|
||||
uint32_t timeout = 1000);
|
||||
ReturnValue_t prepareUpdate();
|
||||
ReturnValue_t eraseMemory();
|
||||
// Calculates CRC over image. Will be used for verification after update writing has
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 192 translations.
|
||||
* @brief Auto-generated event translation file. Contains 194 translations.
|
||||
* @details
|
||||
* Generated on: 2022-04-16 17:47:08
|
||||
* Generated on: 2022-04-18 16:58:03
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -193,6 +193,8 @@ const char *SUPV_ACK_FAILURE_REPORT_STRING = "SUPV_ACK_FAILURE_REPORT";
|
||||
const char *SUPV_EXE_FAILURE_REPORT_STRING = "SUPV_EXE_FAILURE_REPORT";
|
||||
const char *SUPV_ACK_INVALID_APID_STRING = "SUPV_ACK_INVALID_APID";
|
||||
const char *SUPV_EXE_INVALID_APID_STRING = "SUPV_EXE_INVALID_APID";
|
||||
const char *ACK_RECEPTION_FAILURE_STRING = "ACK_RECEPTION_FAILURE";
|
||||
const char *EXE_RECEPTION_FAILURE_STRING = "EXE_RECEPTION_FAILURE";
|
||||
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xFFFF)) {
|
||||
@ -572,6 +574,10 @@ const char *translateEvents(Event event) {
|
||||
return SUPV_ACK_INVALID_APID_STRING;
|
||||
case (13614):
|
||||
return SUPV_EXE_INVALID_APID_STRING;
|
||||
case (13615):
|
||||
return ACK_RECEPTION_FAILURE_STRING;
|
||||
case (13616):
|
||||
return EXE_RECEPTION_FAILURE_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 116 translations.
|
||||
* Generated on: 2022-04-16 17:47:17
|
||||
* Generated on: 2022-04-18 16:58:07
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
||||
|
||||
ProgressPrinter::ProgressPrinter(std::string name, uint32_t numSteps, uint32_t percentageResolution)
|
||||
: name(name), numSteps(numSteps) {}
|
||||
: name(name), numSteps(numSteps), percentageResolution(percentageResolution) {}
|
||||
|
||||
ProgressPrinter::~ProgressPrinter() {}
|
||||
|
||||
@ -11,6 +11,6 @@ void ProgressPrinter::print(uint32_t currentStep) {
|
||||
float progressInPercent = static_cast<float>(currentStep) / static_cast<float>(numSteps) * 100;
|
||||
if (static_cast<uint32_t>(progressInPercent) >= nextProgressPrint) {
|
||||
sif::info << name << " progress: " << progressInPercent << " %" << std::endl;
|
||||
nextProgressPrint += FIVE_PERCENT;
|
||||
nextProgressPrint += percentageResolution;
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ class ProgressPrinter {
|
||||
std::string name = "";
|
||||
uint32_t numSteps = 0;
|
||||
uint32_t nextProgressPrint = 0;
|
||||
uint32_t percentageResolution = 0;
|
||||
};
|
||||
|
||||
#endif /* MISSION_UTILITY_PROGRESSPRINTER_H_ */
|
||||
|
297
thirdparty/libcsp/src/drivers/can/can_socketcan.c
vendored
297
thirdparty/libcsp/src/drivers/can/can_socketcan.c
vendored
@ -19,183 +19,192 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* SocketCAN driver */
|
||||
#include <csp/csp.h>
|
||||
#include <csp/drivers/can_socketcan.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <csp/interfaces/csp_if_can.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/time.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include <linux/can.h>
|
||||
#include <linux/can/raw.h>
|
||||
#include <linux/socket.h>
|
||||
|
||||
#include <csp/csp.h>
|
||||
#include <csp/interfaces/csp_if_can.h>
|
||||
#include <net/if.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef CSP_HAVE_LIBSOCKETCAN
|
||||
#include <libsocketcan.h>
|
||||
#endif
|
||||
|
||||
#define CAN_RX_TASK_PRIO 80
|
||||
|
||||
static struct can_socketcan_s {
|
||||
int socket;
|
||||
csp_iface_t interface;
|
||||
int socket;
|
||||
csp_iface_t interface;
|
||||
} socketcan[1] = {
|
||||
{
|
||||
.interface = {
|
||||
.name = "CAN",
|
||||
.nexthop = csp_can_tx,
|
||||
.mtu = CSP_CAN_MTU,
|
||||
.driver = &socketcan[0],
|
||||
},
|
||||
},
|
||||
{
|
||||
.interface =
|
||||
{
|
||||
.name = "CAN",
|
||||
.nexthop = csp_can_tx,
|
||||
.mtu = CSP_CAN_MTU,
|
||||
.driver = &socketcan[0],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static void * socketcan_rx_thread(void * parameters)
|
||||
{
|
||||
struct can_frame frame;
|
||||
int nbytes;
|
||||
static void *socketcan_rx_thread(void *parameters) {
|
||||
struct can_frame frame;
|
||||
int nbytes;
|
||||
|
||||
while (1) {
|
||||
/* Read CAN frame */
|
||||
nbytes = read(socketcan[0].socket, &frame, sizeof(frame));
|
||||
if (nbytes < 0) {
|
||||
csp_log_error("read: %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
while (1) {
|
||||
/* Read CAN frame */
|
||||
nbytes = read(socketcan[0].socket, &frame, sizeof(frame));
|
||||
if (nbytes < 0) {
|
||||
csp_log_error("read: %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nbytes != sizeof(frame)) {
|
||||
csp_log_warn("Read incomplete CAN frame");
|
||||
continue;
|
||||
}
|
||||
if (nbytes != sizeof(frame)) {
|
||||
csp_log_warn("Read incomplete CAN frame");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Frame type */
|
||||
if (frame.can_id & (CAN_ERR_FLAG | CAN_RTR_FLAG) || !(frame.can_id & CAN_EFF_FLAG)) {
|
||||
/* Drop error and remote frames */
|
||||
csp_log_warn("Discarding ERR/RTR/SFF frame");
|
||||
continue;
|
||||
}
|
||||
/* Frame type */
|
||||
if (frame.can_id & (CAN_ERR_FLAG | CAN_RTR_FLAG) || !(frame.can_id & CAN_EFF_FLAG)) {
|
||||
/* Drop error and remote frames */
|
||||
csp_log_warn("Discarding ERR/RTR/SFF frame");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Strip flags */
|
||||
frame.can_id &= CAN_EFF_MASK;
|
||||
/* Strip flags */
|
||||
frame.can_id &= CAN_EFF_MASK;
|
||||
|
||||
/* Call RX callbacsp_can_rx_frameck */
|
||||
csp_can_rx(&socketcan[0].interface, frame.can_id, frame.data, frame.can_dlc, NULL);
|
||||
}
|
||||
/* Call RX callbacsp_can_rx_frameck */
|
||||
csp_can_rx(&socketcan[0].interface, frame.can_id, frame.data, frame.can_dlc, NULL);
|
||||
}
|
||||
|
||||
/* We should never reach this point */
|
||||
pthread_exit(NULL);
|
||||
/* We should never reach this point */
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
||||
int csp_can_tx_frame(csp_iface_t *interface, uint32_t id, const uint8_t * data, uint8_t dlc)
|
||||
{
|
||||
struct can_frame frame;
|
||||
int i, tries = 0;
|
||||
memset(&frame, 0, sizeof(frame));
|
||||
if (dlc > 8)
|
||||
return -1;
|
||||
|
||||
/* Copy identifier */
|
||||
frame.can_id = id | CAN_EFF_FLAG;
|
||||
|
||||
/* Copy data to frame */
|
||||
for (i = 0; i < dlc; i++)
|
||||
frame.data[i] = data[i];
|
||||
|
||||
/* Set DLC */
|
||||
frame.can_dlc = dlc;
|
||||
|
||||
/* Send frame */
|
||||
while (write(socketcan[0].socket, &frame, sizeof(frame)) != sizeof(frame)) {
|
||||
if (++tries < 1000 && errno == ENOBUFS) {
|
||||
/* Wait 10 ms and try again */
|
||||
usleep(10000);
|
||||
} else {
|
||||
csp_log_error("write: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
static int create_receive_thread() {
|
||||
pthread_t rx_thread;
|
||||
pthread_attr_t attributes;
|
||||
if (pthread_attr_init(&attributes) != 0) {
|
||||
return 1;
|
||||
}
|
||||
if (pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED) != 0) {
|
||||
return 1;
|
||||
}
|
||||
if (pthread_attr_setschedpolicy(&attributes, SCHED_FIFO) != 0) {
|
||||
return 1;
|
||||
}
|
||||
struct sched_param schedule_params;
|
||||
schedule_params.__sched_priority = CAN_RX_TASK_PRIO;
|
||||
if (pthread_attr_setschedparam(&attributes, &schedule_params) != 0) {
|
||||
return 1;
|
||||
}
|
||||
if (pthread_create(&rx_thread, NULL, socketcan_rx_thread, NULL) != 0) {
|
||||
csp_log_error("pthread_create: %s", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
csp_iface_t * csp_can_socketcan_init(const char * ifc, int bitrate, int promisc)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_can addr;
|
||||
pthread_t rx_thread;
|
||||
int csp_can_tx_frame(csp_iface_t *interface, uint32_t id, const uint8_t *data, uint8_t dlc) {
|
||||
struct can_frame frame;
|
||||
int i, tries = 0;
|
||||
memset(&frame, 0, sizeof(frame));
|
||||
if (dlc > 8) return -1;
|
||||
|
||||
//printf("-I-: Initiating CAN interface %s\n", ifc);
|
||||
/* Copy identifier */
|
||||
frame.can_id = id | CAN_EFF_FLAG;
|
||||
|
||||
/* Copy data to frame */
|
||||
for (i = 0; i < dlc; i++) frame.data[i] = data[i];
|
||||
|
||||
/* Set DLC */
|
||||
frame.can_dlc = dlc;
|
||||
|
||||
/* Send frame */
|
||||
while (write(socketcan[0].socket, &frame, sizeof(frame)) != sizeof(frame)) {
|
||||
if (++tries < 1000 && errno == ENOBUFS) {
|
||||
/* Wait 10 ms and try again */
|
||||
usleep(10000);
|
||||
} else {
|
||||
csp_log_error("write: %s", strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
csp_iface_t *csp_can_socketcan_init(const char *ifc, int bitrate, int promisc) {
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_can addr;
|
||||
|
||||
// printf("-I-: Initiating CAN interface %s\n", ifc);
|
||||
|
||||
#ifdef CSP_HAVE_LIBSOCKETCAN
|
||||
/* Set interface up */
|
||||
if (bitrate > 0) {
|
||||
can_do_stop(ifc);
|
||||
can_set_bitrate(ifc, bitrate);
|
||||
can_set_restart_ms(ifc, 100);
|
||||
can_do_start(ifc);
|
||||
}
|
||||
/* Set interface up */
|
||||
if (bitrate > 0) {
|
||||
can_do_stop(ifc);
|
||||
can_set_bitrate(ifc, bitrate);
|
||||
can_set_restart_ms(ifc, 100);
|
||||
can_do_start(ifc);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create socket */
|
||||
if ((socketcan[0].socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
|
||||
csp_log_error("socket: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
/* Create socket */
|
||||
if ((socketcan[0].socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
|
||||
csp_log_error("socket: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Locate interface */
|
||||
strncpy(ifr.ifr_name, ifc, IFNAMSIZ - 1);
|
||||
if (ioctl(socketcan[0].socket, SIOCGIFINDEX, &ifr) < 0) {
|
||||
csp_log_error("ioctl: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
/* Bind the socket to CAN interface */
|
||||
addr.can_family = AF_CAN;
|
||||
addr.can_ifindex = ifr.ifr_ifindex;
|
||||
if (bind(socketcan[0].socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
csp_log_error("bind: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
/* Locate interface */
|
||||
strncpy(ifr.ifr_name, ifc, IFNAMSIZ - 1);
|
||||
if (ioctl(socketcan[0].socket, SIOCGIFINDEX, &ifr) < 0) {
|
||||
csp_log_error("ioctl: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
/* Bind the socket to CAN interface */
|
||||
addr.can_family = AF_CAN;
|
||||
addr.can_ifindex = ifr.ifr_ifindex;
|
||||
if (bind(socketcan[0].socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
csp_log_error("bind: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set filter mode */
|
||||
if (promisc == 0) {
|
||||
/* Set filter mode */
|
||||
if (promisc == 0) {
|
||||
struct can_filter filter;
|
||||
filter.can_id = CFP_MAKE_DST(csp_get_address());
|
||||
filter.can_mask = CFP_MAKE_DST((1 << CFP_HOST_SIZE) - 1);
|
||||
|
||||
struct can_filter filter;
|
||||
filter.can_id = CFP_MAKE_DST(csp_get_address());
|
||||
filter.can_mask = CFP_MAKE_DST((1 << CFP_HOST_SIZE) - 1);
|
||||
if (setsockopt(socketcan[0].socket, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)) < 0) {
|
||||
csp_log_error("setsockopt: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (setsockopt(socketcan[0].socket, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)) < 0) {
|
||||
csp_log_error("setsockopt: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
if (create_receive_thread() != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
csp_iflist_add(&socketcan[0].interface);
|
||||
|
||||
/* Create receive thread */
|
||||
if (pthread_create(&rx_thread, NULL, socketcan_rx_thread, NULL) != 0) {
|
||||
csp_log_error("pthread_create: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
csp_iflist_add(&socketcan[0].interface);
|
||||
|
||||
return &socketcan[0].interface;
|
||||
return &socketcan[0].interface;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user