applied formatting
This commit is contained in:
parent
975b3cd294
commit
77c45c0de9
@ -1,20 +1,19 @@
|
||||
#include "InitMission.h"
|
||||
#include "ObjectFactory.h"
|
||||
|
||||
#include <OBSWConfig.h>
|
||||
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/objectmanager/ObjectManagerIF.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||
#include <fsfw/tasks/PeriodicTaskIF.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
|
||||
#include <mission/utility/InitMission.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "ObjectFactory.h"
|
||||
|
||||
#ifdef LINUX
|
||||
ServiceInterfaceStream sif::debug("DEBUG");
|
||||
ServiceInterfaceStream sif::info("INFO");
|
||||
@ -27,133 +26,132 @@ ServiceInterfaceStream sif::warning("WARNING", true);
|
||||
ServiceInterfaceStream sif::error("ERROR", true, false, true);
|
||||
#endif
|
||||
|
||||
ObjectManagerIF *objectManager = nullptr;
|
||||
ObjectManagerIF* objectManager = nullptr;
|
||||
|
||||
void initmission::initMission() {
|
||||
sif::info << "Building global objects.." << std::endl;
|
||||
/* Instantiate global object manager and also create all objects */
|
||||
ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr);
|
||||
sif::info << "Initializing all objects.." << std::endl;
|
||||
ObjectManager::instance()->initialize();
|
||||
sif::info << "Building global objects.." << std::endl;
|
||||
/* Instantiate global object manager and also create all objects */
|
||||
ObjectManager::instance()->setObjectFactoryFunction(ObjectFactory::produce, nullptr);
|
||||
sif::info << "Initializing all objects.." << std::endl;
|
||||
ObjectManager::instance()->initialize();
|
||||
|
||||
/* This function creates and starts all tasks */
|
||||
initTasks();
|
||||
/* This function creates and starts all tasks */
|
||||
initTasks();
|
||||
}
|
||||
|
||||
void initmission::initTasks() {
|
||||
TaskFactory* factory = TaskFactory::instance();
|
||||
if(factory == nullptr) {
|
||||
/* Should never happen ! */
|
||||
return;
|
||||
}
|
||||
TaskFactory* factory = TaskFactory::instance();
|
||||
if (factory == nullptr) {
|
||||
/* Should never happen ! */
|
||||
return;
|
||||
}
|
||||
#if OBSW_PRINT_MISSED_DEADLINES == 1
|
||||
void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline;
|
||||
void (*missedDeadlineFunc)(void) = TaskFactory::printMissedDeadline;
|
||||
#else
|
||||
void (*missedDeadlineFunc) (void) = nullptr;
|
||||
void (*missedDeadlineFunc)(void) = nullptr;
|
||||
#endif
|
||||
|
||||
/* TMTC Distribution */
|
||||
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
|
||||
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||
ReturnValue_t result = tmTcDistributor->addComponent(
|
||||
objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
sif::error << "Object add component failed" << std::endl;
|
||||
}
|
||||
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
sif::error << "Object add component failed" << std::endl;
|
||||
}
|
||||
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "Object add component failed" << std::endl;
|
||||
}
|
||||
/* TMTC Distribution */
|
||||
PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask(
|
||||
"DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||
ReturnValue_t result = tmTcDistributor->addComponent(objects::CCSDS_PACKET_DISTRIBUTOR);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "Object add component failed" << std::endl;
|
||||
}
|
||||
result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "Object add component failed" << std::endl;
|
||||
}
|
||||
result = tmTcDistributor->addComponent(objects::TM_FUNNEL);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "Object add component failed" << std::endl;
|
||||
}
|
||||
|
||||
/* UDP bridge */
|
||||
PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask(
|
||||
"TMTC_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||
result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
||||
}
|
||||
PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask(
|
||||
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||
result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "Add component UDP Polling failed" << std::endl;
|
||||
}
|
||||
/* UDP bridge */
|
||||
PeriodicTaskIF* tmtcBridgeTask = factory->createPeriodicTask(
|
||||
"TMTC_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc);
|
||||
result = tmtcBridgeTask->addComponent(objects::TMTC_BRIDGE);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "Add component UDP Unix Bridge failed" << std::endl;
|
||||
}
|
||||
PeriodicTaskIF* tmtcPollingTask = factory->createPeriodicTask(
|
||||
"UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||
result = tmtcPollingTask->addComponent(objects::TMTC_POLLING_TASK);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "Add component UDP Polling failed" << std::endl;
|
||||
}
|
||||
|
||||
/* PUS Services */
|
||||
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
|
||||
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
sif::error << "Object add component failed" << std::endl;
|
||||
}
|
||||
/* PUS Services */
|
||||
PeriodicTaskIF* pusVerification = factory->createPeriodicTask(
|
||||
"PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||
result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "Object add component failed" << std::endl;
|
||||
}
|
||||
|
||||
PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
|
||||
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||
result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||
}
|
||||
PeriodicTaskIF* pusEvents = factory->createPeriodicTask(
|
||||
"PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||
result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING);
|
||||
}
|
||||
|
||||
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
|
||||
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||
}
|
||||
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
|
||||
}
|
||||
PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask(
|
||||
"PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc);
|
||||
result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS2", objects::PUS_SERVICE_2_DEVICE_ACCESS);
|
||||
}
|
||||
result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT);
|
||||
}
|
||||
|
||||
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
|
||||
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||
}
|
||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
|
||||
}
|
||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
|
||||
}
|
||||
PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask(
|
||||
"PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT);
|
||||
}
|
||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS200", objects::PUS_SERVICE_200_MODE_MGMT);
|
||||
}
|
||||
result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS);
|
||||
}
|
||||
|
||||
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
|
||||
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
|
||||
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
|
||||
}
|
||||
PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask(
|
||||
"PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, missedDeadlineFunc);
|
||||
result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST);
|
||||
}
|
||||
|
||||
PeriodicTaskIF* testTask = factory->createPeriodicTask(
|
||||
"TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||
PeriodicTaskIF* testTask = factory->createPeriodicTask(
|
||||
"TEST_TASK", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc);
|
||||
#if OBSW_ADD_TEST_CODE == 1
|
||||
result = testTask->addComponent(objects::TEST_TASK);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
|
||||
}
|
||||
result = testTask->addComponent(objects::TEST_TASK);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK);
|
||||
}
|
||||
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||
|
||||
sif::info << "Starting tasks.." << std::endl;
|
||||
tmTcDistributor->startTask();
|
||||
tmtcBridgeTask->startTask();
|
||||
tmtcPollingTask->startTask();
|
||||
sif::info << "Starting tasks.." << std::endl;
|
||||
tmTcDistributor->startTask();
|
||||
tmtcBridgeTask->startTask();
|
||||
tmtcPollingTask->startTask();
|
||||
|
||||
pusVerification->startTask();
|
||||
pusEvents->startTask();
|
||||
pusHighPrio->startTask();
|
||||
pusMedPrio->startTask();
|
||||
pusLowPrio->startTask();
|
||||
pusVerification->startTask();
|
||||
pusEvents->startTask();
|
||||
pusHighPrio->startTask();
|
||||
pusMedPrio->startTask();
|
||||
pusLowPrio->startTask();
|
||||
|
||||
#if OBSW_ADD_TEST_CODE == 1
|
||||
testTask->startTask();
|
||||
testTask->startTask();
|
||||
#endif /* OBSW_ADD_TEST_CODE == 1 */
|
||||
|
||||
sif::info << "Tasks started.." << std::endl;
|
||||
sif::info << "Tasks started.." << std::endl;
|
||||
}
|
||||
|
@ -4,6 +4,6 @@
|
||||
namespace initmission {
|
||||
void initMission();
|
||||
void initTasks();
|
||||
};
|
||||
}; // namespace initmission
|
||||
|
||||
#endif /* BSP_LINUX_INITMISSION_H_ */
|
||||
|
@ -1,14 +1,14 @@
|
||||
#include "ObjectFactory.h"
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||
#include <mission/core/GenericFactory.h>
|
||||
#include <mission/utility/TmFunnel.h>
|
||||
#include <objects/systemObjectList.h>
|
||||
#include <tmtc/apid.h>
|
||||
#include <tmtc/pusIds.h>
|
||||
|
||||
#include <fsfw/tmtcservices/CommandingServiceBase.h>
|
||||
#include <fsfw/tmtcservices/PusServiceBase.h>
|
||||
|
||||
#include <mission/core/GenericFactory.h>
|
||||
#include <mission/utility/TmFunnel.h>
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
#if OBSW_USE_TMTC_TCP_BRIDGE == 0
|
||||
#include "fsfw/osal/common/UdpTcPollingTask.h"
|
||||
@ -20,29 +20,28 @@
|
||||
|
||||
#include <fsfw/tmtcpacket/pus/tm.h>
|
||||
|
||||
|
||||
#if OBSW_ADD_TEST_CODE == 1
|
||||
#include <test/testtasks/TestTask.h>
|
||||
#endif
|
||||
|
||||
void Factory::setStaticFrameworkObjectIds(){
|
||||
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
||||
void Factory::setStaticFrameworkObjectIds() {
|
||||
PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||
PusServiceBase::packetDestination = objects::TM_FUNNEL;
|
||||
|
||||
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
||||
CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
|
||||
CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;
|
||||
|
||||
TmFunnel::downlinkDestination = objects::TMTC_BRIDGE;
|
||||
// No storage object for now.
|
||||
TmFunnel::storageDestination = objects::NO_OBJECT;
|
||||
TmFunnel::downlinkDestination = objects::TMTC_BRIDGE;
|
||||
// No storage object for now.
|
||||
TmFunnel::storageDestination = objects::NO_OBJECT;
|
||||
|
||||
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
||||
TmPacketBase::timeStamperId = objects::TIME_STAMPER;
|
||||
VerificationReporter::messageReceiver = objects::PUS_SERVICE_1_VERIFICATION;
|
||||
TmPacketBase::timeStamperId = objects::TIME_STAMPER;
|
||||
}
|
||||
|
||||
void ObjectFactory::produce(void* args){
|
||||
Factory::setStaticFrameworkObjectIds();
|
||||
ObjectFactory::produceGenericObjects();
|
||||
void ObjectFactory::produce(void* args) {
|
||||
Factory::setStaticFrameworkObjectIds();
|
||||
ObjectFactory::produceGenericObjects();
|
||||
|
||||
new TestTask(objects::TEST_TASK);
|
||||
new TestTask(objects::TEST_TASK);
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
#ifndef BSP_LINUX_OBJECTFACTORY_H_
|
||||
#define BSP_LINUX_OBJECTFACTORY_H_
|
||||
|
||||
|
||||
namespace ObjectFactory {
|
||||
void setStatics();
|
||||
void produce(void* args);
|
||||
};
|
||||
void setStatics();
|
||||
void produce(void* args);
|
||||
}; // namespace ObjectFactory
|
||||
|
||||
#endif /* BSP_LINUX_OBJECTFACTORY_H_ */
|
||||
|
@ -32,7 +32,7 @@ SOFTWARE.
|
||||
|
||||
#define ETL_CHECK_PUSH_POP
|
||||
|
||||
#define ETL_CPP11_SUPPORTED 1
|
||||
#define ETL_NO_NULLPTR_SUPPORT 0
|
||||
#define ETL_CPP11_SUPPORTED 1
|
||||
#define ETL_NO_NULLPTR_SUPPORT 0
|
||||
|
||||
#endif
|
||||
|
@ -6,8 +6,9 @@
|
||||
extern "C" void __gcov_flush();
|
||||
#else
|
||||
void __gcov_flush() {
|
||||
sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if "
|
||||
"coverage information is desired.\n" << std::flush;
|
||||
sif::info << "GCC GCOV: Please supply GCOV=1 in Makefile if "
|
||||
"coverage information is desired.\n"
|
||||
<< std::flush;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -3,13 +3,9 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void printChar(const char* character, bool errStream) {
|
||||
if(errStream) {
|
||||
putc(*character, stderr);
|
||||
return;
|
||||
}
|
||||
putc(*character, stdout);
|
||||
if (errStream) {
|
||||
putc(*character, stderr);
|
||||
return;
|
||||
}
|
||||
putc(*character, stdout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,376 +1,351 @@
|
||||
#include "ArduinoComIF.h"
|
||||
#include "ArduinoCookie.h"
|
||||
|
||||
#include <fsfw/globalfunctions/DleEncoder.h>
|
||||
#include <fsfw/globalfunctions/CRC.h>
|
||||
#include <fsfw/globalfunctions/DleEncoder.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
#include "ArduinoCookie.h"
|
||||
|
||||
// This only works on Linux
|
||||
#ifdef LINUX
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#elif WIN32
|
||||
#include <windows.h>
|
||||
#include <strsafe.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
|
||||
ArduinoComIF::ArduinoComIF(object_id_t setObjectId, bool promptComIF,
|
||||
const char *serialDevice):
|
||||
rxBuffer(MAX_PACKET_SIZE * MAX_NUMBER_OF_SPI_DEVICES*10, true),
|
||||
SystemObject(setObjectId) {
|
||||
ArduinoComIF::ArduinoComIF(object_id_t setObjectId, bool promptComIF, const char *serialDevice)
|
||||
: rxBuffer(MAX_PACKET_SIZE * MAX_NUMBER_OF_SPI_DEVICES * 10, true), SystemObject(setObjectId) {
|
||||
#ifdef LINUX
|
||||
initialized = false;
|
||||
serialPort = ::open("/dev/ttyUSB0", O_RDWR);
|
||||
initialized = false;
|
||||
serialPort = ::open("/dev/ttyUSB0", O_RDWR);
|
||||
|
||||
if (serialPort < 0) {
|
||||
//configuration error
|
||||
printf("Error %i from open: %s\n", errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (serialPort < 0) {
|
||||
// configuration error
|
||||
printf("Error %i from open: %s\n", errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
struct termios tty;
|
||||
memset(&tty, 0, sizeof tty);
|
||||
struct termios tty;
|
||||
memset(&tty, 0, sizeof tty);
|
||||
|
||||
// Read in existing settings, and handle any error
|
||||
if (tcgetattr(serialPort, &tty) != 0) {
|
||||
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
// Read in existing settings, and handle any error
|
||||
if (tcgetattr(serialPort, &tty) != 0) {
|
||||
printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity
|
||||
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication
|
||||
tty.c_cflag |= CS8; // 8 bits per byte
|
||||
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control
|
||||
tty.c_lflag &= ~ICANON; //Disable Canonical Mode
|
||||
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
|
||||
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
|
||||
tty.c_cc[VTIME] = 0; // Non Blocking
|
||||
tty.c_cc[VMIN] = 0;
|
||||
tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity
|
||||
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication
|
||||
tty.c_cflag |= CS8; // 8 bits per byte
|
||||
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control
|
||||
tty.c_lflag &= ~ICANON; // Disable Canonical Mode
|
||||
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
|
||||
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
|
||||
tty.c_cc[VTIME] = 0; // Non Blocking
|
||||
tty.c_cc[VMIN] = 0;
|
||||
|
||||
cfsetispeed(&tty, B9600); //Baudrate
|
||||
cfsetispeed(&tty, B9600); // Baudrate
|
||||
|
||||
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
|
||||
//printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
|
||||
// printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
initialized = true;
|
||||
#elif WIN32
|
||||
DCB serialParams = { 0 };
|
||||
DCB serialParams = {0};
|
||||
|
||||
// we need to ask the COM port from the user.
|
||||
if(promptComIF) {
|
||||
sif::info << "Please enter the COM port (c to cancel): " << std::flush;
|
||||
std::string comPort;
|
||||
while(hCom == INVALID_HANDLE_VALUE) {
|
||||
// we need to ask the COM port from the user.
|
||||
if (promptComIF) {
|
||||
sif::info << "Please enter the COM port (c to cancel): " << std::flush;
|
||||
std::string comPort;
|
||||
while (hCom == INVALID_HANDLE_VALUE) {
|
||||
std::getline(std::cin, comPort);
|
||||
if (comPort[0] == 'c') {
|
||||
break;
|
||||
}
|
||||
const TCHAR *pcCommPort = comPort.c_str();
|
||||
hCom = CreateFileA(pcCommPort, // port name
|
||||
GENERIC_READ | GENERIC_WRITE, // Read/Write
|
||||
0, // No Sharing
|
||||
NULL, // No Security
|
||||
OPEN_EXISTING, // Open existing port only
|
||||
0, // Non Overlapped I/O
|
||||
NULL); // Null for Comm Devices
|
||||
|
||||
std::getline(std::cin, comPort);
|
||||
if(comPort[0] == 'c') {
|
||||
break;
|
||||
}
|
||||
const TCHAR *pcCommPort = comPort.c_str();
|
||||
hCom = CreateFileA(pcCommPort, //port name
|
||||
GENERIC_READ | GENERIC_WRITE, //Read/Write
|
||||
0, // No Sharing
|
||||
NULL, // No Security
|
||||
OPEN_EXISTING,// Open existing port only
|
||||
0, // Non Overlapped I/O
|
||||
NULL); // Null for Comm Devices
|
||||
if (hCom == INVALID_HANDLE_VALUE) {
|
||||
if (GetLastError() == 2) {
|
||||
sif::error << "COM Port does not found!" << std::endl;
|
||||
} else {
|
||||
TCHAR err[128];
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, sizeof(err), NULL);
|
||||
// Handle the error.
|
||||
sif::info << "CreateFileA Error code: " << GetLastError() << std::endl;
|
||||
sif::error << err << std::flush;
|
||||
}
|
||||
sif::info << "Please enter a valid COM port: " << std::flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hCom == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if(GetLastError() == 2) {
|
||||
sif::error << "COM Port does not found!" << std::endl;
|
||||
}
|
||||
else {
|
||||
TCHAR err[128];
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
|
||||
GetLastError(),
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
err, sizeof(err), NULL);
|
||||
// Handle the error.
|
||||
sif::info << "CreateFileA Error code: " << GetLastError()
|
||||
<< std::endl;
|
||||
sif::error << err << std::flush;
|
||||
}
|
||||
sif::info << "Please enter a valid COM port: " << std::flush;
|
||||
}
|
||||
}
|
||||
serialParams.DCBlength = sizeof(serialParams);
|
||||
if (baudRate == 9600) {
|
||||
serialParams.BaudRate = CBR_9600;
|
||||
}
|
||||
if (baudRate == 115200) {
|
||||
serialParams.BaudRate = CBR_115200;
|
||||
} else {
|
||||
serialParams.BaudRate = baudRate;
|
||||
}
|
||||
|
||||
}
|
||||
serialParams.ByteSize = 8;
|
||||
serialParams.Parity = NOPARITY;
|
||||
serialParams.StopBits = ONESTOPBIT;
|
||||
SetCommState(hCom, &serialParams);
|
||||
|
||||
|
||||
serialParams.DCBlength = sizeof(serialParams);
|
||||
if(baudRate == 9600) {
|
||||
serialParams.BaudRate = CBR_9600;
|
||||
}
|
||||
if(baudRate == 115200) {
|
||||
serialParams.BaudRate = CBR_115200;
|
||||
}
|
||||
else {
|
||||
serialParams.BaudRate = baudRate;
|
||||
}
|
||||
|
||||
serialParams.ByteSize = 8;
|
||||
serialParams.Parity = NOPARITY;
|
||||
serialParams.StopBits = ONESTOPBIT;
|
||||
SetCommState(hCom, &serialParams);
|
||||
|
||||
COMMTIMEOUTS timeout = { 0 };
|
||||
// This will set the read operation to be blocking until data is received
|
||||
// and then read continuously until there is a gap of one millisecond.
|
||||
timeout.ReadIntervalTimeout = 1;
|
||||
timeout.ReadTotalTimeoutConstant = 0;
|
||||
timeout.ReadTotalTimeoutMultiplier = 0;
|
||||
timeout.WriteTotalTimeoutConstant = 0;
|
||||
timeout.WriteTotalTimeoutMultiplier = 0;
|
||||
SetCommTimeouts(hCom, &timeout);
|
||||
// Serial port should now be read for operations.
|
||||
COMMTIMEOUTS timeout = {0};
|
||||
// This will set the read operation to be blocking until data is received
|
||||
// and then read continuously until there is a gap of one millisecond.
|
||||
timeout.ReadIntervalTimeout = 1;
|
||||
timeout.ReadTotalTimeoutConstant = 0;
|
||||
timeout.ReadTotalTimeoutMultiplier = 0;
|
||||
timeout.WriteTotalTimeoutConstant = 0;
|
||||
timeout.WriteTotalTimeoutMultiplier = 0;
|
||||
SetCommTimeouts(hCom, &timeout);
|
||||
// Serial port should now be read for operations.
|
||||
#endif
|
||||
}
|
||||
|
||||
ArduinoComIF::~ArduinoComIF() {
|
||||
#ifdef LINUX
|
||||
::close(serialPort);
|
||||
::close(serialPort);
|
||||
#elif WIN32
|
||||
CloseHandle(hCom);
|
||||
CloseHandle(hCom);
|
||||
#endif
|
||||
}
|
||||
ReturnValue_t ArduinoComIF::initializeInterface(CookieIF * cookie) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t ArduinoComIF::initializeInterface(CookieIF *cookie) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoComIF::sendMessage(CookieIF *cookie, const uint8_t *data,
|
||||
size_t len) {
|
||||
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie*>(cookie);
|
||||
if (arduinoCookie == nullptr) {
|
||||
return INVALID_COOKIE_TYPE;
|
||||
}
|
||||
ReturnValue_t ArduinoComIF::sendMessage(CookieIF *cookie, const uint8_t *data, size_t len) {
|
||||
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie *>(cookie);
|
||||
if (arduinoCookie == nullptr) {
|
||||
return INVALID_COOKIE_TYPE;
|
||||
}
|
||||
|
||||
return sendMessage(arduinoCookie->command, arduinoCookie->address, data,
|
||||
len);
|
||||
return sendMessage(arduinoCookie->command, arduinoCookie->address, data, len);
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoComIF::getSendSuccess(CookieIF *cookie) {
|
||||
return RETURN_OK;
|
||||
ReturnValue_t ArduinoComIF::getSendSuccess(CookieIF *cookie) { return RETURN_OK; }
|
||||
|
||||
ReturnValue_t ArduinoComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoComIF::requestReceiveMessage(CookieIF *cookie,
|
||||
size_t requestLen) {
|
||||
return RETURN_OK;
|
||||
ReturnValue_t ArduinoComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) {
|
||||
handleSerialPortRx();
|
||||
|
||||
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie *>(cookie);
|
||||
if (arduinoCookie == nullptr) {
|
||||
return INVALID_COOKIE_TYPE;
|
||||
}
|
||||
|
||||
*buffer = arduinoCookie->replyBuffer.data();
|
||||
*size = arduinoCookie->receivedDataLen;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t ArduinoComIF::readReceivedMessage(CookieIF *cookie,
|
||||
uint8_t **buffer, size_t *size) {
|
||||
ReturnValue_t ArduinoComIF::sendMessage(uint8_t command, uint8_t address, const uint8_t *data,
|
||||
size_t dataLen) {
|
||||
if (dataLen > UINT16_MAX) {
|
||||
return TOO_MUCH_DATA;
|
||||
}
|
||||
|
||||
handleSerialPortRx();
|
||||
// being conservative here
|
||||
uint8_t sendBuffer[(dataLen + 6) * 2 + 2];
|
||||
|
||||
ArduinoCookie *arduinoCookie = dynamic_cast<ArduinoCookie*>(cookie);
|
||||
if (arduinoCookie == nullptr) {
|
||||
return INVALID_COOKIE_TYPE;
|
||||
}
|
||||
sendBuffer[0] = DleEncoder::STX_CHAR;
|
||||
|
||||
*buffer = arduinoCookie->replyBuffer.data();
|
||||
*size = arduinoCookie->receivedDataLen;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
uint8_t *currentPosition = sendBuffer + 1;
|
||||
size_t remainingLen = sizeof(sendBuffer) - 1;
|
||||
size_t encodedLen = 0;
|
||||
|
||||
ReturnValue_t ArduinoComIF::sendMessage(uint8_t command,
|
||||
uint8_t address, const uint8_t *data, size_t dataLen) {
|
||||
if (dataLen > UINT16_MAX) {
|
||||
return TOO_MUCH_DATA;
|
||||
}
|
||||
ReturnValue_t result =
|
||||
DleEncoder::encode(&command, 1, currentPosition, remainingLen, &encodedLen, false);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
currentPosition += encodedLen;
|
||||
remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen
|
||||
|
||||
//being conservative here
|
||||
uint8_t sendBuffer[(dataLen + 6) * 2 + 2];
|
||||
result = DleEncoder::encode(&address, 1, currentPosition, remainingLen, &encodedLen, false);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
currentPosition += encodedLen;
|
||||
remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen
|
||||
|
||||
sendBuffer[0] = DleEncoder::STX_CHAR;
|
||||
uint8_t temporaryBuffer[2];
|
||||
|
||||
uint8_t *currentPosition = sendBuffer + 1;
|
||||
size_t remainingLen = sizeof(sendBuffer) - 1;
|
||||
size_t encodedLen = 0;
|
||||
// note to Lukas: yes we _could_ use Serialize here, but for 16 bit it is a bit too much...
|
||||
temporaryBuffer[0] = dataLen >> 8; // we checked dataLen above
|
||||
temporaryBuffer[1] = dataLen;
|
||||
|
||||
ReturnValue_t result = DleEncoder::encode(&command, 1, currentPosition,
|
||||
remainingLen, &encodedLen, false);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
currentPosition += encodedLen;
|
||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
||||
result =
|
||||
DleEncoder::encode(temporaryBuffer, 2, currentPosition, remainingLen, &encodedLen, false);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
currentPosition += encodedLen;
|
||||
remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen
|
||||
|
||||
result = DleEncoder::encode(&address, 1, currentPosition, remainingLen,
|
||||
&encodedLen, false);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
currentPosition += encodedLen;
|
||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
||||
// encoding the actual data
|
||||
result = DleEncoder::encode(data, dataLen, currentPosition, remainingLen, &encodedLen, false);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
currentPosition += encodedLen;
|
||||
remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen
|
||||
|
||||
uint8_t temporaryBuffer[2];
|
||||
uint16_t crc = CRC::crc16ccitt(&command, 1);
|
||||
crc = CRC::crc16ccitt(&address, 1, crc);
|
||||
// fortunately the length is still there
|
||||
crc = CRC::crc16ccitt(temporaryBuffer, 2, crc);
|
||||
crc = CRC::crc16ccitt(data, dataLen, crc);
|
||||
|
||||
//note to Lukas: yes we _could_ use Serialize here, but for 16 bit it is a bit too much...
|
||||
temporaryBuffer[0] = dataLen >> 8; //we checked dataLen above
|
||||
temporaryBuffer[1] = dataLen;
|
||||
temporaryBuffer[0] = crc >> 8;
|
||||
temporaryBuffer[1] = crc;
|
||||
|
||||
result = DleEncoder::encode(temporaryBuffer, 2, currentPosition,
|
||||
remainingLen, &encodedLen, false);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
currentPosition += encodedLen;
|
||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
||||
result =
|
||||
DleEncoder::encode(temporaryBuffer, 2, currentPosition, remainingLen, &encodedLen, false);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
currentPosition += encodedLen;
|
||||
remainingLen -= encodedLen; // DleEncoder will never return encodedLen > remainingLen
|
||||
|
||||
//encoding the actual data
|
||||
result = DleEncoder::encode(data, dataLen, currentPosition, remainingLen,
|
||||
&encodedLen, false);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
currentPosition += encodedLen;
|
||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
||||
if (remainingLen > 0) {
|
||||
*currentPosition = DleEncoder::ETX_CHAR;
|
||||
}
|
||||
remainingLen -= 1;
|
||||
|
||||
uint16_t crc = CRC::crc16ccitt(&command, 1);
|
||||
crc = CRC::crc16ccitt(&address, 1, crc);
|
||||
//fortunately the length is still there
|
||||
crc = CRC::crc16ccitt(temporaryBuffer, 2, crc);
|
||||
crc = CRC::crc16ccitt(data, dataLen, crc);
|
||||
|
||||
temporaryBuffer[0] = crc >> 8;
|
||||
temporaryBuffer[1] = crc;
|
||||
|
||||
result = DleEncoder::encode(temporaryBuffer, 2, currentPosition,
|
||||
remainingLen, &encodedLen, false);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
currentPosition += encodedLen;
|
||||
remainingLen -= encodedLen; //DleEncoder will never return encodedLen > remainingLen
|
||||
|
||||
if (remainingLen > 0) {
|
||||
*currentPosition = DleEncoder::ETX_CHAR;
|
||||
}
|
||||
remainingLen -= 1;
|
||||
|
||||
encodedLen = sizeof(sendBuffer) - remainingLen;
|
||||
encodedLen = sizeof(sendBuffer) - remainingLen;
|
||||
|
||||
#ifdef LINUX
|
||||
ssize_t writtenlen = ::write(serialPort, sendBuffer, encodedLen);
|
||||
if (writtenlen < 0) {
|
||||
//we could try to find out what happened...
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (writtenlen != encodedLen) {
|
||||
//the OS failed us, we do not try to block until everything is written, as
|
||||
//we can not block the whole system here
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
ssize_t writtenlen = ::write(serialPort, sendBuffer, encodedLen);
|
||||
if (writtenlen < 0) {
|
||||
// we could try to find out what happened...
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (writtenlen != encodedLen) {
|
||||
// the OS failed us, we do not try to block until everything is written, as
|
||||
// we can not block the whole system here
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
#elif WIN32
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ArduinoComIF::handleSerialPortRx() {
|
||||
#ifdef LINUX
|
||||
uint32_t availableSpace = rxBuffer.availableWriteSpace();
|
||||
uint32_t availableSpace = rxBuffer.availableWriteSpace();
|
||||
|
||||
uint8_t dataFromSerial[availableSpace];
|
||||
uint8_t dataFromSerial[availableSpace];
|
||||
|
||||
ssize_t bytesRead = read(serialPort, dataFromSerial,
|
||||
sizeof(dataFromSerial));
|
||||
ssize_t bytesRead = read(serialPort, dataFromSerial, sizeof(dataFromSerial));
|
||||
|
||||
if (bytesRead < 0) {
|
||||
return;
|
||||
}
|
||||
if (bytesRead < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
rxBuffer.writeData(dataFromSerial, bytesRead);
|
||||
rxBuffer.writeData(dataFromSerial, bytesRead);
|
||||
|
||||
uint8_t dataReceivedSoFar[rxBuffer.getMaxSize()];
|
||||
uint8_t dataReceivedSoFar[rxBuffer.getMaxSize()];
|
||||
|
||||
uint32_t dataLenReceivedSoFar = 0;
|
||||
uint32_t dataLenReceivedSoFar = 0;
|
||||
|
||||
rxBuffer.readData(dataReceivedSoFar, sizeof(dataReceivedSoFar), true,
|
||||
&dataLenReceivedSoFar);
|
||||
rxBuffer.readData(dataReceivedSoFar, sizeof(dataReceivedSoFar), true, &dataLenReceivedSoFar);
|
||||
|
||||
//look for STX
|
||||
size_t firstSTXinRawData = 0;
|
||||
while ((firstSTXinRawData < dataLenReceivedSoFar)
|
||||
&& (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR)) {
|
||||
firstSTXinRawData++;
|
||||
}
|
||||
// look for STX
|
||||
size_t firstSTXinRawData = 0;
|
||||
while ((firstSTXinRawData < dataLenReceivedSoFar) &&
|
||||
(dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR)) {
|
||||
firstSTXinRawData++;
|
||||
}
|
||||
|
||||
if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR) {
|
||||
//there is no STX in our data, throw it away...
|
||||
rxBuffer.deleteData(dataLenReceivedSoFar);
|
||||
return;
|
||||
}
|
||||
if (dataReceivedSoFar[firstSTXinRawData] != DleEncoder::STX_CHAR) {
|
||||
// there is no STX in our data, throw it away...
|
||||
rxBuffer.deleteData(dataLenReceivedSoFar);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t packet[MAX_PACKET_SIZE];
|
||||
size_t packetLen = 0;
|
||||
uint8_t packet[MAX_PACKET_SIZE];
|
||||
size_t packetLen = 0;
|
||||
|
||||
size_t readSize = 0;
|
||||
size_t readSize = 0;
|
||||
|
||||
ReturnValue_t result = DleEncoder::decode(
|
||||
dataReceivedSoFar + firstSTXinRawData,
|
||||
dataLenReceivedSoFar - firstSTXinRawData, &readSize, packet,
|
||||
sizeof(packet), &packetLen);
|
||||
ReturnValue_t result = DleEncoder::decode(dataReceivedSoFar + firstSTXinRawData,
|
||||
dataLenReceivedSoFar - firstSTXinRawData, &readSize,
|
||||
packet, sizeof(packet), &packetLen);
|
||||
|
||||
size_t toDelete = firstSTXinRawData;
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
handlePacket(packet, packetLen);
|
||||
size_t toDelete = firstSTXinRawData;
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
handlePacket(packet, packetLen);
|
||||
|
||||
// after handling the packet, we can delete it from the raw stream,
|
||||
// it has been copied to packet
|
||||
toDelete += readSize;
|
||||
}
|
||||
// after handling the packet, we can delete it from the raw stream,
|
||||
// it has been copied to packet
|
||||
toDelete += readSize;
|
||||
}
|
||||
|
||||
//remove Data which was processed
|
||||
rxBuffer.deleteData(toDelete);
|
||||
// remove Data which was processed
|
||||
rxBuffer.deleteData(toDelete);
|
||||
#elif WIN32
|
||||
#endif
|
||||
}
|
||||
|
||||
void ArduinoComIF::setBaudrate(uint32_t baudRate) {
|
||||
this->baudRate = baudRate;
|
||||
}
|
||||
void ArduinoComIF::setBaudrate(uint32_t baudRate) { this->baudRate = baudRate; }
|
||||
|
||||
void ArduinoComIF::handlePacket(uint8_t *packet, size_t packetLen) {
|
||||
uint16_t crc = CRC::crc16ccitt(packet, packetLen);
|
||||
if (crc != 0) {
|
||||
//CRC error
|
||||
return;
|
||||
}
|
||||
uint16_t crc = CRC::crc16ccitt(packet, packetLen);
|
||||
if (crc != 0) {
|
||||
// CRC error
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t command = packet[0];
|
||||
uint8_t address = packet[1];
|
||||
uint8_t command = packet[0];
|
||||
uint8_t address = packet[1];
|
||||
|
||||
uint16_t size = (packet[2] << 8) + packet[3];
|
||||
uint16_t size = (packet[2] << 8) + packet[3];
|
||||
|
||||
if (size != packetLen - 6) {
|
||||
//Invalid Length
|
||||
return;
|
||||
}
|
||||
if (size != packetLen - 6) {
|
||||
// Invalid Length
|
||||
return;
|
||||
}
|
||||
|
||||
switch (command) {
|
||||
case ArduinoCookie::SPI: {
|
||||
//ArduinoCookie **itsComplicated;
|
||||
auto findIter = spiMap.find(address);
|
||||
if (findIter == spiMap.end()) {
|
||||
//we do no know this address
|
||||
return;
|
||||
}
|
||||
ArduinoCookie& cookie = findIter->second;
|
||||
if (packetLen > cookie.maxReplySize + 6) {
|
||||
packetLen = cookie.maxReplySize + 6;
|
||||
}
|
||||
std::memcpy(cookie.replyBuffer.data(), packet + 4, packetLen - 6);
|
||||
cookie.receivedDataLen = packetLen - 6;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
switch (command) {
|
||||
case ArduinoCookie::SPI: {
|
||||
// ArduinoCookie **itsComplicated;
|
||||
auto findIter = spiMap.find(address);
|
||||
if (findIter == spiMap.end()) {
|
||||
// we do no know this address
|
||||
return;
|
||||
}
|
||||
ArduinoCookie &cookie = findIter->second;
|
||||
if (packetLen > cookie.maxReplySize + 6) {
|
||||
packetLen = cookie.maxReplySize + 6;
|
||||
}
|
||||
std::memcpy(cookie.replyBuffer.data(), packet + 4, packetLen - 6);
|
||||
cookie.receivedDataLen = packetLen - 6;
|
||||
} break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
#include <fsfw/container/FixedMap.h>
|
||||
#include <fsfw/container/SimpleRingBuffer.h>
|
||||
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
@ -14,56 +14,53 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
//Forward declaration, so users don't peek
|
||||
// Forward declaration, so users don't peek
|
||||
class ArduinoCookie;
|
||||
|
||||
class ArduinoComIF: public SystemObject,
|
||||
public DeviceCommunicationIF {
|
||||
public:
|
||||
static const uint8_t MAX_NUMBER_OF_SPI_DEVICES = 8;
|
||||
static const uint8_t MAX_PACKET_SIZE = 64;
|
||||
class ArduinoComIF : public SystemObject, public DeviceCommunicationIF {
|
||||
public:
|
||||
static const uint8_t MAX_NUMBER_OF_SPI_DEVICES = 8;
|
||||
static const uint8_t MAX_PACKET_SIZE = 64;
|
||||
|
||||
static const uint8_t COMMAND_INVALID = -1;
|
||||
static const uint8_t COMMAND_SPI = 1;
|
||||
static const uint8_t COMMAND_INVALID = -1;
|
||||
static const uint8_t COMMAND_SPI = 1;
|
||||
|
||||
ArduinoComIF(object_id_t setObjectId, bool promptComIF = false,
|
||||
const char *serialDevice = nullptr);
|
||||
void setBaudrate(uint32_t baudRate);
|
||||
ArduinoComIF(object_id_t setObjectId, bool promptComIF = false,
|
||||
const char *serialDevice = nullptr);
|
||||
void setBaudrate(uint32_t baudRate);
|
||||
|
||||
virtual ~ArduinoComIF();
|
||||
virtual ~ArduinoComIF();
|
||||
|
||||
/** DeviceCommunicationIF overrides */
|
||||
virtual ReturnValue_t initializeInterface(CookieIF * cookie) override;
|
||||
virtual ReturnValue_t sendMessage(CookieIF *cookie,
|
||||
const uint8_t * sendData, size_t sendLen) override;
|
||||
virtual ReturnValue_t getSendSuccess(CookieIF *cookie) override;
|
||||
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie,
|
||||
size_t requestLen) override;
|
||||
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie,
|
||||
uint8_t **buffer, size_t *size) override;
|
||||
/** DeviceCommunicationIF overrides */
|
||||
virtual ReturnValue_t initializeInterface(CookieIF *cookie) override;
|
||||
virtual ReturnValue_t sendMessage(CookieIF *cookie, const uint8_t *sendData,
|
||||
size_t sendLen) override;
|
||||
virtual ReturnValue_t getSendSuccess(CookieIF *cookie) override;
|
||||
virtual ReturnValue_t requestReceiveMessage(CookieIF *cookie, size_t requestLen) override;
|
||||
virtual ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
|
||||
size_t *size) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
#ifdef LINUX
|
||||
#elif WIN32
|
||||
HANDLE hCom = INVALID_HANDLE_VALUE;
|
||||
HANDLE hCom = INVALID_HANDLE_VALUE;
|
||||
#endif
|
||||
// remembering if the initialization in the ctor worked
|
||||
// if not, all calls are disabled
|
||||
bool initialized = false;
|
||||
int serialPort = 0;
|
||||
// Default baud rate is 9600 for now.
|
||||
uint32_t baudRate = 9600;
|
||||
// remembering if the initialization in the ctor worked
|
||||
// if not, all calls are disabled
|
||||
bool initialized = false;
|
||||
int serialPort = 0;
|
||||
// Default baud rate is 9600 for now.
|
||||
uint32_t baudRate = 9600;
|
||||
|
||||
//used to know where to put the data if a reply is received
|
||||
std::map<uint8_t, ArduinoCookie> spiMap;
|
||||
// used to know where to put the data if a reply is received
|
||||
std::map<uint8_t, ArduinoCookie> spiMap;
|
||||
|
||||
SimpleRingBuffer rxBuffer;
|
||||
SimpleRingBuffer rxBuffer;
|
||||
|
||||
ReturnValue_t sendMessage(uint8_t command, uint8_t address,
|
||||
const uint8_t *data, size_t dataLen);
|
||||
void handleSerialPortRx();
|
||||
ReturnValue_t sendMessage(uint8_t command, uint8_t address, const uint8_t *data, size_t dataLen);
|
||||
void handleSerialPortRx();
|
||||
|
||||
void handlePacket(uint8_t *packet, size_t packetLen);
|
||||
void handlePacket(uint8_t *packet, size_t packetLen);
|
||||
};
|
||||
|
||||
#endif /* MISSION_ARDUINOCOMMINTERFACE_H_ */
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include <bsp_hosted/comIF/ArduinoCookie.h>
|
||||
|
||||
ArduinoCookie::ArduinoCookie(Protocol_t protocol, uint8_t address,
|
||||
const size_t maxReplySize) :
|
||||
protocol(protocol), command(protocol), address(address),
|
||||
maxReplySize(maxReplySize), replyBuffer(maxReplySize) {
|
||||
}
|
||||
|
||||
ArduinoCookie::ArduinoCookie(Protocol_t protocol, uint8_t address, const size_t maxReplySize)
|
||||
: protocol(protocol),
|
||||
command(protocol),
|
||||
address(address),
|
||||
maxReplySize(maxReplySize),
|
||||
replyBuffer(maxReplySize) {}
|
||||
|
@ -2,26 +2,21 @@
|
||||
#define MISSION_ARDUINO_ARDUINOCOOKIE_H_
|
||||
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class ArduinoCookie: public CookieIF {
|
||||
public:
|
||||
enum Protocol_t: uint8_t {
|
||||
INVALID,
|
||||
SPI,
|
||||
I2C
|
||||
};
|
||||
class ArduinoCookie : public CookieIF {
|
||||
public:
|
||||
enum Protocol_t : uint8_t { INVALID, SPI, I2C };
|
||||
|
||||
ArduinoCookie(Protocol_t protocol, uint8_t address,
|
||||
const size_t maxReplySize);
|
||||
|
||||
Protocol_t protocol;
|
||||
uint8_t command;
|
||||
uint8_t address;
|
||||
std::vector<uint8_t> replyBuffer;
|
||||
size_t receivedDataLen = 0;
|
||||
size_t maxReplySize;
|
||||
ArduinoCookie(Protocol_t protocol, uint8_t address, const size_t maxReplySize);
|
||||
|
||||
Protocol_t protocol;
|
||||
uint8_t command;
|
||||
uint8_t address;
|
||||
std::vector<uint8_t> replyBuffer;
|
||||
size_t receivedDataLen = 0;
|
||||
size_t maxReplySize;
|
||||
};
|
||||
|
||||
#endif /* MISSION_ARDUINO_ARDUINOCOOKIE_H_ */
|
||||
|
@ -2,56 +2,53 @@
|
||||
#define FSFWCONFIG_DEVICES_GPIOIDS_H_
|
||||
|
||||
namespace gpioIds {
|
||||
enum gpioId_t {
|
||||
HEATER_0,
|
||||
HEATER_1,
|
||||
HEATER_2,
|
||||
HEATER_3,
|
||||
HEATER_4,
|
||||
HEATER_5,
|
||||
HEATER_6,
|
||||
HEATER_7,
|
||||
DEPLSA1,
|
||||
DEPLSA2,
|
||||
enum gpioId_t {
|
||||
HEATER_0,
|
||||
HEATER_1,
|
||||
HEATER_2,
|
||||
HEATER_3,
|
||||
HEATER_4,
|
||||
HEATER_5,
|
||||
HEATER_6,
|
||||
HEATER_7,
|
||||
DEPLSA1,
|
||||
DEPLSA2,
|
||||
|
||||
MGM_0_LIS3_CS,
|
||||
MGM_1_RM3100_CS,
|
||||
GYRO_0_ADIS_CS,
|
||||
GYRO_1_L3G_CS,
|
||||
GYRO_2_L3G_CS,
|
||||
MGM_2_LIS3_CS,
|
||||
MGM_3_RM3100_CS,
|
||||
MGM_0_LIS3_CS,
|
||||
MGM_1_RM3100_CS,
|
||||
GYRO_0_ADIS_CS,
|
||||
GYRO_1_L3G_CS,
|
||||
GYRO_2_L3G_CS,
|
||||
MGM_2_LIS3_CS,
|
||||
MGM_3_RM3100_CS,
|
||||
|
||||
TEST_ID_0,
|
||||
TEST_ID_1,
|
||||
TEST_ID_0,
|
||||
TEST_ID_1,
|
||||
|
||||
RTD_IC_3,
|
||||
RTD_IC_4,
|
||||
RTD_IC_5,
|
||||
RTD_IC_6,
|
||||
RTD_IC_7,
|
||||
RTD_IC_8,
|
||||
RTD_IC_9,
|
||||
RTD_IC_10,
|
||||
RTD_IC_11,
|
||||
RTD_IC_12,
|
||||
RTD_IC_13,
|
||||
RTD_IC_14,
|
||||
RTD_IC_15,
|
||||
RTD_IC_16,
|
||||
RTD_IC_17,
|
||||
RTD_IC_18,
|
||||
RTD_IC_3,
|
||||
RTD_IC_4,
|
||||
RTD_IC_5,
|
||||
RTD_IC_6,
|
||||
RTD_IC_7,
|
||||
RTD_IC_8,
|
||||
RTD_IC_9,
|
||||
RTD_IC_10,
|
||||
RTD_IC_11,
|
||||
RTD_IC_12,
|
||||
RTD_IC_13,
|
||||
RTD_IC_14,
|
||||
RTD_IC_15,
|
||||
RTD_IC_16,
|
||||
RTD_IC_17,
|
||||
RTD_IC_18,
|
||||
|
||||
SPI_MUX_BIT_1,
|
||||
SPI_MUX_BIT_2,
|
||||
SPI_MUX_BIT_3,
|
||||
SPI_MUX_BIT_4,
|
||||
SPI_MUX_BIT_5,
|
||||
SPI_MUX_BIT_6
|
||||
};
|
||||
SPI_MUX_BIT_1,
|
||||
SPI_MUX_BIT_2,
|
||||
SPI_MUX_BIT_3,
|
||||
SPI_MUX_BIT_4,
|
||||
SPI_MUX_BIT_5,
|
||||
SPI_MUX_BIT_6
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* FSFWCONFIG_DEVICES_GPIOIDS_H_ */
|
||||
|
@ -4,55 +4,54 @@
|
||||
#include <OBSWConfig.h>
|
||||
|
||||
namespace pcduSwitches {
|
||||
/* Switches are uint8_t datatype and go from 0 to 255 */
|
||||
enum SwitcherList {
|
||||
Q7S,
|
||||
PAYLOAD_PCDU_CH1,
|
||||
RW,
|
||||
TCS_BOARD_8V_HEATER_IN,
|
||||
SUS_REDUNDANT,
|
||||
DEPLOYMENT_MECHANISM,
|
||||
PAYLOAD_PCDU_CH6,
|
||||
ACS_BOARD_SIDE_B,
|
||||
PAYLOAD_CAMERA,
|
||||
TCS_BOARD_3V3,
|
||||
SYRLINKS,
|
||||
STAR_TRACKER,
|
||||
MGT,
|
||||
SUS_NOMINAL,
|
||||
SOLAR_CELL_EXP,
|
||||
PLOC,
|
||||
ACS_BOARD_SIDE_A,
|
||||
NUMBER_OF_SWITCHES
|
||||
};
|
||||
/* Switches are uint8_t datatype and go from 0 to 255 */
|
||||
enum SwitcherList {
|
||||
Q7S,
|
||||
PAYLOAD_PCDU_CH1,
|
||||
RW,
|
||||
TCS_BOARD_8V_HEATER_IN,
|
||||
SUS_REDUNDANT,
|
||||
DEPLOYMENT_MECHANISM,
|
||||
PAYLOAD_PCDU_CH6,
|
||||
ACS_BOARD_SIDE_B,
|
||||
PAYLOAD_CAMERA,
|
||||
TCS_BOARD_3V3,
|
||||
SYRLINKS,
|
||||
STAR_TRACKER,
|
||||
MGT,
|
||||
SUS_NOMINAL,
|
||||
SOLAR_CELL_EXP,
|
||||
PLOC,
|
||||
ACS_BOARD_SIDE_A,
|
||||
NUMBER_OF_SWITCHES
|
||||
};
|
||||
|
||||
static const uint8_t ON = 1;
|
||||
static const uint8_t OFF = 0;
|
||||
static const uint8_t ON = 1;
|
||||
static const uint8_t OFF = 0;
|
||||
|
||||
/* Output states after reboot of the PDUs */
|
||||
static const uint8_t INIT_STATE_Q7S = ON;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF;
|
||||
static const uint8_t INIT_STATE_RW = OFF;
|
||||
/* Output states after reboot of the PDUs */
|
||||
static const uint8_t INIT_STATE_Q7S = ON;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF;
|
||||
static const uint8_t INIT_STATE_RW = OFF;
|
||||
#if BOARD_TE0720 == 1
|
||||
/* Because the TE0720 is not connected to the PCDU, this switch is always on */
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON;
|
||||
/* Because the TE0720 is not connected to the PCDU, this switch is always on */
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON;
|
||||
#else
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF;
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF;
|
||||
#endif
|
||||
static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF;
|
||||
static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF;
|
||||
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF;
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF;
|
||||