improvements in supervisor helper
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
Some checks failed
EIVE/eive-obsw/pipeline/head There was a failure building this commit
This commit is contained in:
parent
1ce45acba3
commit
ffd64d0463
@ -169,7 +169,7 @@ void initmission::initTasks() {
|
|||||||
|
|
||||||
#if OBSW_ADD_PLOC_SUPERVISOR == 1
|
#if OBSW_ADD_PLOC_SUPERVISOR == 1
|
||||||
PeriodicTaskIF* supvHelperTask = factory->createPeriodicTask(
|
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);
|
result = supvHelperTask->addComponent(objects::PLOC_SUPERVISOR_HELPER);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("PLOC_SUPV_HELPER", objects::PLOC_SUPERVISOR_HELPER);
|
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
|
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
|
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
|
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: ")
|
LOGGER.info("EventParser: Parsing events: ")
|
||||||
# Small delay for clean printout
|
# Small delay for clean printout
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
event_list = generate_event_list()eive
|
event_list = generate_event_list()
|
||||||
if print_events:
|
if print_events:
|
||||||
PrettyPrinter.pprint(event_list)
|
PrettyPrinter.pprint(event_list)
|
||||||
# Delay for clean printout
|
# 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
|
* @details
|
||||||
* Generated on: 2022-04-16 17:47:08
|
* Generated on: 2022-04-18 16:58:03
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#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_EXE_FAILURE_REPORT_STRING = "SUPV_EXE_FAILURE_REPORT";
|
||||||
const char *SUPV_ACK_INVALID_APID_STRING = "SUPV_ACK_INVALID_APID";
|
const char *SUPV_ACK_INVALID_APID_STRING = "SUPV_ACK_INVALID_APID";
|
||||||
const char *SUPV_EXE_INVALID_APID_STRING = "SUPV_EXE_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) {
|
const char *translateEvents(Event event) {
|
||||||
switch ((event & 0xFFFF)) {
|
switch ((event & 0xFFFF)) {
|
||||||
@ -572,6 +574,10 @@ const char *translateEvents(Event event) {
|
|||||||
return SUPV_ACK_INVALID_APID_STRING;
|
return SUPV_ACK_INVALID_APID_STRING;
|
||||||
case (13614):
|
case (13614):
|
||||||
return SUPV_EXE_INVALID_APID_STRING;
|
return SUPV_EXE_INVALID_APID_STRING;
|
||||||
|
case (13615):
|
||||||
|
return ACK_RECEPTION_FAILURE_STRING;
|
||||||
|
case (13616):
|
||||||
|
return EXE_RECEPTION_FAILURE_STRING;
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN_EVENT";
|
return "UNKNOWN_EVENT";
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 116 translations.
|
* Contains 116 translations.
|
||||||
* Generated on: 2022-04-16 17:47:17
|
* Generated on: 2022-04-18 16:58:07
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#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 LATCHUP_RPT_ID = LATCHUP_REPORT;
|
||||||
static const uint32_t LOGGING_RPT_ID = LOGGING_REQUEST_COUNTERS;
|
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.
|
* @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);
|
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,
|
ReturnValue_t PlocMPSoCHandler::scanForReply(const uint8_t* start, size_t remainingSize,
|
||||||
DeviceCommandId_t* foundId, size_t* foundLen) {
|
DeviceCommandId_t* foundId, size_t* foundLen) {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
@ -586,79 +660,7 @@ ReturnValue_t PlocMPSoCHandler::handleMemoryReadReport(const uint8_t* data) {
|
|||||||
return result;
|
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() {
|
void PlocMPSoCHandler::setNextReplyId() {
|
||||||
switch (getPendingCommand()) {
|
switch (getPendingCommand()) {
|
||||||
|
@ -88,7 +88,7 @@ ReturnValue_t PlocSupervisorHandler::executeAction(ActionId_t actionId,
|
|||||||
switch (actionId) {
|
switch (actionId) {
|
||||||
case TERMINATE_SUPV_HELPER: {
|
case TERMINATE_SUPV_HELPER: {
|
||||||
supvHelper->stopProcess();
|
supvHelper->stopProcess();
|
||||||
break;
|
return EXECUTION_FINISHED;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -1145,6 +1145,14 @@ size_t PlocSupervisorHandler::getNextReplyLength(DeviceCommandId_t commandId) {
|
|||||||
return replyLen;
|
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,
|
void PlocSupervisorHandler::handleDeviceTM(const uint8_t* data, size_t dataSize,
|
||||||
DeviceCommandId_t replyId) {
|
DeviceCommandId_t replyId) {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
@ -55,6 +55,7 @@ class PlocSupervisorHandler : public DeviceHandlerBase {
|
|||||||
uint8_t expectedReplies = 1, bool useAlternateId = false,
|
uint8_t expectedReplies = 1, bool useAlternateId = false,
|
||||||
DeviceCommandId_t alternateReplyID = 0) override;
|
DeviceCommandId_t alternateReplyID = 0) override;
|
||||||
size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
|
size_t getNextReplyLength(DeviceCommandId_t deviceCommand) override;
|
||||||
|
virtual ReturnValue_t doSendReadHook() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "fsfw/globalfunctions/CRC.h"
|
#include "fsfw/globalfunctions/CRC.h"
|
||||||
|
#include "fsfw/timemanager/Countdown.h"
|
||||||
#include "mission/utility/Filenaming.h"
|
#include "mission/utility/Filenaming.h"
|
||||||
#include "mission/utility/ProgressPrinter.h"
|
#include "mission/utility/ProgressPrinter.h"
|
||||||
#include "mission/utility/Timestamp.h"
|
#include "mission/utility/Timestamp.h"
|
||||||
@ -44,7 +45,6 @@ ReturnValue_t PlocSupvHelper::performOperation(uint8_t operationCode) {
|
|||||||
triggerEvent(SUPV_UPDATE_SUCCESSFUL, result);
|
triggerEvent(SUPV_UPDATE_SUCCESSFUL, result);
|
||||||
} else if (result == PROCESS_TERMINATED) {
|
} else if (result == PROCESS_TERMINATED) {
|
||||||
// Event already triggered
|
// Event already triggered
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
triggerEvent(SUPV_UPDATE_FAILED, result);
|
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.length = getFileSize(update.file);
|
||||||
update.memoryId = memoryId;
|
update.memoryId = memoryId;
|
||||||
update.startAddress = startAddress;
|
update.startAddress = startAddress;
|
||||||
result = calcImageCrc();
|
|
||||||
if (result != RETURN_OK) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
internalState = InternalState::UPDATE;
|
internalState = InternalState::UPDATE;
|
||||||
uartComIF->flushUartTxAndRxBuf(comCookie);
|
uartComIF->flushUartTxAndRxBuf(comCookie);
|
||||||
semaphore.release();
|
semaphore.release();
|
||||||
@ -140,6 +136,10 @@ void PlocSupvHelper::stopProcess() { terminate = true; }
|
|||||||
|
|
||||||
ReturnValue_t PlocSupvHelper::performUpdate() {
|
ReturnValue_t PlocSupvHelper::performUpdate() {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
result = calcImageCrc();
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
result = prepareUpdate();
|
result = prepareUpdate();
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -149,8 +149,7 @@ ReturnValue_t PlocSupvHelper::performUpdate() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
||||||
ProgressPrinter progressPrinter("Supervisor update: ", update.length,
|
ProgressPrinter progressPrinter("Supervisor update", update.length, ProgressPrinter::ONE_PERCENT);
|
||||||
ProgressPrinter::ONE_PERCENT);
|
|
||||||
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
||||||
uint8_t tempData[supv::WriteMemory::CHUNK_MAX];
|
uint8_t tempData[supv::WriteMemory::CHUNK_MAX];
|
||||||
std::ifstream file(update.file, std::ifstream::binary);
|
std::ifstream file(update.file, std::ifstream::binary);
|
||||||
@ -166,11 +165,17 @@ ReturnValue_t PlocSupvHelper::performUpdate() {
|
|||||||
if (remainingSize > supv::WriteMemory::CHUNK_MAX) {
|
if (remainingSize > supv::WriteMemory::CHUNK_MAX) {
|
||||||
dataLength = supv::WriteMemory::CHUNK_MAX;
|
dataLength = supv::WriteMemory::CHUNK_MAX;
|
||||||
} else {
|
} else {
|
||||||
dataLength = remainingSize;
|
dataLength = static_cast<uint16_t>(remainingSize);
|
||||||
}
|
}
|
||||||
if (file.is_open()) {
|
if (file.is_open()) {
|
||||||
file.seekg(bytesWritten, file.beg);
|
file.seekg(bytesWritten, file.beg);
|
||||||
file.read(reinterpret_cast<char*>(tempData), dataLength);
|
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;
|
remainingSize -= dataLength;
|
||||||
} else {
|
} else {
|
||||||
return FILE_CLOSED_ACCIDENTALLY;
|
return FILE_CLOSED_ACCIDENTALLY;
|
||||||
@ -236,14 +241,15 @@ ReturnValue_t PlocSupvHelper::prepareUpdate() {
|
|||||||
ReturnValue_t PlocSupvHelper::eraseMemory() {
|
ReturnValue_t PlocSupvHelper::eraseMemory() {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
supv::EraseMemory eraseMemory(update.memoryId, update.startAddress, update.length);
|
supv::EraseMemory eraseMemory(update.memoryId, update.startAddress, update.length);
|
||||||
result = handlePacketTransmission(eraseMemory);
|
result = handlePacketTransmission(eraseMemory, supv::recv_timeout::ERASE_MEMORY);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PlocSupvHelper::handlePacketTransmission(SpacePacket& packet) {
|
ReturnValue_t PlocSupvHelper::handlePacketTransmission(SpacePacket& packet,
|
||||||
|
uint32_t timeoutExecutionReport) {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
result = sendCommand(packet);
|
result = sendCommand(packet);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
@ -253,7 +259,7 @@ ReturnValue_t PlocSupvHelper::handlePacketTransmission(SpacePacket& packet) {
|
|||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
result = handleExe();
|
result = handleExe(timeoutExecutionReport);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
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;
|
ReturnValue_t result = RETURN_OK;
|
||||||
supv::TmPacket tmPacket;
|
supv::TmPacket tmPacket;
|
||||||
result = handleTmReception(&tmPacket, supv::SIZE_EXE_REPORT);
|
result = handleTmReception(&tmPacket, supv::SIZE_EXE_REPORT, timeout);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
triggerEvent(EXE_RECEPTION_FAILURE, result, static_cast<uint32_t>(rememberApid));
|
triggerEvent(EXE_RECEPTION_FAILURE, result, static_cast<uint32_t>(rememberApid));
|
||||||
sif::warning << "PlocSupvHelper::handleExe: Error in reception of execution report"
|
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;
|
ReturnValue_t result = RETURN_OK;
|
||||||
size_t readBytes = 0;
|
size_t readBytes = 0;
|
||||||
size_t currentBytes = 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);
|
result = receive(tmPacket->getWholeData() + readBytes, ¤tBytes, remainingBytes);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
@ -395,11 +403,21 @@ ReturnValue_t PlocSupvHelper::calcImageCrc() {
|
|||||||
std::ifstream file(update.file, std::ifstream::binary);
|
std::ifstream file(update.file, std::ifstream::binary);
|
||||||
uint16_t remainder = CRC16_INIT;
|
uint16_t remainder = CRC16_INIT;
|
||||||
uint8_t input;
|
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.seekg(byteCount, file.beg);
|
||||||
file.read(reinterpret_cast<char*>(&input), 1);
|
file.read(reinterpret_cast<char*>(&input), 1);
|
||||||
remainder = CRC::crc16ccitt(&input, sizeof(input), remainder);
|
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();
|
file.close();
|
||||||
update.crc = remainder;
|
update.crc = remainder;
|
||||||
return result;
|
return result;
|
||||||
@ -419,7 +437,8 @@ ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() {
|
|||||||
}
|
}
|
||||||
supv::UpdateStatusReport updateStatusReport;
|
supv::UpdateStatusReport updateStatusReport;
|
||||||
result = handleTmReception(&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) {
|
if (result != RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -487,7 +506,3 @@ ReturnValue_t PlocSupvHelper::handleEventBufferReception() {
|
|||||||
}
|
}
|
||||||
return result;
|
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
|
//! [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);
|
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;
|
static const uint16_t CRC16_INIT = 0xFFFF;
|
||||||
// Event buffer reply will carry 24 space packets with 1016 bytes and one space packet with
|
// Event buffer reply will carry 24 space packets with 1016 bytes and one space packet with
|
||||||
// 192 bytes
|
// 192 bytes
|
||||||
@ -180,7 +177,8 @@ class PlocSupvHelper : public SystemObject, public ExecutableObjectIF, public Ha
|
|||||||
|
|
||||||
ReturnValue_t performUpdate();
|
ReturnValue_t performUpdate();
|
||||||
ReturnValue_t performEventBufferRequest();
|
ReturnValue_t performEventBufferRequest();
|
||||||
ReturnValue_t handlePacketTransmission(SpacePacket& packet);
|
ReturnValue_t handlePacketTransmission(SpacePacket& packet,
|
||||||
|
uint32_t timeoutExecutionReport = 1000);
|
||||||
ReturnValue_t sendCommand(SpacePacket& packet);
|
ReturnValue_t sendCommand(SpacePacket& packet);
|
||||||
/**
|
/**
|
||||||
* @brief Function which reads form the communication interface
|
* @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 receive(uint8_t* data, size_t* readBytes, size_t requestBytes);
|
||||||
ReturnValue_t handleAck();
|
ReturnValue_t handleAck();
|
||||||
ReturnValue_t handleExe();
|
ReturnValue_t handleExe(uint32_t timeout = 1000);
|
||||||
void handleAckApidFailure(uint16_t apid);
|
void handleAckApidFailure(uint16_t apid);
|
||||||
void handleExeApidFailure(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 tmPacket Pointer to space packet where received data will be written to
|
||||||
* @param reaminingBytes Number of bytes to read in the space packet
|
* @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 prepareUpdate();
|
||||||
ReturnValue_t eraseMemory();
|
ReturnValue_t eraseMemory();
|
||||||
// Calculates CRC over image. Will be used for verification after update writing has
|
// 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
|
* @details
|
||||||
* Generated on: 2022-04-16 17:47:08
|
* Generated on: 2022-04-18 16:58:03
|
||||||
*/
|
*/
|
||||||
#include "translateEvents.h"
|
#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_EXE_FAILURE_REPORT_STRING = "SUPV_EXE_FAILURE_REPORT";
|
||||||
const char *SUPV_ACK_INVALID_APID_STRING = "SUPV_ACK_INVALID_APID";
|
const char *SUPV_ACK_INVALID_APID_STRING = "SUPV_ACK_INVALID_APID";
|
||||||
const char *SUPV_EXE_INVALID_APID_STRING = "SUPV_EXE_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) {
|
const char *translateEvents(Event event) {
|
||||||
switch ((event & 0xFFFF)) {
|
switch ((event & 0xFFFF)) {
|
||||||
@ -572,6 +574,10 @@ const char *translateEvents(Event event) {
|
|||||||
return SUPV_ACK_INVALID_APID_STRING;
|
return SUPV_ACK_INVALID_APID_STRING;
|
||||||
case (13614):
|
case (13614):
|
||||||
return SUPV_EXE_INVALID_APID_STRING;
|
return SUPV_EXE_INVALID_APID_STRING;
|
||||||
|
case (13615):
|
||||||
|
return ACK_RECEPTION_FAILURE_STRING;
|
||||||
|
case (13616):
|
||||||
|
return EXE_RECEPTION_FAILURE_STRING;
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN_EVENT";
|
return "UNKNOWN_EVENT";
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* @brief Auto-generated object translation file.
|
* @brief Auto-generated object translation file.
|
||||||
* @details
|
* @details
|
||||||
* Contains 116 translations.
|
* Contains 116 translations.
|
||||||
* Generated on: 2022-04-16 17:47:17
|
* Generated on: 2022-04-18 16:58:07
|
||||||
*/
|
*/
|
||||||
#include "translateObjects.h"
|
#include "translateObjects.h"
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
#include "fsfw/serviceinterface/ServiceInterfaceStream.h"
|
||||||
|
|
||||||
ProgressPrinter::ProgressPrinter(std::string name, uint32_t numSteps, uint32_t percentageResolution)
|
ProgressPrinter::ProgressPrinter(std::string name, uint32_t numSteps, uint32_t percentageResolution)
|
||||||
: name(name), numSteps(numSteps) {}
|
: name(name), numSteps(numSteps), percentageResolution(percentageResolution) {}
|
||||||
|
|
||||||
ProgressPrinter::~ProgressPrinter() {}
|
ProgressPrinter::~ProgressPrinter() {}
|
||||||
|
|
||||||
@ -11,6 +11,6 @@ void ProgressPrinter::print(uint32_t currentStep) {
|
|||||||
float progressInPercent = static_cast<float>(currentStep) / static_cast<float>(numSteps) * 100;
|
float progressInPercent = static_cast<float>(currentStep) / static_cast<float>(numSteps) * 100;
|
||||||
if (static_cast<uint32_t>(progressInPercent) >= nextProgressPrint) {
|
if (static_cast<uint32_t>(progressInPercent) >= nextProgressPrint) {
|
||||||
sif::info << name << " progress: " << progressInPercent << " %" << std::endl;
|
sif::info << name << " progress: " << progressInPercent << " %" << std::endl;
|
||||||
nextProgressPrint += FIVE_PERCENT;
|
nextProgressPrint += percentageResolution;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ class ProgressPrinter {
|
|||||||
std::string name = "";
|
std::string name = "";
|
||||||
uint32_t numSteps = 0;
|
uint32_t numSteps = 0;
|
||||||
uint32_t nextProgressPrint = 0;
|
uint32_t nextProgressPrint = 0;
|
||||||
|
uint32_t percentageResolution = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MISSION_UTILITY_PROGRESSPRINTER_H_ */
|
#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 */
|
/* SocketCAN driver */
|
||||||
|
#include <csp/csp.h>
|
||||||
#include <csp/drivers/can_socketcan.h>
|
#include <csp/drivers/can_socketcan.h>
|
||||||
|
#include <csp/interfaces/csp_if_can.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.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.h>
|
||||||
#include <linux/can/raw.h>
|
#include <linux/can/raw.h>
|
||||||
#include <linux/socket.h>
|
#include <linux/socket.h>
|
||||||
|
#include <net/if.h>
|
||||||
#include <csp/csp.h>
|
#include <pthread.h>
|
||||||
#include <csp/interfaces/csp_if_can.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
|
#ifdef CSP_HAVE_LIBSOCKETCAN
|
||||||
#include <libsocketcan.h>
|
#include <libsocketcan.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CAN_RX_TASK_PRIO 80
|
||||||
|
|
||||||
static struct can_socketcan_s {
|
static struct can_socketcan_s {
|
||||||
int socket;
|
int socket;
|
||||||
csp_iface_t interface;
|
csp_iface_t interface;
|
||||||
} socketcan[1] = {
|
} socketcan[1] = {
|
||||||
{
|
{
|
||||||
.interface = {
|
.interface =
|
||||||
.name = "CAN",
|
{
|
||||||
.nexthop = csp_can_tx,
|
.name = "CAN",
|
||||||
.mtu = CSP_CAN_MTU,
|
.nexthop = csp_can_tx,
|
||||||
.driver = &socketcan[0],
|
.mtu = CSP_CAN_MTU,
|
||||||
},
|
.driver = &socketcan[0],
|
||||||
},
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void * socketcan_rx_thread(void * parameters)
|
static void *socketcan_rx_thread(void *parameters) {
|
||||||
{
|
struct can_frame frame;
|
||||||
struct can_frame frame;
|
int nbytes;
|
||||||
int nbytes;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
/* Read CAN frame */
|
/* Read CAN frame */
|
||||||
nbytes = read(socketcan[0].socket, &frame, sizeof(frame));
|
nbytes = read(socketcan[0].socket, &frame, sizeof(frame));
|
||||||
if (nbytes < 0) {
|
if (nbytes < 0) {
|
||||||
csp_log_error("read: %s", strerror(errno));
|
csp_log_error("read: %s", strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nbytes != sizeof(frame)) {
|
if (nbytes != sizeof(frame)) {
|
||||||
csp_log_warn("Read incomplete CAN frame");
|
csp_log_warn("Read incomplete CAN frame");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Frame type */
|
/* Frame type */
|
||||||
if (frame.can_id & (CAN_ERR_FLAG | CAN_RTR_FLAG) || !(frame.can_id & CAN_EFF_FLAG)) {
|
if (frame.can_id & (CAN_ERR_FLAG | CAN_RTR_FLAG) || !(frame.can_id & CAN_EFF_FLAG)) {
|
||||||
/* Drop error and remote frames */
|
/* Drop error and remote frames */
|
||||||
csp_log_warn("Discarding ERR/RTR/SFF frame");
|
csp_log_warn("Discarding ERR/RTR/SFF frame");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Strip flags */
|
/* Strip flags */
|
||||||
frame.can_id &= CAN_EFF_MASK;
|
frame.can_id &= CAN_EFF_MASK;
|
||||||
|
|
||||||
/* Call RX callbacsp_can_rx_frameck */
|
/* Call RX callbacsp_can_rx_frameck */
|
||||||
csp_can_rx(&socketcan[0].interface, frame.can_id, frame.data, frame.can_dlc, NULL);
|
csp_can_rx(&socketcan[0].interface, frame.can_id, frame.data, frame.can_dlc, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We should never reach this point */
|
/* We should never reach this point */
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int create_receive_thread() {
|
||||||
int csp_can_tx_frame(csp_iface_t *interface, uint32_t id, const uint8_t * data, uint8_t dlc)
|
pthread_t rx_thread;
|
||||||
{
|
pthread_attr_t attributes;
|
||||||
struct can_frame frame;
|
if (pthread_attr_init(&attributes) != 0) {
|
||||||
int i, tries = 0;
|
return 1;
|
||||||
memset(&frame, 0, sizeof(frame));
|
}
|
||||||
if (dlc > 8)
|
if (pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED) != 0) {
|
||||||
return -1;
|
return 1;
|
||||||
|
}
|
||||||
/* Copy identifier */
|
if (pthread_attr_setschedpolicy(&attributes, SCHED_FIFO) != 0) {
|
||||||
frame.can_id = id | CAN_EFF_FLAG;
|
return 1;
|
||||||
|
}
|
||||||
/* Copy data to frame */
|
struct sched_param schedule_params;
|
||||||
for (i = 0; i < dlc; i++)
|
schedule_params.__sched_priority = CAN_RX_TASK_PRIO;
|
||||||
frame.data[i] = data[i];
|
if (pthread_attr_setschedparam(&attributes, &schedule_params) != 0) {
|
||||||
|
return 1;
|
||||||
/* Set DLC */
|
}
|
||||||
frame.can_dlc = dlc;
|
if (pthread_create(&rx_thread, NULL, socketcan_rx_thread, NULL) != 0) {
|
||||||
|
csp_log_error("pthread_create: %s", strerror(errno));
|
||||||
/* Send frame */
|
return 1;
|
||||||
while (write(socketcan[0].socket, &frame, sizeof(frame)) != sizeof(frame)) {
|
}
|
||||||
if (++tries < 1000 && errno == ENOBUFS) {
|
return 0;
|
||||||
/* 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)
|
int csp_can_tx_frame(csp_iface_t *interface, uint32_t id, const uint8_t *data, uint8_t dlc) {
|
||||||
{
|
struct can_frame frame;
|
||||||
struct ifreq ifr;
|
int i, tries = 0;
|
||||||
struct sockaddr_can addr;
|
memset(&frame, 0, sizeof(frame));
|
||||||
pthread_t rx_thread;
|
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
|
#ifdef CSP_HAVE_LIBSOCKETCAN
|
||||||
/* Set interface up */
|
/* Set interface up */
|
||||||
if (bitrate > 0) {
|
if (bitrate > 0) {
|
||||||
can_do_stop(ifc);
|
can_do_stop(ifc);
|
||||||
can_set_bitrate(ifc, bitrate);
|
can_set_bitrate(ifc, bitrate);
|
||||||
can_set_restart_ms(ifc, 100);
|
can_set_restart_ms(ifc, 100);
|
||||||
can_do_start(ifc);
|
can_do_start(ifc);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create socket */
|
/* Create socket */
|
||||||
if ((socketcan[0].socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
|
if ((socketcan[0].socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
|
||||||
csp_log_error("socket: %s", strerror(errno));
|
csp_log_error("socket: %s", strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Locate interface */
|
/* Locate interface */
|
||||||
strncpy(ifr.ifr_name, ifc, IFNAMSIZ - 1);
|
strncpy(ifr.ifr_name, ifc, IFNAMSIZ - 1);
|
||||||
if (ioctl(socketcan[0].socket, SIOCGIFINDEX, &ifr) < 0) {
|
if (ioctl(socketcan[0].socket, SIOCGIFINDEX, &ifr) < 0) {
|
||||||
csp_log_error("ioctl: %s", strerror(errno));
|
csp_log_error("ioctl: %s", strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
/* Bind the socket to CAN interface */
|
/* Bind the socket to CAN interface */
|
||||||
addr.can_family = AF_CAN;
|
addr.can_family = AF_CAN;
|
||||||
addr.can_ifindex = ifr.ifr_ifindex;
|
addr.can_ifindex = ifr.ifr_ifindex;
|
||||||
if (bind(socketcan[0].socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
if (bind(socketcan[0].socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
csp_log_error("bind: %s", strerror(errno));
|
csp_log_error("bind: %s", strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set filter mode */
|
/* Set filter mode */
|
||||||
if (promisc == 0) {
|
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;
|
if (setsockopt(socketcan[0].socket, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)) < 0) {
|
||||||
filter.can_id = CFP_MAKE_DST(csp_get_address());
|
csp_log_error("setsockopt: %s", strerror(errno));
|
||||||
filter.can_mask = CFP_MAKE_DST((1 << CFP_HOST_SIZE) - 1);
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (setsockopt(socketcan[0].socket, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)) < 0) {
|
if (create_receive_thread() != 0) {
|
||||||
csp_log_error("setsockopt: %s", strerror(errno));
|
return NULL;
|
||||||
return NULL;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
csp_iflist_add(&socketcan[0].interface);
|
||||||
|
|
||||||
/* Create receive thread */
|
return &socketcan[0].interface;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user