diff --git a/CMakeLists.txt b/CMakeLists.txt index 05ca6671..99eb93bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ set(LIB_CSP_NAME libcsp) set(FSFW_PATH fsfw) set(MISSION_PATH mission) set(CSPLIB_PATH libcsp) +set(TEST_PATH test/testtasks) set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF) @@ -84,6 +85,7 @@ endif() add_subdirectory(${BSP_PATH}) add_subdirectory(${FSFW_PATH}) add_subdirectory(${MISSION_PATH}) +add_subdirectory(${TEST_PATH}) ################################################################################ # Post-Sources preparation diff --git a/bsp_q7s/InitMission.cpp b/bsp_q7s/InitMission.cpp index ee39c4ea..fd4cde43 100644 --- a/bsp_q7s/InitMission.cpp +++ b/bsp_q7s/InitMission.cpp @@ -157,6 +157,16 @@ void InitMission::initTasks(){ // << "failed!" << std::endl; // } +#endif + +#if TE0720 == 1 && TEST_LIBGPIOD == 1 + PeriodicTaskIF* TestTask = TaskFactory::instance()-> + createPeriodicTask("Libgpiod Test Task", 60, + PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, nullptr); + result = TestTask->addComponent(objects::LIBGPIOD_TEST); + if(result != HasReturnvaluesIF::RETURN_OK){ + sif::error << "Object add component libgpiod test task object" << std::endl; + } #endif //Main thread sleep @@ -174,8 +184,8 @@ void InitMission::initTasks(){ PusMedPrio->startTask(); PusLowPrio->startTask(); -#if OBSW_ADD_TEST_CODE == 1 -// TestTimeslotTask->startTask(); +#if TE0720 == 1 && TEST_LIBGPIOD == 1 + TestTask->startTask(); #endif sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index 37692eb6..7ee93a2c 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -33,6 +33,10 @@ #include #include +# if TEST_LIBGPIOD == 1 +#include "LibgpioTest.h" +#endif + void Factory::setStaticFrameworkObjectIds() { PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; PusServiceBase::packetDestination = objects::TM_FUNNEL; @@ -56,15 +60,6 @@ void ObjectFactory::produce(){ Factory::setStaticFrameworkObjectIds(); ObjectFactory::produceGenericObjects(); - /* Cookies */ - CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, - addresses::P60DOCK); - CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, - addresses::PDU1); - CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, - addresses::PDU2); - CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_LENGTH, - addresses::ACU); #if TE0720 == 1 I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1, TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0")); @@ -80,12 +75,31 @@ void ObjectFactory::produce(){ new CspComIF(objects::CSP_COM_IF); new I2cComIF(objects::I2C_COM_IF); +#if TE0720 == 0 + CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, + addresses::P60DOCK); + CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, + addresses::PDU1); + CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, + addresses::PDU2); + CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_LENGTH, + addresses::ACU); /* Device Handler */ - new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, p60DockCspCookie); - new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, pdu1CspCookie); - new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie); - new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie); + P60DockHandler* p60dockhandler = new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, p60DockCspCookie); + PDU1Handler* pdu1handler = new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, pdu1CspCookie); + PDU2Handler* pdu2handler = new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie); + ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie); new PCDUHandler(objects::PCDU_HANDLER, 50); + + /** + * Setting PCDU devices to mode normal immediately after start up because PCDU is always + * running. + */ + p60dockhandler->setModeNormal(); + pdu1handler->setModeNormal(); + pdu2handler->setModeNormal(); + acuhandler->setModeNormal(); +#endif /* Temperature sensors */ Tmp1075Handler* tmp1075Handler_1 = new Tmp1075Handler( objects::TMP1075_HANDLER_1, objects::I2C_COM_IF, @@ -99,10 +113,19 @@ void ObjectFactory::produce(){ /* Thermal objects */ GpioCookie* gpioCookie = new GpioCookie; #if TE0720 == 1 + +#if TEST_LIBGPIOD == 1 + /* Configure MIO0 as input */ + GpioConfig_t gpioConfigMio0(std::string("gpiochip0"), 0, + std::string("MIO0"), Gpio::IN, 0); + gpioCookie->addGpio(gpioIds::Test_ID, gpioConfigMio0); +#else // Configuration for MIO0 on TE0720-03-1CFA GpioConfig_t gpioConfigForDummyHeater(std::string("gpiochip0"), 0, std::string("Heater0"), Gpio::OUT, 0); gpioCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater); +#endif + #else /* Pin H2-11 on stack connector */ GpioConfig_t gpioConfigHeater0(std::string("gpiochip7"), 18, @@ -148,4 +171,8 @@ void ObjectFactory::produce(){ objects::CCSDS_PACKET_DISTRIBUTOR, objects::TM_STORE, objects::TC_STORE); new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); + +#if TE0720 == 1 && TEST_LIBGPIOD == 1 + new LibgpioTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); +#endif } diff --git a/bsp_q7s/comIF/CspComIF.cpp b/bsp_q7s/comIF/CspComIF.cpp index 52a92cc9..9d7543c3 100644 --- a/bsp_q7s/comIF/CspComIF.cpp +++ b/bsp_q7s/comIF/CspComIF.cpp @@ -187,7 +187,6 @@ ReturnValue_t CspComIF::cspTransfer(uint8_t cspAddress, uint8_t cspPort, reply = csp_read(conn, timeout_ms); if (reply == NULL) { sif::error << "CspComIF::cspTransfer: Failed to read csp packet" << std::endl; - csp_buffer_free(reply); csp_close(conn); return RETURN_FAILED; } diff --git a/bsp_q7s/gpio/CMakeLists.txt b/bsp_q7s/gpio/CMakeLists.txt index e35dd300..3b789394 100644 --- a/bsp_q7s/gpio/CMakeLists.txt +++ b/bsp_q7s/gpio/CMakeLists.txt @@ -3,4 +3,9 @@ target_sources(${TARGET_NAME} PUBLIC LinuxLibgpioIF.cpp ) +target_include_directories(${TARGET_NAME} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/cookies +) + diff --git a/bsp_q7s/gpio/LinuxLibgpioIF.cpp b/bsp_q7s/gpio/LinuxLibgpioIF.cpp index 415ce3d0..97159315 100644 --- a/bsp_q7s/gpio/LinuxLibgpioIF.cpp +++ b/bsp_q7s/gpio/LinuxLibgpioIF.cpp @@ -33,7 +33,7 @@ ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){ return result; } - result = configureGpios(mapToAdd); + result = configureGpios(&mapToAdd); if (result != RETURN_OK) { return RETURN_FAILED; } @@ -44,7 +44,7 @@ ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){ return RETURN_OK; } -ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap mapToAdd) { +ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap* mapToAdd) { GpioMapIter mapToAddIter; std::string chipname; unsigned int lineNum; @@ -54,17 +54,18 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap mapToAdd) { struct gpiod_line *lineHandle; int result; - for (mapToAddIter = mapToAdd.begin(); mapToAddIter != mapToAdd.end(); mapToAddIter++) { + mapToAddIter = mapToAdd->begin(); + for (; mapToAddIter != mapToAdd->end(); mapToAddIter++) { - chipname = gpioMapIter->second.chipname; + chipname = mapToAddIter->second.chipname; chip = gpiod_chip_open_by_name(chipname.c_str()); if (!chip) { sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip " - << chipname << ". Gpio ID: " << gpioMapIter->first << std::endl; + << chipname << ". Gpio ID: " << mapToAddIter->first << std::endl; return RETURN_FAILED; } - lineNum = gpioMapIter->second.lineNum; + lineNum = mapToAddIter->second.lineNum; lineHandle = gpiod_chip_get_line(chip, lineNum); if (!lineHandle) { sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line" << std::endl; @@ -72,16 +73,16 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap mapToAdd) { return RETURN_FAILED; } - direction = gpioMapIter->second.direction; - consumer = gpioMapIter->second.consumer; + direction = mapToAddIter->second.direction; + consumer = mapToAddIter->second.consumer; /* Configure direction and add a description to the GPIO */ switch (direction) { case Gpio::OUT: result = gpiod_line_request_output(lineHandle, consumer.c_str(), - gpioMapIter->second.initValue); + mapToAddIter->second.initValue); if (result < 0) { sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " - << lineNum << " from GPIO instance with ID: " << gpioMapIter->first + << lineNum << " from GPIO instance with ID: " << mapToAddIter->first << std::endl; gpiod_line_release(lineHandle); return RETURN_FAILED; @@ -91,7 +92,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap mapToAdd) { result = gpiod_line_request_input(lineHandle, consumer.c_str()); if (result < 0) { sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " - << lineNum << " from GPIO instance with ID: " << gpioMapIter->first + << lineNum << " from GPIO instance with ID: " << mapToAddIter->first << std::endl; gpiod_line_release(lineHandle); return RETURN_FAILED; @@ -106,7 +107,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap mapToAdd) { * Write line handle to GPIO configuration instance so it can later be used to set or * read states of GPIOs. */ - gpioMapIter->second.lineHandle = lineHandle; + mapToAddIter->second.lineHandle = lineHandle; } return RETURN_OK; } @@ -124,7 +125,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, int result; struct gpiod_line *lineHandle; - GpioMapIter gpioMapIter = gpioMap.find(gpioId); + gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()){ sif::debug << "LinuxLibgpioIF::driveGpio: Unknown gpio id " << gpioId << std::endl; return RETURN_FAILED; @@ -134,7 +135,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, result = gpiod_line_set_value(lineHandle, logiclevel); if (result < 0) { sif::error << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " - << gpioId << "to logic level" << logiclevel << std::endl; + << gpioId << " to logic level " << logiclevel << std::endl; return DRIVE_GPIO_FAILURE; } @@ -144,7 +145,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { struct gpiod_line *lineHandle; - GpioMapIter gpioMapIter = gpioMap.find(gpioId); + gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()){ sif::debug << "LinuxLibgpioIF::readGpio: Unknown gpio id " << gpioId << std::endl; return RETURN_FAILED; diff --git a/bsp_q7s/gpio/LinuxLibgpioIF.h b/bsp_q7s/gpio/LinuxLibgpioIF.h index ef2bf8b5..f8cc1a09 100644 --- a/bsp_q7s/gpio/LinuxLibgpioIF.h +++ b/bsp_q7s/gpio/LinuxLibgpioIF.h @@ -57,7 +57,7 @@ private: /** * @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd. */ - ReturnValue_t configureGpios(GpioMap mapToAdd); + ReturnValue_t configureGpios(GpioMap* mapToAdd); }; #endif /* BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_ */ diff --git a/bsp_q7s/gpio/cookies/GpioCookie.h b/bsp_q7s/gpio/cookies/GpioCookie.h index 517434c1..acc360e0 100644 --- a/bsp_q7s/gpio/cookies/GpioCookie.h +++ b/bsp_q7s/gpio/cookies/GpioCookie.h @@ -39,7 +39,7 @@ typedef struct GpioConfig { std::string consumer; Gpio::Direction direction; int initValue; - struct gpiod_line *lineHandle; + struct gpiod_line* lineHandle; } GpioConfig_t; using GpioMap = std::unordered_map; using GpioMapIter = GpioMap::iterator; diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index 2bbd1ca8..f5456b4d 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -6,7 +6,8 @@ #ifndef FSFWCONFIG_OBSWCONFIG_H_ #define FSFWCONFIG_OBSWCONFIG_H_ -#define OBSW_ADD_TEST_CODE 0 +#define TEST_LIBGPIOD 0 +#define ADD_TEST_TAST 1 // These defines should be disabled for mission code but are useful for // debugging. diff --git a/fsfwconfig/devices/gpioIds.h b/fsfwconfig/devices/gpioIds.h index 90ab29cb..332de906 100644 --- a/fsfwconfig/devices/gpioIds.h +++ b/fsfwconfig/devices/gpioIds.h @@ -13,6 +13,7 @@ namespace gpioIds { HEATER_5, HEATER_6, HEATER_7, + Test_ID }; } diff --git a/fsfwconfig/objects/systemObjectList.h b/fsfwconfig/objects/systemObjectList.h index 8bb027f8..d5a2e737 100644 --- a/fsfwconfig/objects/systemObjectList.h +++ b/fsfwconfig/objects/systemObjectList.h @@ -50,6 +50,7 @@ namespace objects { /* 0x54 ('T') for test handlers */ TEST_TASK = 0x54694269, + LIBGPIOD_TEST = 0x54123456, SPI_TEST = 0x54000010, DUMMY_INTERFACE = 0x5400CAFE, DUMMY_HANDLER = 0x5400AFFE, diff --git a/mission/devices/GomspaceDeviceHandler.cpp b/mission/devices/GomspaceDeviceHandler.cpp index f02548c2..44ede8b7 100644 --- a/mission/devices/GomspaceDeviceHandler.cpp +++ b/mission/devices/GomspaceDeviceHandler.cpp @@ -6,7 +6,6 @@ GomspaceDeviceHandler::GomspaceDeviceHandler(object_id_t objectId, object_id_t c uint16_t hkTableReplySize, LocalPoolDataSetBase* hkTableDataset) : DeviceHandlerBase(objectId, comIF, comCookie), maxConfigTableAddress(maxConfigTableAddress), maxHkTableAddress(maxHkTableAddress), hkTableReplySize(hkTableReplySize), hkTableDataset(hkTableDataset) { - mode = MODE_NORMAL; if (comCookie == NULL) { sif::error << "GomspaceDeviceHandler::GomspaceDeviceHandler: Invalid com cookie" << std::endl; @@ -392,3 +391,7 @@ LocalPoolDataSetBase* GomspaceDeviceHandler::getDataSetHandle(sid_t sid) { return nullptr; } } + +void GomspaceDeviceHandler::setModeNormal() { + mode = MODE_NORMAL; +} diff --git a/mission/devices/GomspaceDeviceHandler.h b/mission/devices/GomspaceDeviceHandler.h index 76ef8226..81c62502 100644 --- a/mission/devices/GomspaceDeviceHandler.h +++ b/mission/devices/GomspaceDeviceHandler.h @@ -36,6 +36,12 @@ public: uint16_t hkTableReplySize, LocalPoolDataSetBase* hkTableDataset); virtual ~GomspaceDeviceHandler(); + /** + * @brief This function can be used to set a gomspace device to normal mode immediately after + * object creation. + */ + void setModeNormal(); + protected: static const uint8_t MAX_PACKET_LEN = 36; diff --git a/mission/devices/HeaterHandler.cpp b/mission/devices/HeaterHandler.cpp index 0545a9e1..a810e2a6 100644 --- a/mission/devices/HeaterHandler.cpp +++ b/mission/devices/HeaterHandler.cpp @@ -214,21 +214,13 @@ void HeaterHandler::handleSwitchOnCommand(HeaterMapIter heaterMapIter) { gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr); result = gpioInterface->pullHigh(gpioId); if (result != RETURN_OK) { - sif::error << "HeaterHandler::handleSwitchOnCommand: Failed to pull gpio with id" - << gpioId << "high" << std::endl; + sif::error << "HeaterHandler::handleSwitchOnCommand: Failed to pull gpio with id " + << gpioId << " high" << std::endl; triggerEvent(GPIO_PULL_HIGH_FAILED, result); } else { switchStates[switchNr] = ON; } - int gpioState; - result = gpioInterface->readGpio(gpioId, &gpioState); - if (result != RETURN_OK) { - sif::debug << "HeaterHandler::handleSwitchOnCommand: Failed to read gpio" - << std::endl; - } - sif::debug << "HeaterHandler::handleSwitchOnCommand: GPIO state: " << gpioState - << std::endl; } else { triggerEvent(SWITCH_ALREADY_ON, switchNr); @@ -283,14 +275,6 @@ void HeaterHandler::handleSwitchOffCommand(HeaterMapIter heaterMapIter) { mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF); } } - int gpioState; - result = gpioInterface->readGpio(gpioId, &gpioState); - if (result != RETURN_OK) { - sif::debug << "HeaterHandler::handleSwitchOnCommand: Failed to read gpio" - << std::endl; - } - sif::debug << "HeaterHandler::handleSwitchOnCommand: GPIO state: " << gpioState - << std::endl; } else { sif::info << "HeaterHandler::handleSwitchOffCommand: Switch already off" << std::endl; diff --git a/test/test.mk b/test/test.mk deleted file mode 100644 index 701ec2d1..00000000 --- a/test/test.mk +++ /dev/null @@ -1,3 +0,0 @@ -CXXSRC += $(wildcard $(CURRENTPATH)/testdevices/*.cpp) -CXXSRC += $(wildcard $(CURRENTPATH)/testinterfaces/*.cpp) -CXXSRC += $(wildcard $(CURRENTPATH)/testtasks/*.cpp) \ No newline at end of file diff --git a/test/testtasks/CMakeLists.txt b/test/testtasks/CMakeLists.txt new file mode 100644 index 00000000..c1f6beb7 --- /dev/null +++ b/test/testtasks/CMakeLists.txt @@ -0,0 +1,8 @@ +target_sources(${TARGET_NAME} PUBLIC + LibgpioTest.cpp + TestTask.cpp +) + +target_include_directories(${TARGET_NAME} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR} +) \ No newline at end of file diff --git a/test/testtasks/LibgpioTest.cpp b/test/testtasks/LibgpioTest.cpp new file mode 100644 index 00000000..01628f0e --- /dev/null +++ b/test/testtasks/LibgpioTest.cpp @@ -0,0 +1,35 @@ +#include "LibgpioTest.h" +#include "devices/gpioIds.h" +#include +#include + +LibgpioTest::LibgpioTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie) : + TestTask(objectId) { + + gpioInterface = objectManager->get(gpioIfobjectId); + if (gpioInterface == nullptr) { + sif::error << "LibgpioTest::LibgpioTest: Invalid Gpio interface." << std::endl; + } + gpioInterface->initialize(gpioCookie); +} + +LibgpioTest::~LibgpioTest() { +} + +ReturnValue_t LibgpioTest::performPeriodicAction() { + int gpioState; + ReturnValue_t result; + + result = gpioInterface->readGpio(gpioIds::Test_ID, &gpioState); + if (result != RETURN_OK) { + sif::debug << "LibgpioTest::performPeriodicAction: Failed to read gpio " + << std::endl; + return RETURN_FAILED; + } + else { + sif::debug << "LibgpioTest::performPeriodicAction: MIO 0 state = " << gpioState + << std::endl; + } + return RETURN_OK; +} + diff --git a/test/testtasks/LibgpioTest.h b/test/testtasks/LibgpioTest.h new file mode 100644 index 00000000..2d670149 --- /dev/null +++ b/test/testtasks/LibgpioTest.h @@ -0,0 +1,25 @@ +#ifndef TEST_TESTTASKS_LIBGPIOTEST_H_ +#define TEST_TESTTASKS_LIBGPIOTEST_H_ + +#include "TestTask.h" +#include "GpioIF.h" +#include "GpioCookie.h" +#include + +/** + * @brief Test for the GPIO read implementation of the LinuxLibgpioIF. + * @author J. Meier + */ +class LibgpioTest: public TestTask { +public: + LibgpioTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie); + virtual ~LibgpioTest(); + +protected: + virtual ReturnValue_t performPeriodicAction() override; + +private: + GpioIF* gpioInterface; +}; + +#endif /* TEST_TESTTASKS_LIBGPIOTEST_H_ */