From 9a995a9b5c387bc432b51296957547b22ce14f64 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 17:44:16 +0100 Subject: [PATCH 01/34] reference returned now --- linux/gpio/GpioCookie.cpp | 2 +- linux/gpio/GpioCookie.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/gpio/GpioCookie.cpp b/linux/gpio/GpioCookie.cpp index f4e585d1..6355578c 100644 --- a/linux/gpio/GpioCookie.cpp +++ b/linux/gpio/GpioCookie.cpp @@ -19,7 +19,7 @@ void GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig){ } } -GpioMap GpioCookie::getGpioMap() const{ +GpioMap& GpioCookie::getGpioMap() const { return gpioMap; } diff --git a/linux/gpio/GpioCookie.h b/linux/gpio/GpioCookie.h index 72011750..8ec30d79 100644 --- a/linux/gpio/GpioCookie.h +++ b/linux/gpio/GpioCookie.h @@ -65,7 +65,7 @@ public: /** * @brief Get map with registered GPIOs. */ - GpioMap getGpioMap() const; + GpioMap& getGpioMap() const; private: -- 2.43.0 From fc0337af040161e676c42bad58e9320d13a0c3b4 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:21:59 +0100 Subject: [PATCH 02/34] some minor improvements --- linux/gpio/GpioCookie.cpp | 20 ++++++------- linux/gpio/GpioCookie.h | 31 ++++++++++---------- linux/gpio/GpioIF.h | 4 +-- linux/gpio/LinuxLibgpioIF.cpp | 55 ++++++++++++++++++----------------- linux/gpio/LinuxLibgpioIF.h | 10 +++---- 5 files changed, 59 insertions(+), 61 deletions(-) diff --git a/linux/gpio/GpioCookie.cpp b/linux/gpio/GpioCookie.cpp index 6355578c..7f80b550 100644 --- a/linux/gpio/GpioCookie.cpp +++ b/linux/gpio/GpioCookie.cpp @@ -1,25 +1,23 @@ #include "GpioCookie.h" -#include +#include GpioCookie::GpioCookie() { } void GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig){ - gpioMapIter = gpioMap.find(gpioId); + auto gpioMapIter = gpioMap.find(gpioId); if(gpioMapIter == gpioMap.end()) { - std::pair status = gpioMap.emplace(gpioId, gpioConfig); - if (status.second == false) { - sif::error << "GpioCookie::addGpio: Failed to add GPIO " - << gpioId << "to GPIO map" << std::endl; + auto statusPair = gpioMap.emplace(gpioId, gpioConfig); + if (statusPair.second == false) { + sif::error << "GpioCookie::addGpio: Failed to add GPIO " << gpioId << + "to GPIO map" << std::endl; } + return; } - else { - sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map " - << std::endl; - } + sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map " << std::endl; } -GpioMap& GpioCookie::getGpioMap() const { +GpioMap GpioCookie::getGpioMap() const { return gpioMap; } diff --git a/linux/gpio/GpioCookie.h b/linux/gpio/GpioCookie.h index 8ec30d79..5e4a7b1d 100644 --- a/linux/gpio/GpioCookie.h +++ b/linux/gpio/GpioCookie.h @@ -17,23 +17,22 @@ enum Direction { /** * @brief Struct containing information about the GPIO to use. This is * required by the libgpiod to access and drive a GPIO. - * @param chipname String of the chipname specifying the group which contains - * the GPIO to access. E.g. gpiochip0. To detect names of - * GPIO groups run gpiodetect on the linux command line. - * @param lineNum The offset of the GPIO within the GPIO group. - * @param consumer Name of the consumer. Simply a description of the GPIO configuration. - * @param direction Specifies whether the GPIO should be used as in- or output. - * @param initValue Defines the initial state of the GPIO when configured as output. Only required - * for output GPIOs. + * @param chipname String of the chipname specifying the group which contains the GPIO to + * access. E.g. gpiochip0. To detect names of GPIO groups run gpiodetect on + * the linux command line. + * @param lineNum The offset of the GPIO within the GPIO group. + * @param consumer Name of the consumer. Simply a description of the GPIO configuration. + * @param direction Specifies whether the GPIO should be used as in- or output. + * @param initValue Defines the initial state of the GPIO when configured as output. + * Only required for output GPIOs. * @param lineHandle The handle returned by gpiod_chip_get_line will be later written to this * pointer. */ typedef struct GpioConfig { GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, - gpio::Direction direction_, int initValue_) : - chipname(chipname_), lineNum(lineNum_), consumer(consumer_), direction(direction_), - initValue(initValue_) { - } + gpio::Direction direction_, int initValue_): + chipname(chipname_), lineNum(lineNum_), consumer(consumer_), + direction(direction_), initValue(initValue_) {} std::string chipname; int lineNum; std::string consumer; @@ -41,6 +40,7 @@ typedef struct GpioConfig { int initValue; struct gpiod_line* lineHandle = nullptr; } GpioConfig_t; + using GpioMap = std::unordered_map; using GpioMapIter = GpioMap::iterator; @@ -65,12 +65,13 @@ public: /** * @brief Get map with registered GPIOs. */ - GpioMap& getGpioMap() const; + GpioMap getGpioMap() const; private: - + /** + * Returns a copy of the internal GPIO map. + */ GpioMap gpioMap; - GpioMapIter gpioMapIter; }; #endif diff --git a/linux/gpio/GpioIF.h b/linux/gpio/GpioIF.h index d1f02dd8..8d36a1b7 100644 --- a/linux/gpio/GpioIF.h +++ b/linux/gpio/GpioIF.h @@ -11,7 +11,7 @@ typedef uint16_t gpioId_t; * over GPIOs. * @author J. Meier */ -class GpioIF : public HasReturnvaluesIF{ +class GpioIF : public HasReturnvaluesIF { public: virtual ~GpioIF() {}; @@ -21,7 +21,7 @@ public: * @param cookie Cookie specifying informations of the GPIOs required * by a object. */ - virtual ReturnValue_t initialize(CookieIF * cookie) = 0; + virtual ReturnValue_t initialize(CookieIF* cookie) = 0; /** * @brief By implementing this function a child must provide the diff --git a/linux/gpio/LinuxLibgpioIF.cpp b/linux/gpio/LinuxLibgpioIF.cpp index e5db2934..da235716 100644 --- a/linux/gpio/LinuxLibgpioIF.cpp +++ b/linux/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,8 +44,8 @@ ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){ return RETURN_OK; } -ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap* mapToAdd) { - GpioMapIter mapToAddIter; +ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { + //GpioMapIter mapToAddIter; std::string chipname; unsigned int lineNum; struct gpiod_chip *chip; @@ -54,18 +54,18 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap* mapToAdd) { struct gpiod_line *lineHandle; int result; - mapToAddIter = mapToAdd->begin(); - for (; mapToAddIter != mapToAdd->end(); mapToAddIter++) { - - chipname = mapToAddIter->second.chipname; + //mapToAddIter = mapToAdd->begin(); + for(auto& gpioConfig: mapToAdd) { + //for (; mapToAddIter != mapToAdd->end(); mapToAddIter++) { + chipname = gpioConfig.second.chipname; chip = gpiod_chip_open_by_name(chipname.c_str()); if (!chip) { sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip " - << chipname << ". Gpio ID: " << mapToAddIter->first << std::endl; + << chipname << ". Gpio ID: " << gpioConfig.first << std::endl; return RETURN_FAILED; } - lineNum = mapToAddIter->second.lineNum; + lineNum = gpioConfig.second.lineNum; lineHandle = gpiod_chip_get_line(chip, lineNum); if (!lineHandle) { sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line" << std::endl; @@ -73,16 +73,16 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap* mapToAdd) { return RETURN_FAILED; } - direction = mapToAddIter->second.direction; - consumer = mapToAddIter->second.consumer; + direction = gpioConfig.second.direction; + consumer = gpioConfig.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(), - mapToAddIter->second.initValue); + gpioConfig.second.initValue); if (result < 0) { sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " - << lineNum << " from GPIO instance with ID: " << mapToAddIter->first + << lineNum << " from GPIO instance with ID: " << gpioConfig.first << std::endl; gpiod_line_release(lineHandle); return RETURN_FAILED; @@ -92,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: " << mapToAddIter->first + << lineNum << " from GPIO instance with ID: " << gpioConfig.first << std::endl; gpiod_line_release(lineHandle); return RETURN_FAILED; @@ -107,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. */ - mapToAddIter->second.lineHandle = lineHandle; + gpioConfig.second.lineHandle = lineHandle; } return RETURN_OK; } @@ -125,7 +125,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, int result; struct gpiod_line *lineHandle; - gpioMapIter = gpioMap.find(gpioId); + auto gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()){ sif::debug << "LinuxLibgpioIF::driveGpio: Unknown gpio id " << gpioId << std::endl; return RETURN_FAILED; @@ -145,7 +145,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { struct gpiod_line *lineHandle; - gpioMapIter = gpioMap.find(gpioId); + auto gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()){ sif::debug << "LinuxLibgpioIF::readGpio: Unknown gpio id " << gpioId << std::endl; return RETURN_FAILED; @@ -157,23 +157,24 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { return RETURN_OK; } -ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap mapToAdd){ +ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ gpioId_t gpioId; - GpioMapIter mapToAddIter = mapToAdd.begin(); - for(; mapToAddIter != mapToAdd.end(); mapToAddIter++){ - gpioId = mapToAddIter->first; + auto gpioMapIter = gpioMap.begin(); + for(auto& gpioConfig: mapToAdd) { + gpioId = gpioConfig.first; + /* Cross check with private map */ gpioMapIter = gpioMap.find(gpioId); - if(gpioMapIter != mapToAdd.end()){ + if(gpioMapIter != mapToAdd.end()) { /* An entry for this GPIO already exists. Check if configuration * of direction is equivalent */ - if (mapToAddIter->second.direction != gpioMapIter->second.direction){ - sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict " - << "for GPIO " << mapToAddIter->first << std::endl; - return RETURN_OK; + if (gpioConfig.second.direction != gpioMapIter->second.direction){ + sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict for GPIO " << + gpioConfig.first << std::endl; + return RETURN_FAILED; } /* Remove element from map to add because a entry for this GPIO * already exists */ - mapToAdd.erase(mapToAddIter); + mapToAdd.erase(gpioConfig.first); } } return RETURN_OK; diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index f91a35ca..6f210458 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -23,16 +23,14 @@ public: LinuxLibgpioIF(object_id_t objectId); virtual ~LinuxLibgpioIF(); - ReturnValue_t initialize(CookieIF * cookie) override; + ReturnValue_t initialize(CookieIF* gpioCookie) override; ReturnValue_t pullHigh(gpioId_t gpioId) override; ReturnValue_t pullLow(gpioId_t gpioId) override; ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override; private: - - /*Holds the information and configuration of all used GPIOs */ + /* Holds the information and configuration of all used GPIOs */ GpioMap gpioMap; - GpioMapIter gpioMapIter; /** * @brief This functions drives line of a GPIO specified by the GPIO ID. @@ -52,12 +50,12 @@ private: * * @return RETURN_OK if successful, otherwise RETURN_FAILED */ - ReturnValue_t checkForConflicts(GpioMap mapToAdd); + ReturnValue_t checkForConflicts(GpioMap& mapToAdd); /** * @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_ */ -- 2.43.0 From 6d2d7ad620cb7bd669abb1524b52ecf3e142196d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:30:12 +0100 Subject: [PATCH 03/34] moved heater handler --- bsp_q7s/CMakeLists.txt | 1 + bsp_q7s/ObjectFactory.cpp | 18 +++++++++--------- bsp_q7s/devices/CMakeLists.txt | 7 +++++++ {mission => bsp_q7s}/devices/HeaterHandler.cpp | 13 +++++++------ {mission => bsp_q7s}/devices/HeaterHandler.h | 2 +- mission/devices/CMakeLists.txt | 1 - 6 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 bsp_q7s/devices/CMakeLists.txt rename {mission => bsp_q7s}/devices/HeaterHandler.cpp (97%) rename {mission => bsp_q7s}/devices/HeaterHandler.h (99%) diff --git a/bsp_q7s/CMakeLists.txt b/bsp_q7s/CMakeLists.txt index 3d3a1c91..7b985558 100644 --- a/bsp_q7s/CMakeLists.txt +++ b/bsp_q7s/CMakeLists.txt @@ -6,6 +6,7 @@ target_sources(${TARGET_NAME} PUBLIC add_subdirectory(boardconfig) add_subdirectory(comIF) +add_subdirectory(devices) add_subdirectory(boardtest) diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index a4503981..aed9e23e 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -4,15 +4,9 @@ #include #include #include +#include -#include -#include -#include -#include -#include -#include - -#include +#include #include #include @@ -21,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -33,6 +26,13 @@ #include #include +#include +#include +#include +#include +#include +#include + #if TEST_LIBGPIOD == 1 #include "LibgpiodTest.h" #endif diff --git a/bsp_q7s/devices/CMakeLists.txt b/bsp_q7s/devices/CMakeLists.txt new file mode 100644 index 00000000..14eae324 --- /dev/null +++ b/bsp_q7s/devices/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${TARGET_NAME} PRIVATE + HeaterHandler.cpp +) + + + + diff --git a/mission/devices/HeaterHandler.cpp b/bsp_q7s/devices/HeaterHandler.cpp similarity index 97% rename from mission/devices/HeaterHandler.cpp rename to bsp_q7s/devices/HeaterHandler.cpp index a810e2a6..759c6d64 100644 --- a/mission/devices/HeaterHandler.cpp +++ b/bsp_q7s/devices/HeaterHandler.cpp @@ -1,15 +1,16 @@ -#include +#include "HeaterHandler.h" + #include #include #include HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, uint8_t mainLineSwitch_) : - SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), mainLineSwitcherObjectId( - mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), actionHelper(this, - nullptr) { - commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, - MessageQueueMessage::MAX_MESSAGE_SIZE); + SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), + mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), + actionHelper(this, nullptr) { + commandQueue = QueueFactory::instance()->createMessageQueue( + cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); } HeaterHandler::~HeaterHandler() { diff --git a/mission/devices/HeaterHandler.h b/bsp_q7s/devices/HeaterHandler.h similarity index 99% rename from mission/devices/HeaterHandler.h rename to bsp_q7s/devices/HeaterHandler.h index 4c37c30f..5406df8d 100644 --- a/mission/devices/HeaterHandler.h +++ b/bsp_q7s/devices/HeaterHandler.h @@ -117,7 +117,7 @@ private: CookieIF * gpioCookie; - GpioIF* gpioInterface; + GpioIF* gpioInterface = nullptr; /** Queue to receive messages from other objects. */ MessageQueueIF* commandQueue = nullptr; diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 9a2920d5..a8205276 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -10,7 +10,6 @@ target_sources(${TARGET_NAME} PUBLIC PDU1Handler.cpp PDU2Handler.cpp ACUHandler.cpp - HeaterHandler.cpp ) -- 2.43.0 From 101a7696c3abe54856e8c6fa17283681608e2824 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:39:50 +0100 Subject: [PATCH 04/34] corrected include guards, changed GpioIF prototype --- bsp_q7s/devices/HeaterHandler.cpp | 3 +- linux/csp/CspComIF.h | 6 ++-- linux/csp/CspCookie.h | 6 ++-- linux/gpio/GpioCookie.h | 46 +++---------------------------- linux/gpio/GpioIF.h | 13 +++++---- linux/gpio/LinuxLibgpioIF.cpp | 16 ++++------- linux/gpio/LinuxLibgpioIF.h | 10 +++---- linux/gpio/gpioDefinitions.h | 46 +++++++++++++++++++++++++++++++ linux/i2c/I2cComIF.h | 6 ++-- linux/i2c/I2cCookie.h | 6 ++-- 10 files changed, 81 insertions(+), 77 deletions(-) create mode 100644 linux/gpio/gpioDefinitions.h diff --git a/bsp_q7s/devices/HeaterHandler.cpp b/bsp_q7s/devices/HeaterHandler.cpp index 759c6d64..eeda9a89 100644 --- a/bsp_q7s/devices/HeaterHandler.cpp +++ b/bsp_q7s/devices/HeaterHandler.cpp @@ -3,6 +3,7 @@ #include #include #include +#include HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, uint8_t mainLineSwitch_) : @@ -43,7 +44,7 @@ ReturnValue_t HeaterHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - result = gpioInterface->initialize(gpioCookie); + result = gpioInterface->initialize(dynamic_cast(gpioCookie)); if (result != RETURN_OK) { sif::error << "HeaterHandler::initialize: Failed to initialize Gpio interface" << std::endl; return ObjectManagerIF::CHILD_INIT_FAILED; diff --git a/linux/csp/CspComIF.h b/linux/csp/CspComIF.h index 78f5158f..5120f232 100644 --- a/linux/csp/CspComIF.h +++ b/linux/csp/CspComIF.h @@ -1,5 +1,5 @@ -#ifndef BSP_LINUX_COMIF_COOKIES_CSPCOMIF_H_ -#define BSP_LINUX_COMIF_COOKIES_CSPCOMIF_H_ +#ifndef LINUX_CSP_CSPCOMIF_H_ +#define LINUX_CSP_CSPCOMIF_H_ #include #include @@ -86,4 +86,4 @@ private: void initiatePingRequest(uint8_t cspAddress, uint16_t querySize); }; -#endif /* BSP_LINUX_COMIF_COOKIES_CSPCOMIF_H_ */ +#endif /* LINUX_CSP_CSPCOMIF_H_ */ diff --git a/linux/csp/CspCookie.h b/linux/csp/CspCookie.h index e877761d..4514c257 100644 --- a/linux/csp/CspCookie.h +++ b/linux/csp/CspCookie.h @@ -1,5 +1,5 @@ -#ifndef BSP_Q7S_COMIF_COOKIES_CSPCOOKIE_H_ -#define BSP_Q7S_COMIF_COOKIES_CSPCOOKIE_H_ +#ifndef LINUX_CSP_CSPCOOKIE_H_ +#define LINUX_CSP_CSPCOOKIE_H_ #include #include @@ -24,4 +24,4 @@ private: uint8_t cspAddress; }; -#endif /* BSP_Q7S_COMIF_COOKIES_CSPCOOKIE_H_ */ +#endif /* LINUX_CSP_CSPCOOKIE_H_ */ diff --git a/linux/gpio/GpioCookie.h b/linux/gpio/GpioCookie.h index 5e4a7b1d..05e80a2e 100644 --- a/linux/gpio/GpioCookie.h +++ b/linux/gpio/GpioCookie.h @@ -1,48 +1,10 @@ -#ifndef SAM9G20_COMIF_COOKIES_GPIO_COOKIE_H_ -#define SAM9G20_COMIF_COOKIES_GPIO_COOKIE_H_ +#ifndef LINUX_GPIO_GPIOCOOKIE_H_ +#define LINUX_GPIO_GPIOCOOKIE_H_ #include "GpioIF.h" +#include "gpioDefinitions.h" #include #include -#include -#include - -namespace gpio { -enum Direction { - IN = 0, - OUT = 1 -}; -} - -/** - * @brief Struct containing information about the GPIO to use. This is - * required by the libgpiod to access and drive a GPIO. - * @param chipname String of the chipname specifying the group which contains the GPIO to - * access. E.g. gpiochip0. To detect names of GPIO groups run gpiodetect on - * the linux command line. - * @param lineNum The offset of the GPIO within the GPIO group. - * @param consumer Name of the consumer. Simply a description of the GPIO configuration. - * @param direction Specifies whether the GPIO should be used as in- or output. - * @param initValue Defines the initial state of the GPIO when configured as output. - * Only required for output GPIOs. - * @param lineHandle The handle returned by gpiod_chip_get_line will be later written to this - * pointer. - */ -typedef struct GpioConfig { - GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, - gpio::Direction direction_, int initValue_): - chipname(chipname_), lineNum(lineNum_), consumer(consumer_), - direction(direction_), initValue(initValue_) {} - std::string chipname; - int lineNum; - std::string consumer; - gpio::Direction direction; - int initValue; - struct gpiod_line* lineHandle = nullptr; -} GpioConfig_t; - -using GpioMap = std::unordered_map; -using GpioMapIter = GpioMap::iterator; /** * @brief Cookie for the GpioIF. Allows the GpioIF to determine which @@ -74,4 +36,4 @@ private: GpioMap gpioMap; }; -#endif +#endif /* LINUX_GPIO_GPIOCOOKIE_H_ */ diff --git a/linux/gpio/GpioIF.h b/linux/gpio/GpioIF.h index 8d36a1b7..65b82573 100644 --- a/linux/gpio/GpioIF.h +++ b/linux/gpio/GpioIF.h @@ -1,10 +1,11 @@ -#ifndef BSP_Q7S_GPIO_GPIOIF_H_ -#define BSP_Q7S_GPIO_GPIOIF_H_ +#ifndef LINUX_GPIO_GPIOIF_H_ +#define LINUX_GPIO_GPIOIF_H_ +#include "gpioDefinitions.h" #include #include -typedef uint16_t gpioId_t; +class GpioCookie; /** * @brief This class defines the interface for objects requiring the control @@ -17,11 +18,11 @@ public: virtual ~GpioIF() {}; /** - * @brief Called by the GPIO using object. + * @brief Called by the GPIO using object. * @param cookie Cookie specifying informations of the GPIOs required * by a object. */ - virtual ReturnValue_t initialize(CookieIF* cookie) = 0; + virtual ReturnValue_t initialize(GpioCookie* cookie) = 0; /** * @brief By implementing this function a child must provide the @@ -49,4 +50,4 @@ public: virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0; }; -#endif /* BSP_Q7S_GPIO_GPIOIF_H_ */ +#endif /* LINUX_GPIO_GPIOIF_H_ */ diff --git a/linux/gpio/LinuxLibgpioIF.cpp b/linux/gpio/LinuxLibgpioIF.cpp index da235716..daaff8ba 100644 --- a/linux/gpio/LinuxLibgpioIF.cpp +++ b/linux/gpio/LinuxLibgpioIF.cpp @@ -1,4 +1,6 @@ #include "LinuxLibgpioIF.h" +#include "GpioCookie.h" + #include #include @@ -11,22 +13,14 @@ LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) { LinuxLibgpioIF::~LinuxLibgpioIF() { } -ReturnValue_t LinuxLibgpioIF::initialize(CookieIF * cookie){ +ReturnValue_t LinuxLibgpioIF::initialize(GpioCookie* gpioCookie){ ReturnValue_t result; - GpioMap mapToAdd; - - if(cookie == nullptr) { + if(gpioCookie == nullptr) { sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl; return RETURN_FAILED; } - GpioCookie* gpioCookie = dynamic_cast(cookie); - if(gpioCookie == nullptr) { - sif::error << "LinuxLibgpioIF: Invalid Gpio Cookie!" - << std::endl; - return RETURN_FAILED; - } - mapToAdd = gpioCookie->getGpioMap(); + GpioMap mapToAdd = gpioCookie->getGpioMap(); result = checkForConflicts(mapToAdd); if (result != RETURN_OK){ diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index 6f210458..4e9130b9 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -1,11 +1,11 @@ -#ifndef BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_ -#define BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_ +#ifndef LINUX_GPIO_LINUXLIBGPIOIF_H_ +#define LINUX_GPIO_LINUXLIBGPIOIF_H_ #include -#include #include #include +class GpioCookie; /** * @brief This class implements the GpioIF for a linux based system. The * implementation is based on the libgpiod lib which requires linux 4.8 @@ -23,7 +23,7 @@ public: LinuxLibgpioIF(object_id_t objectId); virtual ~LinuxLibgpioIF(); - ReturnValue_t initialize(CookieIF* gpioCookie) override; + ReturnValue_t initialize(GpioCookie* gpioCookie) override; ReturnValue_t pullHigh(gpioId_t gpioId) override; ReturnValue_t pullLow(gpioId_t gpioId) override; ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override; @@ -58,4 +58,4 @@ private: ReturnValue_t configureGpios(GpioMap& mapToAdd); }; -#endif /* BSP_Q7S_GPIO_LINUXLIBGPIOIF_H_ */ +#endif /* LINUX_GPIO_LINUXLIBGPIOIF_H_ */ diff --git a/linux/gpio/gpioDefinitions.h b/linux/gpio/gpioDefinitions.h new file mode 100644 index 00000000..bbc599ee --- /dev/null +++ b/linux/gpio/gpioDefinitions.h @@ -0,0 +1,46 @@ +#ifndef LINUX_GPIO_GPIODEFINITIONS_H_ +#define LINUX_GPIO_GPIODEFINITIONS_H_ + +#include +#include + +using gpioId_t = uint16_t; + +namespace gpio { +enum Direction { + IN = 0, + OUT = 1 +}; +} + +/** + * @brief Struct containing information about the GPIO to use. This is + * required by the libgpiod to access and drive a GPIO. + * @param chipname String of the chipname specifying the group which contains the GPIO to + * access. E.g. gpiochip0. To detect names of GPIO groups run gpiodetect on + * the linux command line. + * @param lineNum The offset of the GPIO within the GPIO group. + * @param consumer Name of the consumer. Simply a description of the GPIO configuration. + * @param direction Specifies whether the GPIO should be used as in- or output. + * @param initValue Defines the initial state of the GPIO when configured as output. + * Only required for output GPIOs. + * @param lineHandle The handle returned by gpiod_chip_get_line will be later written to this + * pointer. + */ +typedef struct GpioConfig { + GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, + gpio::Direction direction_, int initValue_): + chipname(chipname_), lineNum(lineNum_), consumer(consumer_), + direction(direction_), initValue(initValue_) {} + std::string chipname; + int lineNum; + std::string consumer; + gpio::Direction direction; + int initValue; + struct gpiod_line* lineHandle = nullptr; +} GpioConfig_t; + +using GpioMap = std::unordered_map; +using GpioMapIter = GpioMap::iterator; + +#endif /* LINUX_GPIO_GPIODEFINITIONS_H_ */ diff --git a/linux/i2c/I2cComIF.h b/linux/i2c/I2cComIF.h index 5e75a280..f5d07ac1 100644 --- a/linux/i2c/I2cComIF.h +++ b/linux/i2c/I2cComIF.h @@ -1,5 +1,5 @@ -#ifndef BSP_Q7S_COMIF_I2COMIF_H_ -#define BSP_Q7S_COMIF_I2COMIF_H_ +#ifndef LINUX_I2C_I2COMIF_H_ +#define LINUX_I2C_I2COMIF_H_ #include "I2cCookie.h" #include @@ -56,4 +56,4 @@ private: address_t i2cAddress, int* fileDescriptor); }; -#endif /* BSP_Q7S_COMIF_I2COMIF_H_ */ +#endif /* LINUX_I2C_I2COMIF_H_ */ diff --git a/linux/i2c/I2cCookie.h b/linux/i2c/I2cCookie.h index f03d6290..c924eb4e 100644 --- a/linux/i2c/I2cCookie.h +++ b/linux/i2c/I2cCookie.h @@ -1,5 +1,5 @@ -#ifndef SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_ -#define SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_ +#ifndef LINUX_I2C_I2CCOOKIE_H_ +#define LINUX_I2C_I2CCOOKIE_H_ #include #include @@ -34,4 +34,4 @@ private: std::string deviceFile; }; -#endif +#endif /* LINUX_I2C_I2CCOOKIE_H_ */ -- 2.43.0 From 0045cd20624746b7af6a11f153bfd0464492e43f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:45:31 +0100 Subject: [PATCH 05/34] simplified i2c code --- linux/gpio/LinuxLibgpioIF.h | 1 + linux/i2c/I2cComIF.cpp | 285 ++++++++++++++++++------------------ 2 files changed, 140 insertions(+), 146 deletions(-) diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index 4e9130b9..f8a5e176 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -6,6 +6,7 @@ #include class GpioCookie; + /** * @brief This class implements the GpioIF for a linux based system. The * implementation is based on the libgpiod lib which requires linux 4.8 diff --git a/linux/i2c/I2cComIF.cpp b/linux/i2c/I2cComIF.cpp index 2f1d710a..ef77baa1 100644 --- a/linux/i2c/I2cComIF.cpp +++ b/linux/i2c/I2cComIF.cpp @@ -14,191 +14,184 @@ I2cComIF::I2cComIF(object_id_t objectId): SystemObject(objectId){ I2cComIF::~I2cComIF() {} -ReturnValue_t I2cComIF::initializeInterface(CookieIF * cookie) { +ReturnValue_t I2cComIF::initializeInterface(CookieIF* cookie) { - address_t i2cAddress; - std::string deviceFile; + address_t i2cAddress; + std::string deviceFile; - if(cookie == nullptr) { - return NULLPOINTER; - } - I2cCookie* i2cCookie = dynamic_cast(cookie); - if(i2cCookie == nullptr) { - sif::error << "I2cComIF: Invalid I2C Cookie!" - << std::endl; - return NULLPOINTER; - } + if(cookie == nullptr) { + sif::error << "I2cComIF::initializeInterface: Invalid cookie!" << std::endl; + return NULLPOINTER; + } + I2cCookie* i2cCookie = dynamic_cast(cookie); + if(i2cCookie == nullptr) { + sif::error << "I2cComIF::initializeInterface: Invalid I2C cookie!" << std::endl; + return NULLPOINTER; + } - i2cAddress = i2cCookie->getAddress(); + i2cAddress = i2cCookie->getAddress(); - i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); - if(i2cDeviceMapIter == i2cDeviceMap.end()) { - size_t maxReplyLen = i2cCookie->getMaxReplyLen(); - I2cInstance_t i2cInstance = {std::vector(maxReplyLen), 0}; - std::pair status = i2cDeviceMap.emplace(i2cAddress, i2cInstance); - if (status.second == false) { - sif::error << "I2cComIF::initializeInterface: Failed to insert " - << "device with address " << i2cAddress << "to I2C device " - << "map" << std::endl; - return HasReturnvaluesIF::RETURN_OK; - } - } - else { - sif::error << "I2cComIF: Device with address " << i2cAddress - << "already in use" << std::endl; - } + i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); + if(i2cDeviceMapIter == i2cDeviceMap.end()) { + size_t maxReplyLen = i2cCookie->getMaxReplyLen(); + I2cInstance_t i2cInstance = {std::vector(maxReplyLen), 0}; + auto statusPair = i2cDeviceMap.emplace(i2cAddress, i2cInstance); + if (not statusPair.second) { + sif::error << "I2cComIF::initializeInterface: Failed to insert device with address " << + i2cAddress << "to I2C device " << "map" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; + } - i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); - if(i2cDeviceMapIter == i2cDeviceMap.end()) { - sif::error << "Failure" << std::endl; - } - - return HasReturnvaluesIF::RETURN_OK; + sif::error << "I2cComIF::initializeInterface: Device with address " << i2cAddress << + "already in use" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; } ReturnValue_t I2cComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) { - ReturnValue_t result; - int fd; - std::string deviceFile; + ReturnValue_t result; + int fd; + std::string deviceFile; - if(sendData == nullptr) { - sif::error << "I2cComIF::sendMessage: Send Data is nullptr" - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } + if(sendData == nullptr) { + sif::error << "I2cComIF::sendMessage: Send Data is nullptr" + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } - if(sendLen == 0) { - return HasReturnvaluesIF::RETURN_OK; - } + if(sendLen == 0) { + return HasReturnvaluesIF::RETURN_OK; + } - I2cCookie* i2cCookie = dynamic_cast(cookie); - if(i2cCookie == nullptr) { - sif::error << "I2cComIF::sendMessasge: Invalid I2C Cookie!" - << std::endl; - return NULLPOINTER; - } + I2cCookie* i2cCookie = dynamic_cast(cookie); + if(i2cCookie == nullptr) { + sif::error << "I2cComIF::sendMessasge: Invalid I2C Cookie!" + << std::endl; + return NULLPOINTER; + } - address_t i2cAddress = i2cCookie->getAddress(); - i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); - if (i2cDeviceMapIter == i2cDeviceMap.end()) { - sif::error << "I2cComIF::sendMessage: i2cAddress of Cookie not " - << "registered in i2cDeviceMap" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } + address_t i2cAddress = i2cCookie->getAddress(); + i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); + if (i2cDeviceMapIter == i2cDeviceMap.end()) { + sif::error << "I2cComIF::sendMessage: i2cAddress of Cookie not " + << "registered in i2cDeviceMap" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } - deviceFile = i2cCookie->getDeviceFile(); - result = openDevice(deviceFile, i2cAddress, &fd); - if (result != HasReturnvaluesIF::RETURN_OK){ - return result; - } + deviceFile = i2cCookie->getDeviceFile(); + result = openDevice(deviceFile, i2cAddress, &fd); + if (result != HasReturnvaluesIF::RETURN_OK){ + return result; + } - if (write(fd, sendData, sendLen) != (int)sendLen) { - sif::error << "I2cComIF::sendMessage: Failed to send data to I2C " - "device with error code " << errno << ". Error description: " - << strerror(errno) << std::endl; - close(fd); - return HasReturnvaluesIF::RETURN_FAILED; - } - close(fd); - return HasReturnvaluesIF::RETURN_OK; + if (write(fd, sendData, sendLen) != (int)sendLen) { + sif::error << "I2cComIF::sendMessage: Failed to send data to I2C " + "device with error code " << errno << ". Error description: " + << strerror(errno) << std::endl; + close(fd); + return HasReturnvaluesIF::RETURN_FAILED; + } + close(fd); + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t I2cComIF::getSendSuccess(CookieIF *cookie) { - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF *cookie, - size_t requestLen) { + size_t requestLen) { - ReturnValue_t result; - int fd; - std::string deviceFile; + ReturnValue_t result; + int fd; + std::string deviceFile; - if (requestLen == 0) { - return HasReturnvaluesIF::RETURN_OK; - } + if (requestLen == 0) { + return HasReturnvaluesIF::RETURN_OK; + } - I2cCookie* i2cCookie = dynamic_cast(cookie); - if(i2cCookie == nullptr) { - sif::error << "I2cComIF::requestReceiveMessage: Invalid I2C Cookie!" - << std::endl; - i2cDeviceMapIter->second.replyLen = 0; - return NULLPOINTER; - } + I2cCookie* i2cCookie = dynamic_cast(cookie); + if(i2cCookie == nullptr) { + sif::error << "I2cComIF::requestReceiveMessage: Invalid I2C Cookie!" + << std::endl; + i2cDeviceMapIter->second.replyLen = 0; + return NULLPOINTER; + } - address_t i2cAddress = i2cCookie->getAddress(); - i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); - if (i2cDeviceMapIter == i2cDeviceMap.end()) { - sif::error << "I2cComIF::requestReceiveMessage: i2cAddress of Cookie not " - << "registered in i2cDeviceMap" << std::endl; - i2cDeviceMapIter->second.replyLen = 0; - return HasReturnvaluesIF::RETURN_FAILED; - } + address_t i2cAddress = i2cCookie->getAddress(); + i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); + if (i2cDeviceMapIter == i2cDeviceMap.end()) { + sif::error << "I2cComIF::requestReceiveMessage: i2cAddress of Cookie not " + << "registered in i2cDeviceMap" << std::endl; + i2cDeviceMapIter->second.replyLen = 0; + return HasReturnvaluesIF::RETURN_FAILED; + } - deviceFile = i2cCookie->getDeviceFile(); - result = openDevice(deviceFile, i2cAddress, &fd); - if (result != HasReturnvaluesIF::RETURN_OK){ - i2cDeviceMapIter->second.replyLen = 0; - return result; - } + deviceFile = i2cCookie->getDeviceFile(); + result = openDevice(deviceFile, i2cAddress, &fd); + if (result != HasReturnvaluesIF::RETURN_OK){ + i2cDeviceMapIter->second.replyLen = 0; + return result; + } - uint8_t* replyBuffer = i2cDeviceMapIter->second.replyBuffer.data(); + uint8_t* replyBuffer = i2cDeviceMapIter->second.replyBuffer.data(); - if (read(fd, replyBuffer, requestLen) != (int)requestLen) { - sif::error << "I2cComIF::requestReceiveMessage: Reading from I2C " - << "device failed with error code " << errno <<". Description" - << " of error: " << strerror(errno) << std::endl; - close(fd); - i2cDeviceMapIter->second.replyLen = 0; - return HasReturnvaluesIF::RETURN_FAILED; - } + if (read(fd, replyBuffer, requestLen) != (int)requestLen) { + sif::error << "I2cComIF::requestReceiveMessage: Reading from I2C " + << "device failed with error code " << errno <<". Description" + << " of error: " << strerror(errno) << std::endl; + close(fd); + i2cDeviceMapIter->second.replyLen = 0; + return HasReturnvaluesIF::RETURN_FAILED; + } - i2cDeviceMapIter->second.replyLen = requestLen; + i2cDeviceMapIter->second.replyLen = requestLen; - close(fd); + close(fd); - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t I2cComIF::readReceivedMessage(CookieIF *cookie, - uint8_t **buffer, size_t* size) { - I2cCookie* i2cCookie = dynamic_cast(cookie); - if(i2cCookie == nullptr) { - sif::error << "I2cComIF::readReceivedMessage: Invalid I2C Cookie!" - << std::endl; - return NULLPOINTER; - } + uint8_t **buffer, size_t* size) { + I2cCookie* i2cCookie = dynamic_cast(cookie); + if(i2cCookie == nullptr) { + sif::error << "I2cComIF::readReceivedMessage: Invalid I2C Cookie!" + << std::endl; + return NULLPOINTER; + } - address_t i2cAddress = i2cCookie->getAddress(); - i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); - if (i2cDeviceMapIter == i2cDeviceMap.end()) { - sif::error << "I2cComIF::readReceivedMessage: i2cAddress of Cookie not " - << "found in i2cDeviceMap" << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - *buffer = i2cDeviceMapIter->second.replyBuffer.data(); - *size = i2cDeviceMapIter->second.replyLen; + address_t i2cAddress = i2cCookie->getAddress(); + i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress); + if (i2cDeviceMapIter == i2cDeviceMap.end()) { + sif::error << "I2cComIF::readReceivedMessage: i2cAddress of Cookie not " + << "found in i2cDeviceMap" << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + *buffer = i2cDeviceMapIter->second.replyBuffer.data(); + *size = i2cDeviceMapIter->second.replyLen; - return HasReturnvaluesIF::RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t I2cComIF::openDevice(std::string deviceFile, - address_t i2cAddress, int* fileDescriptor) { - *fileDescriptor = open(deviceFile.c_str(), O_RDWR); - if (*fileDescriptor < 0) { - sif::error << "I2cComIF: Opening i2c device failed with error code " - << errno << ". Error description: " << strerror(errno) - << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } + address_t i2cAddress, int* fileDescriptor) { + *fileDescriptor = open(deviceFile.c_str(), O_RDWR); + if (*fileDescriptor < 0) { + sif::error << "I2cComIF: Opening i2c device failed with error code " + << errno << ". Error description: " << strerror(errno) + << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } - if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) { - sif::error << "I2cComIF: Specifying target device failed with error " - << "code " << errno << ". Error description " - << strerror(errno) << std::endl; - return HasReturnvaluesIF::RETURN_FAILED; - } - return HasReturnvaluesIF::RETURN_OK; + if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) { + sif::error << "I2cComIF: Specifying target device failed with error " + << "code " << errno << ". Error description " + << strerror(errno) << std::endl; + return HasReturnvaluesIF::RETURN_FAILED; + } + return HasReturnvaluesIF::RETURN_OK; } -- 2.43.0 From a8d25575457e8f4519dd69a48ee3da535e19c444 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:52:40 +0100 Subject: [PATCH 06/34] added back member iter --- linux/gpio/LinuxLibgpioIF.cpp | 8 ++------ linux/gpio/LinuxLibgpioIF.h | 1 + 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/linux/gpio/LinuxLibgpioIF.cpp b/linux/gpio/LinuxLibgpioIF.cpp index daaff8ba..1b152a0f 100644 --- a/linux/gpio/LinuxLibgpioIF.cpp +++ b/linux/gpio/LinuxLibgpioIF.cpp @@ -39,7 +39,6 @@ ReturnValue_t LinuxLibgpioIF::initialize(GpioCookie* gpioCookie){ } ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { - //GpioMapIter mapToAddIter; std::string chipname; unsigned int lineNum; struct gpiod_chip *chip; @@ -48,9 +47,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { struct gpiod_line *lineHandle; int result; - //mapToAddIter = mapToAdd->begin(); for(auto& gpioConfig: mapToAdd) { - //for (; mapToAddIter != mapToAdd->end(); mapToAddIter++) { chipname = gpioConfig.second.chipname; chip = gpiod_chip_open_by_name(chipname.c_str()); if (!chip) { @@ -119,7 +116,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, int result; struct gpiod_line *lineHandle; - auto 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; @@ -139,7 +136,7 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { struct gpiod_line *lineHandle; - auto 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; @@ -153,7 +150,6 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ gpioId_t gpioId; - auto gpioMapIter = gpioMap.begin(); for(auto& gpioConfig: mapToAdd) { gpioId = gpioConfig.first; /* Cross check with private map */ diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index f8a5e176..6a412733 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -32,6 +32,7 @@ public: private: /* Holds the information and configuration of all used GPIOs */ GpioMap gpioMap; + GpioMapIter gpioMapIter; /** * @brief This functions drives line of a GPIO specified by the GPIO ID. -- 2.43.0 From 83f080abe98b119ff355e15c67dad32cc3a54e22 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 18:53:11 +0100 Subject: [PATCH 07/34] removed newlines --- bsp_q7s/devices/CMakeLists.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bsp_q7s/devices/CMakeLists.txt b/bsp_q7s/devices/CMakeLists.txt index 14eae324..c720706a 100644 --- a/bsp_q7s/devices/CMakeLists.txt +++ b/bsp_q7s/devices/CMakeLists.txt @@ -1,7 +1,3 @@ target_sources(${TARGET_NAME} PRIVATE HeaterHandler.cpp ) - - - - -- 2.43.0 From aa5690687a34b04bb68b3553a9631299543d2316 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 19:06:26 +0100 Subject: [PATCH 08/34] small form stuff --- linux/i2c/I2cCookie.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/linux/i2c/I2cCookie.cpp b/linux/i2c/I2cCookie.cpp index 7f86bdc3..fe0f3f92 100644 --- a/linux/i2c/I2cCookie.cpp +++ b/linux/i2c/I2cCookie.cpp @@ -2,8 +2,7 @@ I2cCookie::I2cCookie(address_t i2cAddress_, size_t maxReplyLen_, std::string deviceFile_) : - i2cAddress(i2cAddress_), maxReplyLen(maxReplyLen_), deviceFile( - deviceFile_) { + i2cAddress(i2cAddress_), maxReplyLen(maxReplyLen_), deviceFile(deviceFile_) { } address_t I2cCookie::getAddress() const { -- 2.43.0 From 967618f687ca267ee7064503f0aa0f4bba51060c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Sun, 14 Feb 2021 19:22:58 +0100 Subject: [PATCH 09/34] new linux boardtest folder --- bsp_q7s/ObjectFactory.cpp | 2 +- bsp_q7s/boardtest/CMakeLists.txt | 1 - linux/CMakeLists.txt | 1 + linux/boardtest/CMakeLists.txt | 10 ++++++++++ linux/boardtest/I2cTestClass.cpp | 8 ++++++++ linux/boardtest/I2cTestClass.h | 17 +++++++++++++++++ {bsp_q7s => linux}/boardtest/LibgpiodTest.cpp | 0 {bsp_q7s => linux}/boardtest/LibgpiodTest.h | 0 linux/boardtest/SpiTestClass.cpp | 8 ++++++++ linux/boardtest/SpiTestClass.h | 18 ++++++++++++++++++ linux/boardtest/UartTestClass.cpp | 8 ++++++++ linux/boardtest/UartTestClass.h | 15 +++++++++++++++ 12 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 linux/boardtest/CMakeLists.txt create mode 100644 linux/boardtest/I2cTestClass.cpp create mode 100644 linux/boardtest/I2cTestClass.h rename {bsp_q7s => linux}/boardtest/LibgpiodTest.cpp (100%) rename {bsp_q7s => linux}/boardtest/LibgpiodTest.h (100%) create mode 100644 linux/boardtest/SpiTestClass.cpp create mode 100644 linux/boardtest/SpiTestClass.h create mode 100644 linux/boardtest/UartTestClass.cpp create mode 100644 linux/boardtest/UartTestClass.h diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index aed9e23e..72e11d44 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -34,7 +34,7 @@ #include #if TEST_LIBGPIOD == 1 -#include "LibgpiodTest.h" +#include #endif void Factory::setStaticFrameworkObjectIds() { diff --git a/bsp_q7s/boardtest/CMakeLists.txt b/bsp_q7s/boardtest/CMakeLists.txt index 7e59ddb9..0599b73f 100644 --- a/bsp_q7s/boardtest/CMakeLists.txt +++ b/bsp_q7s/boardtest/CMakeLists.txt @@ -1,5 +1,4 @@ target_sources(${TARGET_NAME} PRIVATE - LibgpiodTest.cpp ) diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 9a25fdff..9101e15d 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -2,4 +2,5 @@ add_subdirectory(gpio) add_subdirectory(i2c) add_subdirectory(csp) add_subdirectory(spi) +add_subdirectory(boardtest) diff --git a/linux/boardtest/CMakeLists.txt b/linux/boardtest/CMakeLists.txt new file mode 100644 index 00000000..0fa4e322 --- /dev/null +++ b/linux/boardtest/CMakeLists.txt @@ -0,0 +1,10 @@ +target_sources(${TARGET_NAME} PRIVATE + LibgpiodTest.cpp + I2cTestClass.cpp + SpiTestClass.cpp + UartTestClass.cpp +) + + + + diff --git a/linux/boardtest/I2cTestClass.cpp b/linux/boardtest/I2cTestClass.cpp new file mode 100644 index 00000000..66c16b33 --- /dev/null +++ b/linux/boardtest/I2cTestClass.cpp @@ -0,0 +1,8 @@ +#include + +I2cTestClass::I2cTestClass(object_id_t objectId): TestTask(objectId) { +} + +ReturnValue_t I2cTestClass::performPeriodicAction() { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/linux/boardtest/I2cTestClass.h b/linux/boardtest/I2cTestClass.h new file mode 100644 index 00000000..172a7f71 --- /dev/null +++ b/linux/boardtest/I2cTestClass.h @@ -0,0 +1,17 @@ +#ifndef LINUX_BOARDTEST_I2CTESTCLASS_H_ +#define LINUX_BOARDTEST_I2CTESTCLASS_H_ + +#include + +class I2cTestClass: public TestTask { +public: + I2cTestClass(object_id_t objectId); + + ReturnValue_t performPeriodicAction() override; +private: + +}; + + + +#endif /* LINUX_BOARDTEST_I2CTESTCLASS_H_ */ diff --git a/bsp_q7s/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp similarity index 100% rename from bsp_q7s/boardtest/LibgpiodTest.cpp rename to linux/boardtest/LibgpiodTest.cpp diff --git a/bsp_q7s/boardtest/LibgpiodTest.h b/linux/boardtest/LibgpiodTest.h similarity index 100% rename from bsp_q7s/boardtest/LibgpiodTest.h rename to linux/boardtest/LibgpiodTest.h diff --git a/linux/boardtest/SpiTestClass.cpp b/linux/boardtest/SpiTestClass.cpp new file mode 100644 index 00000000..daf38749 --- /dev/null +++ b/linux/boardtest/SpiTestClass.cpp @@ -0,0 +1,8 @@ +#include + +SpiTestClass::SpiTestClass(object_id_t objectId): TestTask(objectId) { +} + +ReturnValue_t SpiTestClass::performPeriodicAction() { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/linux/boardtest/SpiTestClass.h b/linux/boardtest/SpiTestClass.h new file mode 100644 index 00000000..b3f10222 --- /dev/null +++ b/linux/boardtest/SpiTestClass.h @@ -0,0 +1,18 @@ +#ifndef LINUX_BOARDTEST_SPITESTCLASS_H_ +#define LINUX_BOARDTEST_SPITESTCLASS_H_ + +#include + +class SpiTestClass: public TestTask { +public: + SpiTestClass(object_id_t objectId); + + ReturnValue_t performPeriodicAction() override; +private: + +}; + + + + +#endif /* LINUX_BOARDTEST_SPITESTCLASS_H_ */ diff --git a/linux/boardtest/UartTestClass.cpp b/linux/boardtest/UartTestClass.cpp new file mode 100644 index 00000000..dc9f79c3 --- /dev/null +++ b/linux/boardtest/UartTestClass.cpp @@ -0,0 +1,8 @@ +#include + +UartTestClass::UartTestClass(object_id_t objectId): TestTask(objectId) { +} + +ReturnValue_t UartTestClass::performPeriodicAction() { + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/linux/boardtest/UartTestClass.h b/linux/boardtest/UartTestClass.h new file mode 100644 index 00000000..406d2af5 --- /dev/null +++ b/linux/boardtest/UartTestClass.h @@ -0,0 +1,15 @@ +#ifndef LINUX_BOARDTEST_UARTTESTCLASS_H_ +#define LINUX_BOARDTEST_UARTTESTCLASS_H_ + +#include + +class UartTestClass: public TestTask { +public: + UartTestClass(object_id_t objectId); + + ReturnValue_t performPeriodicAction() override; +private: + +}; + +#endif /* LINUX_BOARDTEST_UARTTESTCLASS_H_ */ -- 2.43.0 From 7c71e2b06738eeae426b9cf2ef3f34db7a837edb Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 12:36:28 +0100 Subject: [PATCH 10/34] separate folder for RPi builds --- cmake/scripts/RPi/create_cmake_debug_cfg.sh | 4 +++- cmake/scripts/RPi/create_cmake_release_cfg.sh | 4 +++- cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh | 4 +++- cmake/scripts/cmake_build_config.py | 5 +++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cmake/scripts/RPi/create_cmake_debug_cfg.sh b/cmake/scripts/RPi/create_cmake_debug_cfg.sh index deb78243..d0ec5d76 100644 --- a/cmake/scripts/RPi/create_cmake_debug_cfg.sh +++ b/cmake/scripts/RPi/create_cmake_debug_cfg.sh @@ -17,6 +17,7 @@ fi os_fsfw="linux" tgt_bsp="arm/raspberrypi" build_generator="" +build_dir="Debug-RPi" if [ "${OS}" = "Windows_NT" ]; then build_generator="MinGW Makefiles" # Could be other OS but this works for now. @@ -24,4 +25,5 @@ else build_generator="Unix Makefiles" fi -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" +python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "debug" -t "${tgt_bsp}" \ + -l"${build_dir}" diff --git a/cmake/scripts/RPi/create_cmake_release_cfg.sh b/cmake/scripts/RPi/create_cmake_release_cfg.sh index 0e23bee4..4eb9b38a 100644 --- a/cmake/scripts/RPi/create_cmake_release_cfg.sh +++ b/cmake/scripts/RPi/create_cmake_release_cfg.sh @@ -17,6 +17,7 @@ fi os_fsfw="linux" tgt_bsp="arm/raspberrypi" build_generator="" +build_dir="Release-RPi" if [ "${OS}" = "Windows_NT" ]; then build_generator="MinGW Makefiles" # Could be other OS but this works for now. @@ -24,4 +25,5 @@ else build_generator="Unix Makefiles" fi -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" +python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "release" -t "${tgt_bsp}" \ + -l"${build_dir}" diff --git a/cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh b/cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh index 3e952750..de7651a7 100644 --- a/cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh +++ b/cmake/scripts/RPi/create_cmake_relwithdeb_cfg.sh @@ -17,6 +17,7 @@ fi os_fsfw="linux" tgt_bsp="arm/raspberrypi" build_generator="" +build_dir="RelWithDeb-RPi" if [ "${OS}" = "Windows_NT" ]; then build_generator="MinGW Makefiles" # Could be other OS but this works for now. @@ -24,4 +25,5 @@ else build_generator="Unix Makefiles" fi -python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "reldeb" -t "${tgt_bsp}" +python3 cmake_build_config.py -o "${os_fsfw}" -g "${build_generator}" -b "reldeb" -t "${tgt_bsp}" \ + -l"${build_dir}" diff --git a/cmake/scripts/cmake_build_config.py b/cmake/scripts/cmake_build_config.py index a6388ef8..0e4b6f25 100644 --- a/cmake/scripts/cmake_build_config.py +++ b/cmake/scripts/cmake_build_config.py @@ -61,9 +61,10 @@ def main(): else: cmake_target_cfg_cmd = "" - # TODO: Use builddir if given (need to check whether path is relative or absolute) build_folder = cmake_build_type - + if args.builddir is not None: + build_folder = args.builddir + build_path = source_location + os.path.sep + build_folder if os.path.isdir(build_path): remove_old_dir = input(f"{build_folder} folder already exists. Remove old directory? [y/n]: ") -- 2.43.0 From 86e527882cda45c46c8a170d48aa23adb73b49f9 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 12:40:12 +0100 Subject: [PATCH 11/34] added loopback test mode --- linux/boardtest/LibgpiodTest.cpp | 27 +++++++++++++++++++-------- linux/boardtest/LibgpiodTest.h | 7 +++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index 51f89abe..dbd0947a 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -13,6 +13,7 @@ LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl; } gpioInterface->initialize(gpioCookie); + testCase = TestCases::READ; } LibgpiodTest::~LibgpiodTest() { @@ -22,16 +23,26 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { int gpioState; ReturnValue_t result; - result = gpioInterface->readGpio(gpioIds::Test_ID, &gpioState); - if (result != RETURN_OK) { - sif::debug << "LibgpiodTest::performPeriodicAction: Failed to read gpio " - << std::endl; - return RETURN_FAILED; + switch(testCase) { + case(testCase == TestCases::READ): { + result = gpioInterface->readGpio(gpioIds::Test_ID, &gpioState); + if (result != RETURN_OK) { + sif::debug << "LibgpiodTest::performPeriodicAction: Failed to read gpio " + << std::endl; + return RETURN_FAILED; + } + else { + sif::debug << "LibgpiodTest::performPeriodicAction: MIO 0 state = " << gpioState + << std::endl; + } + break; } - else { - sif::debug << "LibgpiodTest::performPeriodicAction: MIO 0 state = " << gpioState - << std::endl; + case(testCase == TestCases::LOOPBACK): { + } + } + + return RETURN_OK; } diff --git a/linux/boardtest/LibgpiodTest.h b/linux/boardtest/LibgpiodTest.h index 678c06a3..642d4cd7 100644 --- a/linux/boardtest/LibgpiodTest.h +++ b/linux/boardtest/LibgpiodTest.h @@ -12,6 +12,13 @@ */ class LibgpiodTest: public TestTask { public: + enum TestCases { + READ = 0, + LOOPBACK = 1 + }; + + TestCases testCase; + LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie); virtual ~LibgpiodTest(); -- 2.43.0 From ab1b4271ec9936942f8be3120f469b418b7cfe0f Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 12:45:10 +0100 Subject: [PATCH 12/34] updated cmake lists --- CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22e45134..2cde6b98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,14 @@ if(TGT_BSP) set(ADD_LINUX_FILES TRUE) set(ADD_CSP_LIB TRUE) endif() + + if(${TGT_BSP} MATCHES "arm/raspberrypi") + add_definitions(-DRASPBERRY_PI) + endif() + + if(${TGT_BSP} MATCHES "arm/q7s") + add_definitions(-DXIPHOS_Q7S) + endif() else() # Required by FSFW library set(FSFW_CONFIG_PATH "${BSP_PATH}/fsfwconfig") -- 2.43.0 From 400d5710d415b378e50feebf26418a183f642643 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 12:57:41 +0100 Subject: [PATCH 13/34] added link library gpiod --- bsp_rpi/ObjectFactory.cpp | 11 ++++++++++- bsp_rpi/boardconfig/rpi_config.h | 8 ++++++++ fsfwconfig/OBSWConfig.h | 7 +++++-- linux/boardtest/LibgpiodTest.cpp | 4 ++-- linux/gpio/CMakeLists.txt | 4 ++++ 5 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 bsp_rpi/boardconfig/rpi_config.h diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index c90db492..7a7820b8 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -1,17 +1,20 @@ #include "ObjectFactory.h" #include -#include #include #include #include #include +#include #include #include #include #include #include +#include +#include +#include #include #include @@ -45,4 +48,10 @@ void ObjectFactory::produce(){ new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); new SpiTest(objects::SPI_TEST); + new LinuxLibgpioIF(objects::GPIO_IF); + +#if RPI_TEST_GPIO == 1 + GpioCookie* gpioCookie = new GpioCookie(); + new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); +#endif } diff --git a/bsp_rpi/boardconfig/rpi_config.h b/bsp_rpi/boardconfig/rpi_config.h new file mode 100644 index 00000000..7d41e302 --- /dev/null +++ b/bsp_rpi/boardconfig/rpi_config.h @@ -0,0 +1,8 @@ +#ifndef BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ +#define BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ + +#define RPI_TEST_GPIO 1 + + + +#endif /* BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ */ diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index 66eddf12..b429f491 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -6,6 +6,11 @@ #ifndef FSFWCONFIG_OBSWCONFIG_H_ #define FSFWCONFIG_OBSWCONFIG_H_ +#ifdef RASPBERRY_PI +#include +#endif +#include "OBSWVersion.h" + #define TEST_LIBGPIOD 0 /* These defines should be disabled for mission code but are useful for @@ -18,8 +23,6 @@ debugging. */ #define PDU1_DEBUG 0 #define PDU2_DEBUG 0 -#include "OBSWVersion.h" - #ifdef __cplusplus #include "objects/systemObjectList.h" diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index dbd0947a..cc60ce18 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -24,7 +24,7 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { ReturnValue_t result; switch(testCase) { - case(testCase == TestCases::READ): { + case(TestCases::READ): { result = gpioInterface->readGpio(gpioIds::Test_ID, &gpioState); if (result != RETURN_OK) { sif::debug << "LibgpiodTest::performPeriodicAction: Failed to read gpio " @@ -37,7 +37,7 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { } break; } - case(testCase == TestCases::LOOPBACK): { + case(TestCases::LOOPBACK): { } } diff --git a/linux/gpio/CMakeLists.txt b/linux/gpio/CMakeLists.txt index 052173b3..9b20b35e 100644 --- a/linux/gpio/CMakeLists.txt +++ b/linux/gpio/CMakeLists.txt @@ -3,6 +3,10 @@ target_sources(${TARGET_NAME} PUBLIC LinuxLibgpioIF.cpp ) +target_link_libraries(${TARGET_NAME} PUBLIC + gpiod +) + -- 2.43.0 From 7f05285803ffec5696e03052025244beba076b36 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 12:59:50 +0100 Subject: [PATCH 14/34] heater handler moved --- mission/devices/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/mission/devices/CMakeLists.txt b/mission/devices/CMakeLists.txt index 4f45a7e6..aec93c1c 100644 --- a/mission/devices/CMakeLists.txt +++ b/mission/devices/CMakeLists.txt @@ -10,7 +10,6 @@ target_sources(${TARGET_NAME} PUBLIC PDU1Handler.cpp PDU2Handler.cpp ACUHandler.cpp - HeaterHandler.cpp SolarArrayDeploymentHandler.cpp ) -- 2.43.0 From e6c75c54ead7977f91e57fea1e41e3cda06c4b44 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 13:01:46 +0100 Subject: [PATCH 15/34] explicit cast so it compiles --- mission/devices/SolarArrayDeploymentHandler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 45521800..a78478e5 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -2,6 +2,7 @@ #include #include #include +#include SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_, object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, @@ -38,7 +39,7 @@ ReturnValue_t SolarArrayDeploymentHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - result = gpioInterface->initialize(gpioCookie); + result = gpioInterface->initialize(dynamic_cast(gpioCookie)); if (result != RETURN_OK) { sif::error << "SolarArrayDeploymentHandler::initialize: Failed to initialize Gpio interface" << std::endl; -- 2.43.0 From ac250cb4cb3561b174af2adb81373d0172076024 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 14:25:46 +0100 Subject: [PATCH 16/34] bugfix --- bsp_q7s/ObjectFactory.cpp | 1 - bsp_q7s/devices/HeaterHandler.cpp | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index d3078f82..e5a1e039 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/bsp_q7s/devices/HeaterHandler.cpp b/bsp_q7s/devices/HeaterHandler.cpp index eeda9a89..2387ab2a 100644 --- a/bsp_q7s/devices/HeaterHandler.cpp +++ b/bsp_q7s/devices/HeaterHandler.cpp @@ -1,5 +1,4 @@ #include "HeaterHandler.h" - #include #include #include @@ -10,8 +9,8 @@ HeaterHandler::HeaterHandler(object_id_t setObjectId_, object_id_t gpioDriverId_ SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), actionHelper(this, nullptr) { - commandQueue = QueueFactory::instance()->createMessageQueue( - cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); + commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, + MessageQueueMessage::MAX_MESSAGE_SIZE); } HeaterHandler::~HeaterHandler() { -- 2.43.0 From b03420c706a037c8aaf8fc71b27938f28d38b272 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 17:36:44 +0100 Subject: [PATCH 17/34] added service 20 --- bsp_hosted/InitMission.cpp | 2 + bsp_q7s/InitMission.cpp | 186 +++++++++--------- bsp_q7s/ObjectFactory.cpp | 6 +- bsp_rpi/CMakeLists.txt | 7 +- bsp_rpi/InitMission.cpp | 151 +++++++------- bsp_rpi/ObjectFactory.cpp | 20 +- bsp_rpi/boardconfig/rpi_config.h | 4 +- bsp_rpi/boardtest/CMakeLists.txt | 1 - bsp_rpi/gpio/CMakeLists.txt | 9 + bsp_rpi/gpio/GPIORPi.cpp | 36 ++++ bsp_rpi/gpio/GPIORPi.h | 26 +++ fsfwconfig/OBSWConfig.h | 16 +- fsfwconfig/devices/gpioIds.h | 3 +- linux/boardtest/LibgpiodTest.cpp | 40 +++- linux/boardtest/LibgpiodTest.h | 3 +- linux/gpio/GpioCookie.cpp | 10 +- linux/gpio/GpioCookie.h | 2 +- linux/gpio/GpioIF.h | 1 + linux/gpio/LinuxLibgpioIF.h | 1 + linux/gpio/gpioDefinitions.h | 3 + .../boardtest => misc/archive}/RPiGPIO.cpp | 0 {bsp_rpi/boardtest => misc/archive}/RPiGPIO.h | 0 mission/core/GenericFactory.cpp | 5 +- mission/utility/InitMission.h | 22 +++ 24 files changed, 358 insertions(+), 196 deletions(-) create mode 100644 bsp_rpi/gpio/CMakeLists.txt create mode 100644 bsp_rpi/gpio/GPIORPi.cpp create mode 100644 bsp_rpi/gpio/GPIORPi.h rename {bsp_rpi/boardtest => misc/archive}/RPiGPIO.cpp (100%) rename {bsp_rpi/boardtest => misc/archive}/RPiGPIO.h (100%) create mode 100644 mission/utility/InitMission.h diff --git a/bsp_hosted/InitMission.cpp b/bsp_hosted/InitMission.cpp index 39dcafff..4da13c70 100644 --- a/bsp_hosted/InitMission.cpp +++ b/bsp_hosted/InitMission.cpp @@ -11,6 +11,8 @@ #include #include +#include + #include // This is configured for linux without \cr diff --git a/bsp_q7s/InitMission.cpp b/bsp_q7s/InitMission.cpp index 681d6b48..2930803e 100644 --- a/bsp_q7s/InitMission.cpp +++ b/bsp_q7s/InitMission.cpp @@ -2,6 +2,8 @@ #include "ObjectFactory.h" #include +#include + #include #include #include @@ -13,7 +15,7 @@ #include -// This is configured for linux without \cr +/* This is configured for linux without CR */ #ifdef LINUX ServiceInterfaceStream sif::debug("DEBUG"); ServiceInterfaceStream sif::info("INFO"); @@ -39,144 +41,142 @@ void InitMission::initMission() { initTasks(); } -void InitMission::initTasks(){ +void InitMission::initTasks() { + TaskFactory* factory = TaskFactory::instance(); + if(factory == nullptr) { + /* Should never happen ! */ + return; + } + /* TMTC Distribution */ - PeriodicTaskIF* TmTcDistributor = TaskFactory::instance()-> - createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.2, nullptr); - ReturnValue_t result = TmTcDistributor->addComponent( + PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + ReturnValue_t result = tmTcDistributor->addComponent( objects::CCSDS_PACKET_DISTRIBUTOR); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR); } - result = TmTcDistributor->addComponent(objects::PUS_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) { + InitMission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR); } - result = TmTcDistributor->addComponent(objects::TM_FUNNEL); + result = tmTcDistributor->addComponent(objects::TM_FUNNEL); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Object add component failed" << std::endl; + InitMission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL); } /* UDP bridge */ - PeriodicTaskIF* UdpBridgeTask = TaskFactory::instance()->createPeriodicTask( - "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.2, nullptr); - result = UdpBridgeTask->addComponent(objects::UDP_BRIDGE); + PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( + "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Add component UDP Unix Bridge failed" << std::endl; + InitMission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE); } - PeriodicTaskIF* UdpPollingTask = TaskFactory::instance()-> - createPeriodicTask("UDP_POLLING", 80, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); - result = UdpPollingTask->addComponent(objects::UDP_POLLING_TASK); + PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( + "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); + result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "Add component UDP Polling failed" << std::endl; + InitMission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK); } /* PUS Services */ - PeriodicTaskIF* PusVerification = TaskFactory::instance()-> - createPeriodicTask("PUS_VERIF_1", 40, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); - result = PusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + PeriodicTaskIF* pusVerification = factory->createPeriodicTask( + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION); } - PeriodicTaskIF* PusEvents = TaskFactory::instance()-> - createPeriodicTask("PUS_VERIF_1", 60, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); - result = PusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); - 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, nullptr); + result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); } - PeriodicTaskIF* PusHighPrio = TaskFactory::instance()-> - createPeriodicTask("PUS_HIGH_PRIO", 50, - PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.200, nullptr); - result = PusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( + "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + result = pusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS); } - result = PusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT); } - PeriodicTaskIF* PusMedPrio = TaskFactory::instance()-> - createPeriodicTask("PUS_HIGH_PRIO", 40, - PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.8, nullptr); - result = PusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( + "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, nullptr); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT); } - result = PusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT); + } + result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); } - PeriodicTaskIF* PusLowPrio = TaskFactory::instance()-> - createPeriodicTask("PUSB", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 1.6, nullptr); - result = PusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); - if(result!=HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( + "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, nullptr); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST); } //TODO: Add handling of missed deadlines /* Polling Sequence Table Default */ - FixedTimeslotTaskIF * PollingSequenceTableTaskDefault = - TaskFactory::instance()->createFixedTimeslotTask("PST_TASK_DEFAULT", - 50, PeriodicTaskIF::MINIMUM_STACK_SIZE*4, 3.0, - nullptr); - result = pst::pollingSequenceInitDefault(PollingSequenceTableTaskDefault); + FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask( + "PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, nullptr); + result = pst::pollingSequenceInitDefault(pollingSequenceTableTaskDefault); if (result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: Creating PST failed!" - << std::endl; + sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; } #if TE0720 == 0 - FixedTimeslotTaskIF* GomSpacePstTask = TaskFactory::instance()-> + FixedTimeslotTaskIF* gomSpacePstTask = factory-> createFixedTimeslotTask("GS_PST_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, nullptr); - result = pst::gomspacePstInit(GomSpacePstTask); + result = pst::gomspacePstInit(gomSpacePstTask); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::initTasks: GomSpace PST initialization " - << "failed!" << std::endl; + sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl; } #endif + PeriodicTaskIF* testTask = factory->createPeriodicTask( + "GPIOD_TEST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, nullptr); +#if OBSW_ADD_TEST_CODE == 1 + result = testTask->addComponent(objects::TEST_TASK); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + } +#endif /* OBSW_ADD_TEST_CODE == 1 */ #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; + result = testTask->addComponent(objects::LIBGPIOD_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); } -#endif +#endif /* TE0720 == 1 && TEST_LIBGPIOD == 1 */ - //Main thread sleep sif::info << "Starting tasks.." << std::endl; - TmTcDistributor->startTask(); - UdpBridgeTask->startTask(); - UdpPollingTask->startTask(); + tmTcDistributor->startTask(); + udpBridgeTask->startTask(); + udpPollingTask->startTask(); #if TE0720 == 0 - GomSpacePstTask->startTask(); + gomSpacePstTask->startTask(); #endif - PollingSequenceTableTaskDefault->startTask(); + pollingSequenceTableTaskDefault->startTask(); - PusVerification->startTask(); - PusEvents->startTask(); - PusHighPrio->startTask(); - PusMedPrio->startTask(); - PusLowPrio->startTask(); + pusVerification->startTask(); + pusEvents->startTask(); + pusHighPrio->startTask(); + pusMedPrio->startTask(); + pusLowPrio->startTask(); -#if TE0720 == 1 && TEST_LIBGPIOD == 1 - TestTask->startTask(); -#endif + testTask->startTask(); sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index e5a1e039..1a54ca34 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -180,14 +180,14 @@ void ObjectFactory::produce(){ GpioConfig_t gpioConfigMio0(std::string("gpiochip0"), 0, std::string("MIO0"), gpio::IN, 0); GpioCookie* gpioCookie = new GpioCookie; - gpioCookie->addGpio(gpioIds::Test_ID, gpioConfigMio0); + gpioCookie->addGpio(gpioIds::TEST_ID_0, gpioConfigMio0); new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); #elif TE0720 == 1 /* Configuration for MIO0 on TE0720-03-1CFA */ GpioConfig_t gpioConfigForDummyHeater(std::string("gpiochip0"), 0, std::string("Heater0"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigForDummyHeater); - new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, objects::PCDU_HANDLER, - pcduSwitches::TCS_BOARD_8V_HEATER_IN); + new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, heaterGpiosCookie, + objects::PCDU_HANDLER, pcduSwitches::TCS_BOARD_8V_HEATER_IN); #endif } diff --git a/bsp_rpi/CMakeLists.txt b/bsp_rpi/CMakeLists.txt index 281994bf..da35633d 100644 --- a/bsp_rpi/CMakeLists.txt +++ b/bsp_rpi/CMakeLists.txt @@ -6,11 +6,8 @@ target_sources(${TARGET_NAME} PUBLIC add_subdirectory(boardconfig) add_subdirectory(boardtest) - -# wiringPi is deprecated unfortunately.. -#target_link_libraries(${TARGET_NAME} PRIVATE -# wiringPi -#) +add_subdirectory(gpio) + diff --git a/bsp_rpi/InitMission.cpp b/bsp_rpi/InitMission.cpp index 197abcc6..f3dc47ed 100644 --- a/bsp_rpi/InitMission.cpp +++ b/bsp_rpi/InitMission.cpp @@ -1,6 +1,12 @@ #include "InitMission.h" #include "ObjectFactory.h" +#include +#include +#include + +#include + #include #include #include @@ -8,9 +14,6 @@ #include #include #include -#include -#include -#include #include @@ -34,127 +37,129 @@ void InitMission::initMission() { void InitMission::initTasks(){ /* TMTC Distribution */ - PeriodicTaskIF* TmTcDistributor = TaskFactory::instance()-> + PeriodicTaskIF* tmTcDistributor = TaskFactory::instance()-> createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.100, nullptr); - ReturnValue_t result = TmTcDistributor->addComponent( + 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); + 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); + result = tmTcDistributor->addComponent(objects::TM_FUNNEL); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Object add component failed" << std::endl; } /* UDP bridge */ - PeriodicTaskIF* UdpBridgeTask = TaskFactory::instance()->createPeriodicTask( + PeriodicTaskIF* udpBridgeTask = TaskFactory::instance()->createPeriodicTask( "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); - result = UdpBridgeTask->addComponent(objects::UDP_BRIDGE); + result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Unix Bridge failed" << std::endl; } - PeriodicTaskIF* UdpPollingTask = TaskFactory::instance()-> + PeriodicTaskIF* udpPollingTask = TaskFactory::instance()-> createPeriodicTask("UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); - result = UdpPollingTask->addComponent(objects::UDP_POLLING_TASK); + result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Polling failed" << std::endl; } /* PUS Services */ - PeriodicTaskIF* PusVerification = TaskFactory::instance()-> - createPeriodicTask("PUS_VERIF_1", 40, + PeriodicTaskIF* pusVerification = TaskFactory::instance()-> + createPeriodicTask("PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); - result = PusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); + result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); if(result != HasReturnvaluesIF::RETURN_OK){ sif::error << "Object add component failed" << std::endl; } - PeriodicTaskIF* PusEvents = TaskFactory::instance()-> - createPeriodicTask("PUS_VERIF_1", 60, + PeriodicTaskIF* pusEvents = TaskFactory::instance()-> + createPeriodicTask("PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); - result = PusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); + result = pusVerification->addComponent(objects::PUS_SERVICE_5_EVENT_REPORTING); if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + InitMission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING); } - PeriodicTaskIF* PusHighPrio = TaskFactory::instance()-> + PeriodicTaskIF* pusHighPrio = TaskFactory::instance()-> createPeriodicTask("PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); - result = PusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; + 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){ - sif::error << "Object add component failed" << std::endl; + 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 = TaskFactory::instance()-> + PeriodicTaskIF* pusMedPrio = TaskFactory::instance()-> createPeriodicTask("PUS_HIGH_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, nullptr); - result = PusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - result = PusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - - PeriodicTaskIF* PusLowPrio = TaskFactory::instance()-> - createPeriodicTask("PUSB", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 1.6, nullptr); - result = PusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add component failed" << std::endl; - } - - -#if OBSW_ADD_TEST_CODE == 1 - FixedTimeslotTaskIF* TestTimeslotTask = TaskFactory::instance()-> - createFixedTimeslotTask("PST_TEST_TASK", 10, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.0, nullptr); - result = pst::pollingSequenceTestFunction(TestTimeslotTask); + result = pusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT); if(result != HasReturnvaluesIF::RETURN_OK) { - sif::error << "InitMission::createTasks: Test PST initialization " - << "failed!" << std::endl; + InitMission::printAddObjectError("PUS8", objects::PUS_SERVICE_8_FUNCTION_MGMT); } - -#endif - - PeriodicTaskIF* SpiTestTask = TaskFactory::instance()-> - createPeriodicTask("SPI_TEST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 2.0, nullptr); - result = SpiTestTask->addComponent(objects::SPI_TEST); - if(result != HasReturnvaluesIF::RETURN_OK){ - sif::error << "Object add SPI test failed" << std::endl; + 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); } - //Main thread sleep + PeriodicTaskIF* pusLowPrio = TaskFactory::instance()-> + createPeriodicTask("PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 1.6, nullptr); + result = pusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); + } + + PeriodicTaskIF* testTask = TaskFactory::instance()-> + createPeriodicTask("SPI_TEST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, + 2.0, nullptr); +#if OBSW_ADD_TEST_CODE == 1 + result = testTask->addComponent(objects::TEST_TASK); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("TEST_TASK", objects::TEST_TASK); + } +#endif /* OBSW_ADD_TEST_CODE == 1 */ +#if RPI_ADD_SPI_TEST == 1 + result = testTask->addComponent(objects::SPI_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("SPI_TEST", objects::SPI_TEST); + } +#endif /* RPI_ADD_SPI_TEST == 1 */ +#if RPI_ADD_GPIO_TEST == 1 + result = testTask->addComponent(objects::LIBGPIOD_TEST); + if(result != HasReturnvaluesIF::RETURN_OK) { + InitMission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); + } +#endif /* RPI_ADD_GPIO_TEST == 1 */ + sif::info << "Starting tasks.." << std::endl; - TmTcDistributor->startTask(); - UdpBridgeTask->startTask(); - UdpPollingTask->startTask(); + tmTcDistributor->startTask(); + udpBridgeTask->startTask(); + udpPollingTask->startTask(); - PusVerification->startTask(); - PusEvents->startTask(); - PusHighPrio->startTask(); - PusMedPrio->startTask(); - PusLowPrio->startTask(); - - SpiTestTask->startTask(); + pusVerification->startTask(); + pusEvents->startTask(); + pusHighPrio->startTask(); + pusMedPrio->startTask(); + pusLowPrio->startTask(); #if OBSW_ADD_TEST_CODE == 1 - TestTimeslotTask->startTask(); -#endif + testTask->startTask(); +#endif /* OBSW_ADD_TEST_CODE == 1 */ sif::info << "Tasks started.." << std::endl; } diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index 7a7820b8..458456c8 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -1,7 +1,9 @@ #include "ObjectFactory.h" #include +#include #include +#include #include #include #include @@ -47,11 +49,23 @@ void ObjectFactory::produce(){ objects::TM_STORE, objects::TC_STORE); new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE); - new SpiTest(objects::SPI_TEST); - new LinuxLibgpioIF(objects::GPIO_IF); + new LinuxLibgpioIF(objects::GPIO_IF); -#if RPI_TEST_GPIO == 1 +#if RPI_ADD_SPI_TEST == 1 + new SpiTest(objects::SPI_TEST); +#endif + +#if RPI_LOOPBACK_TEST_GPIO == 1 GpioCookie* gpioCookie = new GpioCookie(); + /* Loopback pins. Adapt according to setup */ + gpioId_t gpioIdSender = gpioIds::TEST_ID_0; + int bcmPinSender = 26; + gpioId_t gpioIdReader = gpioIds::TEST_ID_1; + int bcmPinReader = 16; + gpio::createRpiGpioConfig(gpioCookie, gpioIdSender, bcmPinSender, "GPIO_LB_SENDER", + gpio::Direction::OUT, 0); + gpio::createRpiGpioConfig(gpioCookie, gpioIdReader, bcmPinReader, "GPIO_LB_READER", + gpio::Direction::IN, 0); new LibgpiodTest(objects::LIBGPIOD_TEST, objects::GPIO_IF, gpioCookie); #endif } diff --git a/bsp_rpi/boardconfig/rpi_config.h b/bsp_rpi/boardconfig/rpi_config.h index 7d41e302..89141b80 100644 --- a/bsp_rpi/boardconfig/rpi_config.h +++ b/bsp_rpi/boardconfig/rpi_config.h @@ -1,7 +1,9 @@ #ifndef BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ #define BSP_RPI_BOARDCONFIG_RPI_CONFIG_H_ -#define RPI_TEST_GPIO 1 +#define RPI_ADD_GPIO_TEST 1 +#define RPI_ADD_SPI_TEST 1 +#define RPI_LOOPBACK_TEST_GPIO 1 diff --git a/bsp_rpi/boardtest/CMakeLists.txt b/bsp_rpi/boardtest/CMakeLists.txt index 1e373efb..768fc52f 100644 --- a/bsp_rpi/boardtest/CMakeLists.txt +++ b/bsp_rpi/boardtest/CMakeLists.txt @@ -1,6 +1,5 @@ target_sources(${TARGET_NAME} PRIVATE SpiTest.cpp - RPiGPIO.cpp ) diff --git a/bsp_rpi/gpio/CMakeLists.txt b/bsp_rpi/gpio/CMakeLists.txt new file mode 100644 index 00000000..85bd6aa6 --- /dev/null +++ b/bsp_rpi/gpio/CMakeLists.txt @@ -0,0 +1,9 @@ +target_sources(${TARGET_NAME} PUBLIC + GPIORPi.cpp +) + + + + + + diff --git a/bsp_rpi/gpio/GPIORPi.cpp b/bsp_rpi/gpio/GPIORPi.cpp new file mode 100644 index 00000000..84a3365f --- /dev/null +++ b/bsp_rpi/gpio/GPIORPi.cpp @@ -0,0 +1,36 @@ +#include "GPIORPi.h" +#include + +#include +#include + +ReturnValue_t gpio::createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int bcmPin, + std::string consumer, gpio::Direction direction, int initValue) { + if(cookie == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + GpioConfig_t config; + /* Default chipname for Raspberry Pi. There is still gpiochip1 for expansion, but most users + will not need this */ + config.chipname = "gpiochip0"; + + config.consumer = consumer; + config.direction = direction; + config.initValue = initValue; + + /* Sanity check for the BCM pins before assigning it */ + if(bcmPin > 27) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "createRpiGpioConfig: BCM pin " << bcmPin << " invalid!" << std::endl; +#else + sif::printError("createRpiGpioConfig: BCM pin %d invalid!\n", bcmPin); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return HasReturnvaluesIF::RETURN_FAILED; + } + config.lineNum = bcmPin; + cookie->addGpio(gpioId, config); + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/bsp_rpi/gpio/GPIORPi.h b/bsp_rpi/gpio/GPIORPi.h new file mode 100644 index 00000000..a2c11879 --- /dev/null +++ b/bsp_rpi/gpio/GPIORPi.h @@ -0,0 +1,26 @@ +#ifndef BSP_RPI_GPIO_GPIORPI_H_ +#define BSP_RPI_GPIO_GPIORPI_H_ + +#include +#include + +class GpioCookie; + +namespace gpio { + +/** + * Create a GpioConfig_t. This function does a sanity check on the BCM pin number and fails if the + * BCM pin is invalid. + * @param cookie Adds the configuration to this cookie directly + * @param gpioId ID which identifies the GPIO configuration + * @param bcmPin Raspberry Pi BCM pin + * @param consumer Information string + * @param direction GPIO direction + * @param initValue Intial value for output pins, 0 for low, 1 for high + * @return + */ +ReturnValue_t createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int bcmPin, + std::string consumer, gpio::Direction direction, int initValue); +} + +#endif /* BSP_RPI_GPIO_GPIORPI_H_ */ diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index abfb7456..5f841062 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -11,18 +11,18 @@ #endif #include "OBSWVersion.h" -#define TEST_LIBGPIOD 0 - /* These defines should be disabled for mission code but are useful for debugging. */ -#define OBSW_VERBOSE_LEVEL 1 +#define OBSW_VERBOSE_LEVEL 1 +#define OBSW_ADD_TEST_CODE 1 +#define TEST_LIBGPIOD 0 -#define TE0720 0 +#define TE0720 0 -#define P60DOCK_DEBUG 0 -#define PDU1_DEBUG 0 -#define PDU2_DEBUG 0 -#define ACU_DEBUG 1 +#define P60DOCK_DEBUG 0 +#define PDU1_DEBUG 0 +#define PDU2_DEBUG 0 +#define ACU_DEBUG 1 #ifdef __cplusplus diff --git a/fsfwconfig/devices/gpioIds.h b/fsfwconfig/devices/gpioIds.h index 70507b42..1e95ab9d 100644 --- a/fsfwconfig/devices/gpioIds.h +++ b/fsfwconfig/devices/gpioIds.h @@ -15,7 +15,8 @@ namespace gpioIds { HEATER_7, DEPLSA1, DEPLSA2, - Test_ID + TEST_ID_0, + TEST_ID_1 }; } diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index cc60ce18..5dec5581 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -13,7 +13,7 @@ LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl; } gpioInterface->initialize(gpioCookie); - testCase = TestCases::READ; + testCase = TestCases::LOOPBACK; } LibgpiodTest::~LibgpiodTest() { @@ -25,7 +25,7 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { switch(testCase) { case(TestCases::READ): { - result = gpioInterface->readGpio(gpioIds::Test_ID, &gpioState); + result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState); if (result != RETURN_OK) { sif::debug << "LibgpiodTest::performPeriodicAction: Failed to read gpio " << std::endl; @@ -38,7 +38,7 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { break; } case(TestCases::LOOPBACK): { - + break; } } @@ -46,3 +46,37 @@ ReturnValue_t LibgpiodTest::performPeriodicAction() { return RETURN_OK; } +ReturnValue_t LibgpiodTest::performOneShotAction() { + int gpioState; + ReturnValue_t result; + + switch(testCase) { + case(TestCases::READ): { + break; + } + case(TestCases::LOOPBACK): { + result = gpioInterface->pullHigh(gpioIds::TEST_ID_0); + if(result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "LibgpiodTest::performOneShotAction:" + "GPIO pulled high successfully for loopback test" << std::endl; + } + else { + sif::warning << "LibgpiodTest::performOneShotAction: Could not pull GPIO high!" + << std::endl; + return HasReturnvaluesIF::RETURN_OK; + } + result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState); + if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 1) { + sif::info << "LibgpiodTest::performOneShotAction:" + "GPIO state read successfully and is high" << std::endl; + } + else { + sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not high!" + << std::endl; + return HasReturnvaluesIF::RETURN_OK; + } + break; + } + } + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/linux/boardtest/LibgpiodTest.h b/linux/boardtest/LibgpiodTest.h index 642d4cd7..e9c6c030 100644 --- a/linux/boardtest/LibgpiodTest.h +++ b/linux/boardtest/LibgpiodTest.h @@ -23,7 +23,8 @@ public: virtual ~LibgpiodTest(); protected: - virtual ReturnValue_t performPeriodicAction() override; + ReturnValue_t performOneShotAction() override; + ReturnValue_t performPeriodicAction() override; private: GpioIF* gpioInterface; diff --git a/linux/gpio/GpioCookie.cpp b/linux/gpio/GpioCookie.cpp index 7f80b550..cd73574c 100644 --- a/linux/gpio/GpioCookie.cpp +++ b/linux/gpio/GpioCookie.cpp @@ -4,17 +4,23 @@ GpioCookie::GpioCookie() { } -void GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig){ +ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t& gpioConfig){ auto gpioMapIter = gpioMap.find(gpioId); if(gpioMapIter == gpioMap.end()) { auto statusPair = gpioMap.emplace(gpioId, gpioConfig); if (statusPair.second == false) { +#if FSFW_VERBOSE_LEVEL >= 1 sif::error << "GpioCookie::addGpio: Failed to add GPIO " << gpioId << "to GPIO map" << std::endl; +#endif + return HasReturnvaluesIF::RETURN_FAILED; } - return; + return HasReturnvaluesIF::RETURN_OK; } +#if FSFW_VERBOSE_LEVEL >= 1 sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map " << std::endl; +#endif + return HasReturnvaluesIF::RETURN_FAILED; } GpioMap GpioCookie::getGpioMap() const { diff --git a/linux/gpio/GpioCookie.h b/linux/gpio/GpioCookie.h index 05e80a2e..e1436813 100644 --- a/linux/gpio/GpioCookie.h +++ b/linux/gpio/GpioCookie.h @@ -23,7 +23,7 @@ public: virtual ~GpioCookie(); - void addGpio(gpioId_t gpioId, GpioConfig_t gpioConfig); + ReturnValue_t addGpio(gpioId_t gpioId, GpioConfig_t& gpioConfig); /** * @brief Get map with registered GPIOs. */ diff --git a/linux/gpio/GpioIF.h b/linux/gpio/GpioIF.h index 269174e4..80d3a727 100644 --- a/linux/gpio/GpioIF.h +++ b/linux/gpio/GpioIF.h @@ -29,6 +29,7 @@ public: * functionality to pull a certain GPIO to high logic level. * * @param gpioId A unique number which specifies the GPIO to drive. + * @return Returns RETURN_OK for success. This should never return RETURN_FAILED. */ virtual ReturnValue_t pullHigh(gpioId_t gpioId) = 0; diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index 6a412733..a849bb09 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -58,6 +58,7 @@ private: * @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd. */ ReturnValue_t configureGpios(GpioMap& mapToAdd); + }; #endif /* LINUX_GPIO_LINUXLIBGPIOIF_H_ */ diff --git a/linux/gpio/gpioDefinitions.h b/linux/gpio/gpioDefinitions.h index bbc599ee..ce26ec78 100644 --- a/linux/gpio/gpioDefinitions.h +++ b/linux/gpio/gpioDefinitions.h @@ -28,6 +28,9 @@ enum Direction { * pointer. */ typedef struct GpioConfig { + GpioConfig(): chipname(), lineNum(0), consumer(), direction(gpio::Direction::OUT), + initValue(0) {}; + GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, gpio::Direction direction_, int initValue_): chipname(chipname_), lineNum(lineNum_), consumer(consumer_), diff --git a/bsp_rpi/boardtest/RPiGPIO.cpp b/misc/archive/RPiGPIO.cpp similarity index 100% rename from bsp_rpi/boardtest/RPiGPIO.cpp rename to misc/archive/RPiGPIO.cpp diff --git a/bsp_rpi/boardtest/RPiGPIO.h b/misc/archive/RPiGPIO.h similarity index 100% rename from bsp_rpi/boardtest/RPiGPIO.h rename to misc/archive/RPiGPIO.h diff --git a/mission/core/GenericFactory.cpp b/mission/core/GenericFactory.cpp index 2a254cf0..2fcb4450 100644 --- a/mission/core/GenericFactory.cpp +++ b/mission/core/GenericFactory.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -78,11 +79,13 @@ void ObjectFactory::produceGenericObjects() { apid::EIVE_OBSW, pus::PUS_SERVICE_9); new Service17Test(objects::PUS_SERVICE_17_TEST, apid::EIVE_OBSW, pus::PUS_SERVICE_17); + new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS, apid::EIVE_OBSW, + pus::PUS_SERVICE_20); new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, apid::EIVE_OBSW, pus::PUS_SERVICE_200); /* Test Device Handler */ #if OBSW_ADD_TEST_CODE == 1 - new TestTask(objects::TEST_TASK); + new TestTask(objects::TEST_TASK); #endif } diff --git a/mission/utility/InitMission.h b/mission/utility/InitMission.h new file mode 100644 index 00000000..93ebc9bc --- /dev/null +++ b/mission/utility/InitMission.h @@ -0,0 +1,22 @@ +#ifndef MISSION_UTILITY_INITMISSION_H_ +#define MISSION_UTILITY_INITMISSION_H_ + +#include +#include + +namespace InitMission { + +void printAddObjectError(const char* name, object_id_t objectId) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "InitMission::printAddError: Adding object " << name << " with object ID 0x" + << std::hex << std::setfill('0') << std::setw(8) << objectId + << " failed!" << std::dec << std::endl; +#else + sif::printError("InitMission::printAddError: Adding object %s with object ID 0x%08x failed!\n" , + name, objectId); +#endif +} + +} + +#endif /* MISSION_UTILITY_INITMISSION_H_ */ -- 2.43.0 From e9ffa930de5936e955519ed53bc9c3edab36e9a7 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 18:46:45 +0100 Subject: [PATCH 18/34] better missed deadline handling --- bsp_hosted/InitMission.cpp | 4 +- bsp_hosted/InitMission.h | 2 +- bsp_hosted/main.cpp | 2 +- bsp_q7s/InitMission.cpp | 62 ++++++++++++----------- bsp_q7s/InitMission.h | 2 +- bsp_q7s/main.cpp | 6 +-- bsp_rpi/InitMission.cpp | 84 ++++++++++++++++---------------- bsp_rpi/InitMission.h | 2 +- bsp_rpi/ObjectFactory.cpp | 18 ++++--- bsp_rpi/boardtest/CMakeLists.txt | 1 - bsp_rpi/boardtest/SpiTest.cpp | 61 ----------------------- bsp_rpi/boardtest/SpiTest.h | 45 ----------------- bsp_rpi/main.cpp | 10 ++-- fsfw | 2 +- fsfwconfig/OBSWConfig.h | 17 ++++--- linux/boardtest/LibgpiodTest.cpp | 17 +++++++ mission/utility/InitMission.h | 4 +- test/testtasks/TestTask.cpp | 21 +++----- test/testtasks/TestTask.h | 3 +- 19 files changed, 136 insertions(+), 227 deletions(-) delete mode 100644 bsp_rpi/boardtest/SpiTest.cpp delete mode 100644 bsp_rpi/boardtest/SpiTest.h diff --git a/bsp_hosted/InitMission.cpp b/bsp_hosted/InitMission.cpp index 4da13c70..5ed5775d 100644 --- a/bsp_hosted/InitMission.cpp +++ b/bsp_hosted/InitMission.cpp @@ -30,7 +30,7 @@ ServiceInterfaceStream sif::error("ERROR", true, false, true); ObjectManagerIF *objectManager = nullptr; -void InitMission::initMission() { +void initmission::initMission() { sif::info << "Building global objects.." << std::endl; /* Instantiate global object manager and also create all objects */ objectManager = new ObjectManager(ObjectFactory::produce); @@ -41,7 +41,7 @@ void InitMission::initMission() { initTasks(); } -void InitMission::initTasks(){ +void initmission::initTasks(){ /* TMTC Distribution */ PeriodicTaskIF* TmTcDistributor = TaskFactory::instance()-> createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, diff --git a/bsp_hosted/InitMission.h b/bsp_hosted/InitMission.h index 5ecf9e41..01c72008 100644 --- a/bsp_hosted/InitMission.h +++ b/bsp_hosted/InitMission.h @@ -1,7 +1,7 @@ #ifndef BSP_LINUX_INITMISSION_H_ #define BSP_LINUX_INITMISSION_H_ -namespace InitMission { +namespace initmission { void initMission(); void initTasks(); }; diff --git a/bsp_hosted/main.cpp b/bsp_hosted/main.cpp index 02d793f9..4fa1eb04 100644 --- a/bsp_hosted/main.cpp +++ b/bsp_hosted/main.cpp @@ -24,7 +24,7 @@ int main(void) << SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; - InitMission::initMission(); + initmission::initMission(); for(;;) { // suspend main thread by sleeping it. diff --git a/bsp_q7s/InitMission.cpp b/bsp_q7s/InitMission.cpp index 2930803e..a3d0c0dc 100644 --- a/bsp_q7s/InitMission.cpp +++ b/bsp_q7s/InitMission.cpp @@ -30,7 +30,7 @@ ServiceInterfaceStream sif::error("ERROR", true, false, true); ObjectManagerIF *objectManager = nullptr; -void InitMission::initMission() { +void initmission::initMission() { sif::info << "Building global objects.." << std::endl; /* Instantiate global object manager and also create all objects */ objectManager = new ObjectManager(ObjectFactory::produce); @@ -41,96 +41,102 @@ void InitMission::initMission() { initTasks(); } -void InitMission::initTasks() { +void initmission::initTasks() { TaskFactory* factory = TaskFactory::instance(); if(factory == nullptr) { /* Should never happen ! */ return; } +#if OBSW_PRINT_MISSED_DEADLINES == 1 + void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline; +#else + void (*missedDeadlineFunc) (void) = nullptr; +#endif /* TMTC Distribution */ PeriodicTaskIF* tmTcDistributor = factory->createPeriodicTask( - "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + "DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); ReturnValue_t result = tmTcDistributor->addComponent( objects::CCSDS_PACKET_DISTRIBUTOR); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR); + initmission::printAddObjectError("CCSDS_DISTRIB", objects::CCSDS_PACKET_DISTRIBUTOR); } result = tmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR); + initmission::printAddObjectError("PUS_PACKET_DISTRIB", objects::PUS_PACKET_DISTRIBUTOR); } result = tmTcDistributor->addComponent(objects::TM_FUNNEL); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL); + initmission::printAddObjectError("TM_FUNNEL", objects::TM_FUNNEL); } /* UDP bridge */ PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( - "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, nullptr); + "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE); + initmission::printAddObjectError("UDP_BRIDGE", objects::UDP_BRIDGE); } PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( - "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); + "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK); + initmission::printAddObjectError("UDP_POLLING", objects::UDP_POLLING_TASK); } /* PUS Services */ PeriodicTaskIF* pusVerification = factory->createPeriodicTask( - "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + "PUS_VERIF", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, missedDeadlineFunc); result = pusVerification->addComponent(objects::PUS_SERVICE_1_VERIFICATION); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION); + initmission::printAddObjectError("PUS_VERIF", objects::PUS_SERVICE_1_VERIFICATION); } PeriodicTaskIF* pusEvents = factory->createPeriodicTask( - "PUS_EVENTS", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + "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("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); + initmission::printAddObjectError("PUS_EVENTS", objects::PUS_SERVICE_5_EVENT_REPORTING); } PeriodicTaskIF* pusHighPrio = factory->createPeriodicTask( - "PUS_HIGH_PRIO", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + "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("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS); + initmission::printAddObjectError("PUS_2", objects::PUS_SERVICE_2_DEVICE_ACCESS); } result = pusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT); + initmission::printAddObjectError("PUS_9", objects::PUS_SERVICE_9_TIME_MGMT); } PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( - "PUS_MED_PRIO", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, nullptr); + "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("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT); + initmission::printAddObjectError("PUS_8", objects::PUS_SERVICE_8_FUNCTION_MGMT); } result = pusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT); + initmission::printAddObjectError("PUS_200", objects::PUS_SERVICE_200_MODE_MGMT); } result = pusMedPrio->addComponent(objects::PUS_SERVICE_20_PARAMETERS); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); + initmission::printAddObjectError("PUS_20", objects::PUS_SERVICE_20_PARAMETERS); } PeriodicTaskIF* pusLowPrio = factory->createPeriodicTask( - "PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1.6, nullptr); + "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("PUS_17", objects::PUS_SERVICE_17_TEST); + initmission::printAddObjectError("PUS_17", objects::PUS_SERVICE_17_TEST); } //TODO: Add handling of missed deadlines /* Polling Sequence Table Default */ FixedTimeslotTaskIF * pollingSequenceTableTaskDefault = factory->createFixedTimeslotTask( - "PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, nullptr); + "PST_TASK_DEFAULT", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 4, 3.0, + missedDeadlineFunc); result = pst::pollingSequenceInitDefault(pollingSequenceTableTaskDefault); if (result != HasReturnvaluesIF::RETURN_OK) { sif::error << "InitMission::initTasks: Creating PST failed!" << std::endl; @@ -139,7 +145,7 @@ void InitMission::initTasks() { #if TE0720 == 0 FixedTimeslotTaskIF* gomSpacePstTask = factory-> createFixedTimeslotTask("GS_PST_TASK", 50, - PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, nullptr); + PeriodicTaskIF::MINIMUM_STACK_SIZE*8, 3.0, missedDeadlineFunc); result = pst::gomspacePstInit(gomSpacePstTask); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "InitMission::initTasks: GomSpace PST initialization failed!" << std::endl; @@ -147,17 +153,17 @@ void InitMission::initTasks() { #endif PeriodicTaskIF* testTask = factory->createPeriodicTask( - "GPIOD_TEST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, nullptr); + "GPIOD_TEST", 60, PeriodicTaskIF::MINIMUM_STACK_SIZE, 1, 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); + initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); } #endif /* OBSW_ADD_TEST_CODE == 1 */ #if TE0720 == 1 && TEST_LIBGPIOD == 1 result = testTask->addComponent(objects::LIBGPIOD_TEST); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); + initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); } #endif /* TE0720 == 1 && TEST_LIBGPIOD == 1 */ diff --git a/bsp_q7s/InitMission.h b/bsp_q7s/InitMission.h index 89d65ada..568b26b5 100644 --- a/bsp_q7s/InitMission.h +++ b/bsp_q7s/InitMission.h @@ -1,7 +1,7 @@ #ifndef BSP_Q7S_INITMISSION_H_ #define BSP_Q7S_INITMISSION_H_ -namespace InitMission { +namespace initmission { void initMission(); void initTasks(); }; diff --git a/bsp_q7s/main.cpp b/bsp_q7s/main.cpp index 49416ae2..b087e315 100644 --- a/bsp_q7s/main.cpp +++ b/bsp_q7s/main.cpp @@ -13,15 +13,15 @@ int main(void) { std::cout << "-- EIVE OBSW --" << std::endl; - std::cout << "-- Compiled for Linux " << " --" << std::endl; + std::cout << "-- Compiled for Linux (Xiphos Q7S) --" << std::endl; std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; - InitMission::initMission(); + initmission::initMission(); for(;;) { - // suspend main thread by sleeping it. + /* Suspend main thread by sleeping it. */ TaskFactory::delayTask(5000); } } diff --git a/bsp_rpi/InitMission.cpp b/bsp_rpi/InitMission.cpp index f3dc47ed..c31cbe22 100644 --- a/bsp_rpi/InitMission.cpp +++ b/bsp_rpi/InitMission.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -24,7 +24,7 @@ ServiceInterfaceStream sif::error("ERROR"); ObjectManagerIF *objectManager = nullptr; -void InitMission::initMission() { +void initmission::initMission() { sif::info << "Building global objects.." << std::endl; /* Instantiate global object manager and also create all objects */ objectManager = new ObjectManager(ObjectFactory::produce); @@ -35,11 +35,21 @@ void InitMission::initMission() { initTasks(); } -void InitMission::initTasks(){ +void initmission::initTasks() { + TaskFactory* factory = TaskFactory::instance(); + if(factory == nullptr) { + /* Should never happen ! */ + return; + } +#if OBSW_PRINT_MISSED_DEADLINES == 1 + void (*missedDeadlineFunc) (void) = TaskFactory::printMissedDeadline; +#else + void (*missedDeadlineFunc) (void) = nullptr; +#endif + /* TMTC Distribution */ - PeriodicTaskIF* tmTcDistributor = TaskFactory::instance()-> - createPeriodicTask("DIST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.100, nullptr); + 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){ @@ -55,95 +65,85 @@ void InitMission::initTasks(){ } /* UDP bridge */ - PeriodicTaskIF* udpBridgeTask = TaskFactory::instance()->createPeriodicTask( - "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.2, nullptr); + PeriodicTaskIF* udpBridgeTask = factory->createPeriodicTask( + "UDP_UNIX_BRIDGE", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.2, missedDeadlineFunc); result = udpBridgeTask->addComponent(objects::UDP_BRIDGE); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Unix Bridge failed" << std::endl; } - PeriodicTaskIF* udpPollingTask = TaskFactory::instance()-> - createPeriodicTask("UDP_POLLING", 80, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, nullptr); + PeriodicTaskIF* udpPollingTask = factory->createPeriodicTask( + "UDP_POLLING", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE, 2.0, missedDeadlineFunc); result = udpPollingTask->addComponent(objects::UDP_POLLING_TASK); if(result != HasReturnvaluesIF::RETURN_OK) { sif::error << "Add component UDP Polling failed" << std::endl; } /* PUS Services */ - PeriodicTaskIF* pusVerification = TaskFactory::instance()-> - createPeriodicTask("PUS_VERIF", 40, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + 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 = TaskFactory::instance()-> - createPeriodicTask("PUS_EVENTS", 60, - PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.200, nullptr); + 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); + initmission::printAddObjectError("PUS5", objects::PUS_SERVICE_5_EVENT_REPORTING); } - PeriodicTaskIF* pusHighPrio = TaskFactory::instance()-> - createPeriodicTask("PUS_HIGH_PRIO", 50, - PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.200, nullptr); + 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); + 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); + initmission::printAddObjectError("PUS9", objects::PUS_SERVICE_9_TIME_MGMT); } - PeriodicTaskIF* pusMedPrio = TaskFactory::instance()-> - createPeriodicTask("PUS_HIGH_PRIO", 40, - PeriodicTaskIF::MINIMUM_STACK_SIZE, - 0.8, nullptr); + PeriodicTaskIF* pusMedPrio = factory->createPeriodicTask( + "PUS_HIGH_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); + 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); + 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); + initmission::printAddObjectError("PUS20", objects::PUS_SERVICE_20_PARAMETERS); } - PeriodicTaskIF* pusLowPrio = TaskFactory::instance()-> - createPeriodicTask("PUS_LOW_PRIO", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 1.6, nullptr); + 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); + initmission::printAddObjectError("PUS17", objects::PUS_SERVICE_17_TEST); } - PeriodicTaskIF* testTask = TaskFactory::instance()-> - createPeriodicTask("SPI_TEST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE, - 2.0, nullptr); + 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); + initmission::printAddObjectError("TEST_TASK", objects::TEST_TASK); } #endif /* OBSW_ADD_TEST_CODE == 1 */ #if RPI_ADD_SPI_TEST == 1 result = testTask->addComponent(objects::SPI_TEST); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("SPI_TEST", objects::SPI_TEST); + initmission::printAddObjectError("SPI_TEST", objects::SPI_TEST); } #endif /* RPI_ADD_SPI_TEST == 1 */ #if RPI_ADD_GPIO_TEST == 1 result = testTask->addComponent(objects::LIBGPIOD_TEST); if(result != HasReturnvaluesIF::RETURN_OK) { - InitMission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); + initmission::printAddObjectError("GPIOD_TEST", objects::LIBGPIOD_TEST); } #endif /* RPI_ADD_GPIO_TEST == 1 */ diff --git a/bsp_rpi/InitMission.h b/bsp_rpi/InitMission.h index 5ecf9e41..01c72008 100644 --- a/bsp_rpi/InitMission.h +++ b/bsp_rpi/InitMission.h @@ -1,7 +1,7 @@ #ifndef BSP_LINUX_INITMISSION_H_ #define BSP_LINUX_INITMISSION_H_ -namespace InitMission { +namespace initmission { void initMission(); void initTasks(); }; diff --git a/bsp_rpi/ObjectFactory.cpp b/bsp_rpi/ObjectFactory.cpp index 458456c8..01552be8 100644 --- a/bsp_rpi/ObjectFactory.cpp +++ b/bsp_rpi/ObjectFactory.cpp @@ -1,5 +1,4 @@ #include "ObjectFactory.h" -#include #include #include @@ -8,18 +7,21 @@ #include #include +#include +#include +#include +#include + +#include +#include + #include #include #include #include #include #include -#include -#include -#include - -#include -#include +#include void Factory::setStaticFrameworkObjectIds() { PusServiceBase::packetSource = objects::PUS_PACKET_DISTRIBUTOR; @@ -52,7 +54,7 @@ void ObjectFactory::produce(){ new LinuxLibgpioIF(objects::GPIO_IF); #if RPI_ADD_SPI_TEST == 1 - new SpiTest(objects::SPI_TEST); + new SpiTestClass(objects::SPI_TEST); #endif #if RPI_LOOPBACK_TEST_GPIO == 1 diff --git a/bsp_rpi/boardtest/CMakeLists.txt b/bsp_rpi/boardtest/CMakeLists.txt index 768fc52f..0599b73f 100644 --- a/bsp_rpi/boardtest/CMakeLists.txt +++ b/bsp_rpi/boardtest/CMakeLists.txt @@ -1,5 +1,4 @@ target_sources(${TARGET_NAME} PRIVATE - SpiTest.cpp ) diff --git a/bsp_rpi/boardtest/SpiTest.cpp b/bsp_rpi/boardtest/SpiTest.cpp deleted file mode 100644 index a78d0171..00000000 --- a/bsp_rpi/boardtest/SpiTest.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "SpiTest.h" - -#include - -#include -#include - - - -SpiTest::SpiTest(object_id_t objectId): SystemObject(objectId) { - sif::info << "Setting up Raspberry Pi WiringPi library." << std::endl; -// wiringPiSetupGpio(); - -// pinMode(SS_MGM_0_LIS3, OUTPUT); -// pinMode(SS_MGM_1_RM, OUTPUT); -// pinMode(SS_GYRO_0_ADIS, OUTPUT); -// pinMode(SS_GYRO_1_L3G, OUTPUT); -// pinMode(SS_GYRO_2_L3G, OUTPUT); -// pinMode(SS_MGM_2_LIS3, OUTPUT); -// pinMode(SS_MGM_3_RM, OUTPUT); -// -// digitalWrite(SS_MGM_0_LIS3, HIGH); -// digitalWrite(SS_MGM_1_RM, HIGH); -// digitalWrite(SS_GYRO_0_ADIS, HIGH); -// digitalWrite(SS_GYRO_1_L3G, HIGH); -// digitalWrite(SS_GYRO_2_L3G, HIGH); -// digitalWrite(SS_MGM_2_LIS3, HIGH); -// digitalWrite(SS_MGM_3_RM, HIGH); - - int spiFd = open(spiDeviceName.c_str(), O_RDWR); - if (spiFd < 0){ - sif::error << "Could not open SPI device!" << std::endl; - } - - spiMode = SPI_MODE_3; - int ret = ioctl(spiFd, SPI_IOC_WR_MODE, &spiMode); - if(ret < 0) { - sif::error << "Could not set write mode!" << std::endl; - } - - /* Datenrate setzen */ - ret = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &spiSpeed); - if(ret < 0) { - sif::error << "Could not SPI speed!" << std::endl; - } -} - -ReturnValue_t SpiTest::performOperation(uint8_t opCode) { - if(oneShot) { - - } - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t SpiTest::initialize() { - //transferHandle.rx_buf = reinterpret_cast<__u64>(receiveBuffer); - //transferHandle.tx_buf = reinterpret_cast<__u64>(sendBuffer); - //transferHandle.speed_hz = 976000; - //transferHandle.len = 2; - return HasReturnvaluesIF::RETURN_OK; -} diff --git a/bsp_rpi/boardtest/SpiTest.h b/bsp_rpi/boardtest/SpiTest.h deleted file mode 100644 index b4f37fe2..00000000 --- a/bsp_rpi/boardtest/SpiTest.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef BSP_LINUX_TEST_SPITEST_H_ -#define BSP_LINUX_TEST_SPITEST_H_ - -#include -#include -#include -#include - -class SpiTest: - public SystemObject, - public ExecutableObjectIF { -public: - SpiTest(object_id_t objectId); - - ReturnValue_t performOperation(uint8_t opCode) override; - ReturnValue_t initialize() override; -private: - // These chip selects (BCM number) will be pulled high if not used - // ACS board specific. - enum SpiChipSelects { - SS_MGM_0_LIS3 = 0, //!< MGM 0, LIS3MDLTR, U6, A side - SS_MGM_1_RM = 1, //!< MGM 1, RM3100, U7, A side - SS_GYRO_0_ADIS = 2, //!< Gyro 0, ADIS16485, U3, A side - SS_GYRO_1_L3G = 3, //!< Gyro 1, L3GD20H, U4, A side - SS_GYRO_2_L3G = 4, //!< Gyro 2, L3GD20h, U5, B side - SS_MGM_2_LIS3 = 17, //!< MGM 2, LIS3MDLTR, U8, B side - SS_MGM_3_RM = 27, //!< MGM 3, RM3100, U9, B side - }; - - const std::string spiDeviceName = "/dev/spidev0.0"; - int spiFd = 0; - - uint8_t spiMode = SPI_MODE_3; - uint32_t spiSpeed = 976000; - - uint8_t sendBuffer[32]; - uint8_t receiveBuffer[32]; - struct spi_ioc_transfer transferHandle; - - bool oneShot = true; - -}; - - -#endif /* BSP_LINUX_TEST_SPITEST_H_ */ diff --git a/bsp_rpi/main.cpp b/bsp_rpi/main.cpp index 5f6be8db..e1f8d9f6 100644 --- a/bsp_rpi/main.cpp +++ b/bsp_rpi/main.cpp @@ -1,12 +1,10 @@ #include "InitMission.h" - #include + #include #include -#include - /** * @brief This is the main program for the target hardware. * @return @@ -14,15 +12,15 @@ int main(void) { std::cout << "-- EIVE OBSW --" << std::endl; - std::cout << "-- Compiled for Linux " << " --" << std::endl; + std::cout << "-- Compiled for Linux (Raspberry Pi) --" << std::endl; std::cout << "-- Software version " << SW_NAME << " v" << SW_VERSION << "." << SW_SUBVERSION << "." << SW_SUBSUBVERSION << " -- " << std::endl; std::cout << "-- " << __DATE__ << " " << __TIME__ << " --" << std::endl; - InitMission::initMission(); + initmission::initMission(); for(;;) { - // suspend main thread by sleeping it. + /* suspend main thread by sleeping it. */ TaskFactory::delayTask(5000); } } diff --git a/fsfw b/fsfw index c2839825..14437582 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit c28398257b68facbabb19d7228b045f1388305df +Subproject commit 144375827441b80a601579fe4395e3bbc19df92c diff --git a/fsfwconfig/OBSWConfig.h b/fsfwconfig/OBSWConfig.h index 5f841062..d4220b9e 100644 --- a/fsfwconfig/OBSWConfig.h +++ b/fsfwconfig/OBSWConfig.h @@ -13,16 +13,17 @@ /* These defines should be disabled for mission code but are useful for debugging. */ -#define OBSW_VERBOSE_LEVEL 1 -#define OBSW_ADD_TEST_CODE 1 -#define TEST_LIBGPIOD 0 +#define OBSW_VERBOSE_LEVEL 1 +#define OBSW_PRINT_MISSED_DEADLINES 1 +#define OBSW_ADD_TEST_CODE 1 +#define TEST_LIBGPIOD 0 -#define TE0720 0 +#define TE0720 0 -#define P60DOCK_DEBUG 0 -#define PDU1_DEBUG 0 -#define PDU2_DEBUG 0 -#define ACU_DEBUG 1 +#define P60DOCK_DEBUG 0 +#define PDU1_DEBUG 0 +#define PDU2_DEBUG 0 +#define ACU_DEBUG 1 #ifdef __cplusplus diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index 5dec5581..d88e5676 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -3,6 +3,7 @@ #include #include #include +#include LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie): @@ -75,6 +76,22 @@ ReturnValue_t LibgpiodTest::performOneShotAction() { << std::endl; return HasReturnvaluesIF::RETURN_OK; } + + result = gpioInterface->pullLow(gpioIds::TEST_ID_0); + if(result == HasReturnvaluesIF::RETURN_OK) { + sif::info << "LibgpiodTest::performOneShotAction:" + "GPIO pulled low successfully for loopback test" << std::endl; + } + result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState); + if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 0) { + sif::info << "LibgpiodTest::performOneShotAction:" + "GPIO state read successfully and is low" << std::endl; + } + else { + sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not low!" + << std::endl; + return HasReturnvaluesIF::RETURN_OK; + } break; } } diff --git a/mission/utility/InitMission.h b/mission/utility/InitMission.h index 93ebc9bc..b4a83a1e 100644 --- a/mission/utility/InitMission.h +++ b/mission/utility/InitMission.h @@ -4,7 +4,7 @@ #include #include -namespace InitMission { +namespace initmission { void printAddObjectError(const char* name, object_id_t objectId) { #if FSFW_CPP_OSTREAM_ENABLED == 1 @@ -14,7 +14,7 @@ void printAddObjectError(const char* name, object_id_t objectId) { #else sif::printError("InitMission::printAddError: Adding object %s with object ID 0x%08x failed!\n" , name, objectId); -#endif +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ } } diff --git a/test/testtasks/TestTask.cpp b/test/testtasks/TestTask.cpp index e6fb8457..9a5018c5 100644 --- a/test/testtasks/TestTask.cpp +++ b/test/testtasks/TestTask.cpp @@ -8,14 +8,9 @@ #include #include -bool TestTask::oneShotAction = true; -MutexIF* TestTask::testLock = nullptr; TestTask::TestTask(object_id_t objectId_): SystemObject(objectId_), testMode(testModes::A) { - if(testLock == nullptr) { - testLock = MutexFactory::instance()->createMutex(); - } IPCStore = objectManager->get(objects::IPC_STORE); } @@ -24,19 +19,17 @@ TestTask::~TestTask() { ReturnValue_t TestTask::performOperation(uint8_t operationCode) { ReturnValue_t result = RETURN_OK; - sif::info << "Hallo EIVE!" << std::endl; - testLock ->lockMutex(MutexIF::TimeoutType::WAITING, 20); + if(oneShotAction) { - // Add code here which should only be run once + /* Add code here which should only be run once */ performOneShotAction(); oneShotAction = false; } - testLock->unlockMutex(); - // Add code here which should only be run once per performOperation + /* Add code here which should only be run once per performOperation */ performPeriodicAction(); - // Add code here which should only be run on alternating cycles. + /* Add code here which should only be run on alternating cycles. */ if(testMode == testModes::A) { performActionA(); testMode = testModes::B; @@ -49,7 +42,7 @@ ReturnValue_t TestTask::performOperation(uint8_t operationCode) { } ReturnValue_t TestTask::performOneShotAction() { - // Everything here will only be performed once. + /* Everything here will only be performed once. */ return HasReturnvaluesIF::RETURN_OK; } @@ -61,12 +54,12 @@ ReturnValue_t TestTask::performPeriodicAction() { ReturnValue_t TestTask::performActionA() { ReturnValue_t result = RETURN_OK; - // Add periodically executed code here + /* Add periodically executed code here */ return result; } ReturnValue_t TestTask::performActionB() { ReturnValue_t result = RETURN_OK; - // Add periodically executed code here + /* Add periodically executed code here */ return result; } diff --git a/test/testtasks/TestTask.h b/test/testtasks/TestTask.h index 24e62af1..fef1ff0e 100644 --- a/test/testtasks/TestTask.h +++ b/test/testtasks/TestTask.h @@ -48,8 +48,7 @@ protected: private: // Actually, to be really thread-safe, a mutex should be used as well // Let's keep it simple for now. - static bool oneShotAction; - static MutexIF* testLock; + bool oneShotAction = true; StorageManagerIF* IPCStore; }; -- 2.43.0 From a2e6634208d04589058fb3adc3dd999a644edd32 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Mon, 22 Feb 2021 18:48:58 +0100 Subject: [PATCH 19/34] fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 14437582..1ccfb747 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 144375827441b80a601579fe4395e3bbc19df92c +Subproject commit 1ccfb74709ba0ce6d469eed3df1584dbcb444321 -- 2.43.0 From 3550fb6ca731c49b1d6c2e7a87e594d1a8bd52e1 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 11:31:50 +0100 Subject: [PATCH 20/34] spi com if almost finished --- fsfw | 2 +- linux/gpio/LinuxLibgpioIF.h | 3 +- linux/gpio/gpioDefinitions.h | 2 + linux/i2c/I2cComIF.cpp | 26 ++- linux/i2c/I2cComIF.h | 4 +- linux/spi/CMakeLists.txt | 2 + linux/spi/SpiComIF.cpp | 303 ++++++++++++++++++++++++++++++++++ linux/spi/SpiComIF.h | 61 +++++++ linux/spi/SpiCookie.cpp | 99 +++++++++++ linux/spi/SpiCookie.h | 113 +++++++++++++ linux/spi/spiDefinitions.h | 15 ++ linux/utility/errorhandling.h | 30 ++++ 12 files changed, 649 insertions(+), 11 deletions(-) create mode 100644 linux/spi/SpiComIF.cpp create mode 100644 linux/spi/SpiComIF.h create mode 100644 linux/spi/SpiCookie.cpp create mode 100644 linux/spi/SpiCookie.h create mode 100644 linux/spi/spiDefinitions.h create mode 100644 linux/utility/errorhandling.h diff --git a/fsfw b/fsfw index 1ccfb747..a3d245f5 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 1ccfb74709ba0ce6d469eed3df1584dbcb444321 +Subproject commit a3d245f5a030c9450c516552283d26da2c799301 diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index a849bb09..03c78fdb 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -40,8 +40,7 @@ private: * @param gpioId The GPIO ID of the GPIO to drive. * @param logiclevel The logic level to set. O or 1. */ - ReturnValue_t driveGpio(gpioId_t gpioId, - unsigned int logiclevel); + ReturnValue_t driveGpio(gpioId_t gpioId, unsigned int logiclevel); /** * @brief This function checks if GPIOs are already registered and whether diff --git a/linux/gpio/gpioDefinitions.h b/linux/gpio/gpioDefinitions.h index ce26ec78..28ad1239 100644 --- a/linux/gpio/gpioDefinitions.h +++ b/linux/gpio/gpioDefinitions.h @@ -11,6 +11,8 @@ enum Direction { IN = 0, OUT = 1 }; + +static constexpr gpioId_t NO_GPIO = -1; } /** diff --git a/linux/i2c/I2cComIF.cpp b/linux/i2c/I2cComIF.cpp index ef77baa1..8e372b14 100644 --- a/linux/i2c/I2cComIF.cpp +++ b/linux/i2c/I2cComIF.cpp @@ -181,16 +181,30 @@ ReturnValue_t I2cComIF::openDevice(std::string deviceFile, address_t i2cAddress, int* fileDescriptor) { *fileDescriptor = open(deviceFile.c_str(), O_RDWR); if (*fileDescriptor < 0) { - sif::error << "I2cComIF: Opening i2c device failed with error code " - << errno << ". Error description: " << strerror(errno) - << std::endl; +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "I2cComIF: Opening I2C device failed with error code " << errno << "." << + std::endl; + sif::warning << "Error description: " << strerror(errno) << std::endl; +#else + sif::printWarning("I2cComIF: Opening I2C device failed with error code %d.\n"); + sif::printWarning("Error description: %s\n", strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ return HasReturnvaluesIF::RETURN_FAILED; } if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) { - sif::error << "I2cComIF: Specifying target device failed with error " - << "code " << errno << ". Error description " - << strerror(errno) << std::endl; +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "I2cComIF: Specifying target device failed with error code " << errno << "." + << std::endl; + sif::warning << "Error description " << strerror(errno) << std::endl; +#else + sif::printWarning("I2cComIF: Specifying target device failed with error code %d.\n"); + sif::printWarning("Error description: %s\n", strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ return HasReturnvaluesIF::RETURN_FAILED; } return HasReturnvaluesIF::RETURN_OK; diff --git a/linux/i2c/I2cComIF.h b/linux/i2c/I2cComIF.h index f5d07ac1..3529bde7 100644 --- a/linux/i2c/I2cComIF.h +++ b/linux/i2c/I2cComIF.h @@ -45,8 +45,8 @@ private: I2cDeviceMapIter i2cDeviceMapIter; /** - * @brief This function opens an i2c device and binds the opened file - * to a specific i2c address. + * @brief This function opens an I2C device and binds the opened file + * to a specific I2C address. * @param deviceFile The name of the device file. E.g. i2c-0 * @param i2cAddress The address of the i2c slave device. * @param fileDescriptor Pointer to device descriptor. diff --git a/linux/spi/CMakeLists.txt b/linux/spi/CMakeLists.txt index 45a7edcc..cb1c9277 100644 --- a/linux/spi/CMakeLists.txt +++ b/linux/spi/CMakeLists.txt @@ -1,4 +1,6 @@ target_sources(${TARGET_NAME} PUBLIC + SpiComIF.cpp + SpiCookie.cpp ) diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp new file mode 100644 index 00000000..bdb0c705 --- /dev/null +++ b/linux/spi/SpiComIF.cpp @@ -0,0 +1,303 @@ +#include "SpiComIF.h" +#include "spiDefinitions.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(objectId), + gpioComIF(gpioComIF) { + if(gpioComIF == nullptr) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "SpiComIF::SpiComIF: GPIO communication interface invalid!" << std::endl; +#else + sif::printError("SpiComIF::SpiComIF: GPIO communication interface invalid!\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + } + + spiMutex = MutexFactory::instance()->createMutex(); +} + +ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { + SpiCookie* spiCookie = dynamic_cast(cookie); + if(spiCookie == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + address_t spiAddress = spiCookie->getSpiAddress(); + + auto iter = spiDeviceMap.find(spiAddress); + if(iter == spiDeviceMap.end()) { + size_t bufferSize = spiCookie->getMaxBufferSize(); + SpiInstance spiInstance = {std::vector(bufferSize)}; + auto statusPair = spiDeviceMap.emplace(spiAddress, spiInstance); + if (not statusPair.second) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "SpiComIF::initializeInterface: Failed to insert device with address " << + spiAddress << "to SPI device map" << std::endl; +#else + sif::printError("SpiComIF::initializeInterface: Failed to insert device with address " + "%lu to SPI device map\n", static_cast(spiAddress)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return HasReturnvaluesIF::RETURN_FAILED; + } + /* Now we emplaced the read buffer in the map, we still need to assign that location + to the SPI driver transfer struct */ + spiCookie->assignReadBuffer(statusPair.first->second.replyBuffer.data()); + } + else { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "SpiComIF::initializeInterface: SPI address already exists!" << std::endl; +#else + sif::printError("SpiComIF::initializeInterface: SPI address already exists!\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return HasReturnvaluesIF::RETURN_FAILED; + } + + gpioId_t gpioId = spiCookie->getChipSelectPin(); + if(gpioId != gpio::NO_GPIO) { + gpioComIF->pullHigh(gpioId); + } + + size_t spiSpeed = 0; + spi::SpiMode spiMode = spi::SpiMode::MODE_0; + + SpiCookie::UncommonParameters params; + spiCookie->getSpiParameters(spiMode, spiSpeed, ¶ms); + + int fileDescriptor = 0; + ReturnValue_t result = openDevice(spiCookie->getSpiDevice(), &fileDescriptor); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, spiSpeed); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initializeInterface: Setting SPI mode failed!"); + } + + retval = ioctl(fileDescriptor, SPI_IOC_WR_MAX_SPEED_HZ, spiSpeed); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initializeInterface: Setting SPI speed failed!"); + } + + /* These flags are rather uncommon */ + if(params.threeWireSpi or params.noCs or params.csHigh) { + uint32_t currentMode = 0; + retval = ioctl(fileDescriptor, SPI_IOC_RD_MODE32, ¤tMode); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initialiezInterface: Could not read full mode!"); + } + + if(params.threeWireSpi) { + currentMode |= SPI_3WIRE; + } + if(params.noCs) { + /* Some drivers like the Raspberry Pi ignore this flag in any case */ + currentMode |= SPI_NO_CS; + } + if(params.csHigh) { + currentMode |= SPI_CS_HIGH; + } + /* Write adapted mode */ + retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE32, currentMode); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initialiezInterface: Could not write full mode!"); + } + } + if(params.lsbFirst) { + retval = ioctl(fileDescriptor, SPI_IOC_WR_LSB_FIRST, true); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initializeInterface: Setting LSB first failed"); + } + } + if(params.bitsPerWord != 8) { + retval = ioctl(fileDescriptor, SPI_IOC_WR_BITS_PER_WORD, params.bitsPerWord); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::initializeInterface: " + "Could not write bits per word!"); + } + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) { + SpiCookie* spiCookie = dynamic_cast(cookie); + if(spiCookie == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + if(sendLen > spiCookie->getMaxBufferSize()) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "SpiComIF::sendMessage: Too much data sent, send length" << sendLen << + "larger than maximum buffer length" << spiCookie->getMaxBufferSize() << std::endl; +#else + sif::printWarning("SpiComIF::sendMessage: Too much data sent, send length %lu larger " + "than maximum buffer length %lu!\n", static_cast(sendLen), + static_cast(spiCookie->getMaxBufferSize())); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return DeviceCommunicationIF::TOO_MUCH_DATA; + } + + spiCookie->assignWriteBuffer(sendData); + spiCookie->assignTransferSize(sendLen); + int fileDescriptor = 0; + std::string device = spiCookie->getSpiDevice(); + ReturnValue_t result = openDevice(device, &fileDescriptor); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + bool fullDuplex = spiCookie->isFullDuplex(); + int retval = 0; + + gpioId_t gpioId = spiCookie->getChipSelectPin(); + MutexHelper(spiMutex, timeoutType, timeoutMs); + if(gpioId != gpio::NO_GPIO) { + /* For now, no support for active high given */ + gpioComIF->pullLow(gpioId); + } + + if(fullDuplex) { + /* Initiate a full duplex SPI transfer. */ + retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle()); + if(retval != 0) { + utility::handleIoctlError("SpiComIF::sendMessage: ioctl error."); + /* TODO: Better returnvalue */ + return HasReturnvaluesIF::RETURN_FAILED; + } + } + else { + /* We write with a blocking transfer here */ + if (write(fileDescriptor, sendData, sendLen) != static_cast(sendLen)) { + sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << + std::endl; + /* TODO: Better returnvalue */ + return HasReturnvaluesIF::RETURN_FAILED; + } + } + + if(gpioId != gpio::NO_GPIO) { + gpioComIF->pullHigh(gpioId); + } + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::getSendSuccess(CookieIF *cookie) { + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) { + SpiCookie* spiCookie = dynamic_cast(cookie); + if(spiCookie == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + bool fullDuplex = spiCookie->isFullDuplex(); + if(fullDuplex) { + return HasReturnvaluesIF::RETURN_OK; + } + + std::string device = spiCookie->getSpiDevice(); + int fileDescriptor = 0; + ReturnValue_t result = openDevice(device, &fileDescriptor); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + uint8_t* rxBuf = nullptr; + size_t readSize = spiCookie->getCurrentTransferSize(); + result = getReadBuffer(spiCookie->getSpiAddress(), &rxBuf); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + gpioId_t gpioId = spiCookie->getChipSelectPin(); + MutexHelper(spiMutex, timeoutType, timeoutMs); + if(gpioId != gpio::NO_GPIO) { + gpioComIF->pullLow(gpioId); + } + + if(read(fileDescriptor, rxBuf, readSize) != static_cast(readSize)) { + sif::warning << "SpiComIF::sendMessage: Half-Duplex read operation failed!" << std::endl; + if(gpioId != gpio::NO_GPIO) { + gpioComIF->pullHigh(gpioId); + } + } + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t *size) { + SpiCookie* spiCookie = dynamic_cast(cookie); + if(spiCookie == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + uint8_t* rxBuf = nullptr; + ReturnValue_t result = getReadBuffer(spiCookie->getSpiAddress(), &rxBuf); + if(result != HasReturnvaluesIF::RETURN_OK) { + return result; + } + + *buffer = rxBuf; + *size = spiCookie->getCurrentTransferSize(); + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::openDevice(std::string deviceFile, int *fileDescriptor, bool nonBlocking) { + if(fileDescriptor == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + int flags = O_RDWR; + if(nonBlocking) { + flags |= O_NONBLOCK; + } + *fileDescriptor = open(deviceFile.c_str(), flags); + if (*fileDescriptor < 0) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "SpiComIF: Opening SPI device failed with error code " << errno << "." << + std::endl; + sif::warning << "Error description: " << strerror(errno) << std::endl; +#else + sif::printError("SpiComIF: Opening SPI device failed with error code %d.\n"); + sif::printWarning("Error description: %s\n", strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + return HasReturnvaluesIF::RETURN_FAILED; + } + + return HasReturnvaluesIF::RETURN_OK; +} + +ReturnValue_t SpiComIF::getReadBuffer(address_t spiAddress, uint8_t** buffer) { + if(buffer == nullptr) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + auto iter = spiDeviceMap.find(spiAddress); + if(iter == spiDeviceMap.end()) { + return HasReturnvaluesIF::RETURN_FAILED; + } + + *buffer = iter->second.replyBuffer.data(); + return HasReturnvaluesIF::RETURN_OK; +} diff --git a/linux/spi/SpiComIF.h b/linux/spi/SpiComIF.h new file mode 100644 index 00000000..4009eed9 --- /dev/null +++ b/linux/spi/SpiComIF.h @@ -0,0 +1,61 @@ +#ifndef LINUX_SPI_SPICOMIF_H_ +#define LINUX_SPI_SPICOMIF_H_ + +#include +#include +#include + +#include +#include + +/** + * @brief Encapsulates access to linux SPI driver for FSFW objects + * @details + * Right now, only full-duplex SPI is supported. + * @author R. Mueller + */ +class SpiComIF: public DeviceCommunicationIF, public SystemObject { +public: + SpiComIF(object_id_t objectId, GpioIF* gpioComIF); + + ReturnValue_t initializeInterface(CookieIF * cookie) override; + ReturnValue_t sendMessage(CookieIF *cookie,const uint8_t *sendData, + size_t sendLen) override; + ReturnValue_t getSendSuccess(CookieIF *cookie) override; + ReturnValue_t requestReceiveMessage(CookieIF *cookie, + size_t requestLen) override; + ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, + size_t *size) override; +private: + + struct SpiInstance { + std::vector replyBuffer; + }; + + GpioIF* gpioComIF = nullptr; + + MutexIF* spiMutex = nullptr; + MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING; + uint32_t timeoutMs = 20; + + using SpiDeviceMap = std::unordered_map; + using SpiDeviceMapIter = SpiDeviceMap::iterator; + + SpiDeviceMap spiDeviceMap; + + /** + * @brief This function opens an SPI device and binds the opened file + * to a specific SPI address. + * @param deviceFile The name of the device file. E.g. spi-0 + * @param i2cAddress The address of the SPI slave device. + * @param fileDescriptor Pointer to device descriptor. + * @return RETURN_OK if successful, otherwise RETURN_FAILED. + */ + ReturnValue_t openDevice(std::string deviceFile, int* fileDescriptor, bool nonBlocking = false); + + ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); +}; + + + +#endif /* LINUX_SPI_SPICOMIF_H_ */ diff --git a/linux/spi/SpiCookie.cpp b/linux/spi/SpiCookie.cpp new file mode 100644 index 00000000..f0b81f67 --- /dev/null +++ b/linux/spi/SpiCookie.cpp @@ -0,0 +1,99 @@ +#include "SpiCookie.h" + +SpiCookie::SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, + const size_t maxSize, spi::SpiMode spiMode, uint32_t spiSpeed): spiAddress(spiAddress), + chipSelectPin(chipSelect), spiDevice(spiDev), maxSize(maxSize), spiMode(spiMode), + spiSpeed(spiSpeed) { +} + +SpiCookie::SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxSize, + spi::SpiMode spiMode, uint32_t spiSpeed): + SpiCookie(spiAddress, gpio::NO_GPIO, spiDev, maxSize, spiMode, spiSpeed) { +} + +void SpiCookie::getSpiParameters(spi::SpiMode& spiMode, uint32_t& spiSpeed, + UncommonParameters* parameters) const { + spiMode = this->spiMode; + spiSpeed = this->spiSpeed; + + if(parameters != nullptr) { + parameters->threeWireSpi = uncommonParameters.threeWireSpi; + parameters->lsbFirst = uncommonParameters.lsbFirst; + parameters->noCs = uncommonParameters.noCs; + parameters->bitsPerWord = uncommonParameters.bitsPerWord; + parameters->csHigh = uncommonParameters.csHigh; + } +} + +gpioId_t SpiCookie::getChipSelectPin() const { + return chipSelectPin; +} + +size_t SpiCookie::getMaxBufferSize() const { + return maxSize; +} + +address_t SpiCookie::getSpiAddress() const { + return spiAddress; +} + +std::string SpiCookie::getSpiDevice() const { + return spiDevice; +} + +void SpiCookie::setThreeWireSpi(bool enable) { + uncommonParameters.threeWireSpi = enable; +} + +void SpiCookie::setLsbFirst(bool enable) { + uncommonParameters.lsbFirst = enable; +} + +void SpiCookie::setNoCs(bool enable) { + uncommonParameters.noCs = enable; +} + +void SpiCookie::setBitsPerWord(uint8_t bitsPerWord) { + uncommonParameters.bitsPerWord = bitsPerWord; +} + +void SpiCookie::setCsHigh(bool enable) { + uncommonParameters.csHigh = enable; +} + +void SpiCookie::activateCsDeselect(bool deselectCs, uint16_t delayUsecs) { + spiTransferStruct.cs_change = deselectCs; + spiTransferStruct.delay_usecs = delayUsecs; +} + +void SpiCookie::assignReadBuffer(uint8_t* rx) { + if(rx != nullptr) { + spiTransferStruct.rx_buf = reinterpret_cast<__u64>(rx); + } +} + +void SpiCookie::assignWriteBuffer(const uint8_t* tx) { + if(tx != nullptr) { + spiTransferStruct.tx_buf = reinterpret_cast<__u64>(tx); + } +} + +spi_ioc_transfer* SpiCookie::getTransferStructHandle() { + return &spiTransferStruct; +} + +void SpiCookie::setFullOrHalfDuplex(bool halfDuplex) { + this->halfDuplex = halfDuplex; +} + +bool SpiCookie::isFullDuplex() const { + return not this->halfDuplex; +} + +void SpiCookie::assignTransferSize(size_t transferSize) { + spiTransferStruct.len = transferSize; +} + +size_t SpiCookie::getCurrentTransferSize() const { + return spiTransferStruct.len; +} diff --git a/linux/spi/SpiCookie.h b/linux/spi/SpiCookie.h new file mode 100644 index 00000000..91d42a3c --- /dev/null +++ b/linux/spi/SpiCookie.h @@ -0,0 +1,113 @@ +#ifndef LINUX_SPI_SPICOOKIE_H_ +#define LINUX_SPI_SPICOOKIE_H_ + +#include "spiDefinitions.h" +#include +#include +#include + +class SpiCookie: public CookieIF { +public: + + /** + * Each SPI device will have a corresponding cookie. The cookie is used by the communication + * interface and contains device specific information like the largest expected size to be + * sent and received and the GPIO pin used to toggle the SPI slave select pin. + * @param spiAddress + * @param chipSelect Chip select. gpio::NO_GPIO can be used for hardware slave selects. + * @param spiDev + * @param maxSize + */ + SpiCookie(address_t spiAddress, gpioId_t chipSelect, std::string spiDev, + const size_t maxReplySize, spi::SpiMode spiMode, uint32_t spiSpeed); + + /** + * Like constructor above, but without a dedicated GPIO CS. Can be used for hardware + * slave select or if CS logic is performed with decoders. + */ + SpiCookie(address_t spiAddress, std::string spiDev, const size_t maxReplySize, + spi::SpiMode spiMode, uint32_t spiSpeed); + + address_t getSpiAddress() const; + std::string getSpiDevice() const; + gpioId_t getChipSelectPin() const; + size_t getMaxBufferSize() const; + /** + * True if SPI transfers should be performed in full duplex mode + * @return + */ + bool isFullDuplex() const; + + /** + * Set transfer type to full duplex or half duplex. Full duplex is the default setting, + * ressembling common SPI hardware implementation with shift registers, where read and writes + * happen simultaneosly. + * @param fullDuplex + */ + void setFullOrHalfDuplex(bool halfDuplex); + + /** + * This needs to be called to specify where the SPI driver writes to or reads from. + * @param readLocation + * @param writeLocation + */ + void assignReadBuffer(uint8_t* rx); + void assignWriteBuffer(const uint8_t* tx); + /** + * Assign size for the next transfer. + * @param transferSize + */ + void assignTransferSize(size_t transferSize); + size_t getCurrentTransferSize() const; + + struct UncommonParameters { + uint8_t bitsPerWord = 8; + bool noCs = false; + bool csHigh = false; + bool threeWireSpi = false; + /* MSB first is more common */ + bool lsbFirst = false; + }; + + /** + * Can be used to explicitely disable hardware chip select. + * Some drivers like the Raspberry Pi Linux driver will not use hardware chip select by default + * (see https://www.raspberrypi.org/documentation/hardware/raspberrypi/spi/README.md) + * @param enable + */ + void setNoCs(bool enable); + void setThreeWireSpi(bool enable); + void setLsbFirst(bool enable); + void setCsHigh(bool enable); + void setBitsPerWord(uint8_t bitsPerWord); + + void getSpiParameters(spi::SpiMode& spiMode, uint32_t& spiSpeed, + UncommonParameters* parameters = nullptr) const; + + /** + * See spidev.h cs_change and delay_usecs + * @param deselectCs + * @param delayUsecs + */ + void activateCsDeselect(bool deselectCs, uint16_t delayUsecs); + + spi_ioc_transfer* getTransferStructHandle(); +private: + size_t currentTransferSize = 0; + + address_t spiAddress; + gpioId_t chipSelectPin; + std::string spiDevice; + + const size_t maxSize; + spi::SpiMode spiMode; + uint32_t spiSpeed; + bool halfDuplex = false; + + struct spi_ioc_transfer spiTransferStruct; + UncommonParameters uncommonParameters; +}; + + + +#endif /* LINUX_SPI_SPICOOKIE_H_ */ diff --git a/linux/spi/spiDefinitions.h b/linux/spi/spiDefinitions.h new file mode 100644 index 00000000..9c278a70 --- /dev/null +++ b/linux/spi/spiDefinitions.h @@ -0,0 +1,15 @@ +#ifndef LINUX_SPI_SPIDEFINITONS_H_ +#define LINUX_SPI_SPIDEFINITONS_H_ + +namespace spi { + +enum SpiMode { + MODE_0, + MODE_1, + MODE_2, + MODE_3 +}; + +} + +#endif /* LINUX_SPI_SPIDEFINITONS_H_ */ diff --git a/linux/utility/errorhandling.h b/linux/utility/errorhandling.h new file mode 100644 index 00000000..1b4bc38b --- /dev/null +++ b/linux/utility/errorhandling.h @@ -0,0 +1,30 @@ +#ifndef LINUX_UTILITY_ERRORHANDLING_H_ +#define LINUX_UTILITY_ERRORHANDLING_H_ + +#include +#include +#include + +namespace utility { + +void handleIoctlError(const char* const customPrintout) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + if(customPrintout != nullptr) { + sif::warning << customPrintout << std::endl; + } + sif::warning << "handleIoctlError: Error code " << errno << ", "<< strerror(errno) << + std::endl; +#else + if(customPrintout != nullptr) { + sif::printWarning("%s\n", customPrintout); + } + sif::printWarning("handleIoctlError: Error code %d, %s\n", errno, strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + +} + +} + +#endif /* LINUX_UTILITY_ERRORHANDLING_H_ */ -- 2.43.0 From e1e0c0774629d3526e1378cbf668cee018835d33 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 11:56:48 +0100 Subject: [PATCH 21/34] spi com if finished --- fsfwconfig/returnvalues/classIds.h | 1 + linux/spi/SpiComIF.cpp | 69 +++++++++----------------- linux/spi/SpiComIF.h | 29 +++++++---- linux/utility/errorhandling.h | 30 ------------ linux/utility/utility.h | 77 ++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 85 deletions(-) delete mode 100644 linux/utility/errorhandling.h create mode 100644 linux/utility/utility.h diff --git a/fsfwconfig/returnvalues/classIds.h b/fsfwconfig/returnvalues/classIds.h index 419a24ef..deafbd75 100644 --- a/fsfwconfig/returnvalues/classIds.h +++ b/fsfwconfig/returnvalues/classIds.h @@ -14,6 +14,7 @@ enum { MGM_LIS3MDL, MGM_RM3100, LINUX_LIBGPIO_IF, + LINUX_SPI_COM_IF, PCDU_HANDLER, HEATER_HANDLER, SA_DEPL_HANDLER diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index bdb0c705..144a6db0 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -2,8 +2,6 @@ #include "spiDefinitions.h" #include -#include - #include #include @@ -12,6 +10,7 @@ #include #include #include +#include #include SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(objectId), @@ -81,9 +80,10 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { spiCookie->getSpiParameters(spiMode, spiSpeed, ¶ms); int fileDescriptor = 0; - ReturnValue_t result = openDevice(spiCookie->getSpiDevice(), &fileDescriptor); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; + utility::UnixFileHelper fileHelper(spiCookie->getSpiDevice(), &fileDescriptor, O_RDWR, + "SpiComIF::initializeInterface: "); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return fileHelper.getOpenResult(); } int retval = ioctl(fileDescriptor, SPI_IOC_WR_MODE, spiSpeed); @@ -138,6 +138,7 @@ ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, size_t sendLen) { SpiCookie* spiCookie = dynamic_cast(cookie); + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; if(spiCookie == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; } @@ -160,9 +161,10 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s spiCookie->assignTransferSize(sendLen); int fileDescriptor = 0; std::string device = spiCookie->getSpiDevice(); - ReturnValue_t result = openDevice(device, &fileDescriptor); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; + utility::UnixFileHelper fileHelper(device, &fileDescriptor, O_RDWR, + "SpiComIF::sendMessage: "); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return OPENING_FILE_FAILED; } bool fullDuplex = spiCookie->isFullDuplex(); @@ -180,8 +182,7 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), spiCookie->getTransferStructHandle()); if(retval != 0) { utility::handleIoctlError("SpiComIF::sendMessage: ioctl error."); - /* TODO: Better returnvalue */ - return HasReturnvaluesIF::RETURN_FAILED; + result = FULL_DUPLEX_TRANSFER_FAILED; } } else { @@ -189,15 +190,14 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s if (write(fileDescriptor, sendData, sendLen) != static_cast(sendLen)) { sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << std::endl; - /* TODO: Better returnvalue */ - return HasReturnvaluesIF::RETURN_FAILED; + result = HALF_DUPLEX_TRANSFER_FAILED; } } if(gpioId != gpio::NO_GPIO) { gpioComIF->pullHigh(gpioId); } - return HasReturnvaluesIF::RETURN_OK; + return result; } ReturnValue_t SpiComIF::getSendSuccess(CookieIF *cookie) { @@ -205,6 +205,7 @@ ReturnValue_t SpiComIF::getSendSuccess(CookieIF *cookie) { } ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) { + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; SpiCookie* spiCookie = dynamic_cast(cookie); if(spiCookie == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; @@ -217,9 +218,10 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLe std::string device = spiCookie->getSpiDevice(); int fileDescriptor = 0; - ReturnValue_t result = openDevice(device, &fileDescriptor); - if(result != HasReturnvaluesIF::RETURN_OK) { - return result; + utility::UnixFileHelper fileHelper(device, &fileDescriptor, O_RDWR, + "SpiComIF::requestReceiveMessage: "); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return OPENING_FILE_FAILED; } uint8_t* rxBuf = nullptr; @@ -237,9 +239,11 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLe if(read(fileDescriptor, rxBuf, readSize) != static_cast(readSize)) { sif::warning << "SpiComIF::sendMessage: Half-Duplex read operation failed!" << std::endl; - if(gpioId != gpio::NO_GPIO) { - gpioComIF->pullHigh(gpioId); - } + result = HALF_DUPLEX_TRANSFER_FAILED; + } + + if(gpioId != gpio::NO_GPIO) { + gpioComIF->pullHigh(gpioId); } return HasReturnvaluesIF::RETURN_OK; @@ -261,33 +265,6 @@ ReturnValue_t SpiComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, return HasReturnvaluesIF::RETURN_OK; } -ReturnValue_t SpiComIF::openDevice(std::string deviceFile, int *fileDescriptor, bool nonBlocking) { - if(fileDescriptor == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; - } - - int flags = O_RDWR; - if(nonBlocking) { - flags |= O_NONBLOCK; - } - *fileDescriptor = open(deviceFile.c_str(), flags); - if (*fileDescriptor < 0) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "SpiComIF: Opening SPI device failed with error code " << errno << "." << - std::endl; - sif::warning << "Error description: " << strerror(errno) << std::endl; -#else - sif::printError("SpiComIF: Opening SPI device failed with error code %d.\n"); - sif::printWarning("Error description: %s\n", strerror(errno)); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - return HasReturnvaluesIF::RETURN_FAILED; - } - - return HasReturnvaluesIF::RETURN_OK; -} - ReturnValue_t SpiComIF::getReadBuffer(address_t spiAddress, uint8_t** buffer) { if(buffer == nullptr) { return HasReturnvaluesIF::RETURN_FAILED; diff --git a/linux/spi/SpiComIF.h b/linux/spi/SpiComIF.h index 4009eed9..b91dd479 100644 --- a/linux/spi/SpiComIF.h +++ b/linux/spi/SpiComIF.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -16,6 +17,16 @@ */ class SpiComIF: public DeviceCommunicationIF, public SystemObject { public: + static constexpr uint8_t spiRetvalId = CLASS_ID::LINUX_SPI_COM_IF; + static constexpr ReturnValue_t OPENING_FILE_FAILED = + HasReturnvaluesIF::makeReturnCode(spiRetvalId, 0); + /* Full duplex (ioctl) transfer failure */ + static constexpr ReturnValue_t FULL_DUPLEX_TRANSFER_FAILED = + HasReturnvaluesIF::makeReturnCode(spiRetvalId, 1); + /* Half duplex (read/write) transfer failure */ + static constexpr ReturnValue_t HALF_DUPLEX_TRANSFER_FAILED = + HasReturnvaluesIF::makeReturnCode(spiRetvalId, 2); + SpiComIF(object_id_t objectId, GpioIF* gpioComIF); ReturnValue_t initializeInterface(CookieIF * cookie) override; @@ -43,15 +54,15 @@ private: SpiDeviceMap spiDeviceMap; - /** - * @brief This function opens an SPI device and binds the opened file - * to a specific SPI address. - * @param deviceFile The name of the device file. E.g. spi-0 - * @param i2cAddress The address of the SPI slave device. - * @param fileDescriptor Pointer to device descriptor. - * @return RETURN_OK if successful, otherwise RETURN_FAILED. - */ - ReturnValue_t openDevice(std::string deviceFile, int* fileDescriptor, bool nonBlocking = false); +// /** +// * @brief This function opens an SPI device and binds the opened file +// * to a specific SPI address. +// * @param deviceFile The name of the device file. E.g. spi-0 +// * @param i2cAddress The address of the SPI slave device. +// * @param fileDescriptor Pointer to device descriptor. +// * @return RETURN_OK if successful, otherwise RETURN_FAILED. +// */ +// ReturnValue_t openDevice(std::string deviceFile, int* fileDescriptor, bool nonBlocking = false); ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); }; diff --git a/linux/utility/errorhandling.h b/linux/utility/errorhandling.h deleted file mode 100644 index 1b4bc38b..00000000 --- a/linux/utility/errorhandling.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef LINUX_UTILITY_ERRORHANDLING_H_ -#define LINUX_UTILITY_ERRORHANDLING_H_ - -#include -#include -#include - -namespace utility { - -void handleIoctlError(const char* const customPrintout) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - if(customPrintout != nullptr) { - sif::warning << customPrintout << std::endl; - } - sif::warning << "handleIoctlError: Error code " << errno << ", "<< strerror(errno) << - std::endl; -#else - if(customPrintout != nullptr) { - sif::printWarning("%s\n", customPrintout); - } - sif::printWarning("handleIoctlError: Error code %d, %s\n", errno, strerror(errno)); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - -} - -} - -#endif /* LINUX_UTILITY_ERRORHANDLING_H_ */ diff --git a/linux/utility/utility.h b/linux/utility/utility.h new file mode 100644 index 00000000..278b081c --- /dev/null +++ b/linux/utility/utility.h @@ -0,0 +1,77 @@ +#ifndef LINUX_UTILITY_UTILITY_H_ +#define LINUX_UTILITY_UTILITY_H_ + +#include +#include +#include + +#include +#include + +namespace utility { + +void handleIoctlError(const char* const customPrintout) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + if(customPrintout != nullptr) { + sif::warning << customPrintout << std::endl; + } + sif::warning << "handleIoctlError: Error code " << errno << ", "<< strerror(errno) << + std::endl; +#else + if(customPrintout != nullptr) { + sif::printWarning("%s\n", customPrintout); + } + sif::printWarning("handleIoctlError: Error code %d, %s\n", errno, strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + +} + +class UnixFileHelper { +public: + static constexpr int READ_WRITE_FLAG = O_RDWR; + static constexpr int READ_ONLY_FLAG = O_RDONLY; + static constexpr int NON_BLOCKING_IO_FLAG = O_NONBLOCK; + + static constexpr ReturnValue_t OPEN_FILE_FAILED = 1; + + UnixFileHelper(std::string device, int* fileDescriptor, int flags, + std::string diagnosticPrefix = ""): + fileDescriptor(fileDescriptor) { + if(fileDescriptor == nullptr) { + return; + } + *fileDescriptor = open(device.c_str(), flags); + if (*fileDescriptor < 0) { + #if FSFW_VERBOSE_LEVEL >= 1 + #if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << diagnosticPrefix <<"Opening device failed with error code " << errno << + "." << std::endl; + sif::warning << "Error description: " << strerror(errno) << std::endl; + #else + sif::printError("%sOpening device failed with error code %d.\n", diagnosticPrefix); + sif::printWarning("Error description: %s\n", strerror(errno)); + #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ + #endif /* FSFW_VERBOSE_LEVEL >= 1 */ + openStatus = OPEN_FILE_FAILED; + } + } + + virtual~ UnixFileHelper() { + if(fileDescriptor != nullptr) { + close(*fileDescriptor); + } + } + + ReturnValue_t getOpenResult() const { + return openStatus; + } +private: + int* fileDescriptor = nullptr; + ReturnValue_t openStatus = HasReturnvaluesIF::RETURN_OK; +}; + +} + +#endif /* LINUX_UTILITY_UTILITY_H_ */ -- 2.43.0 From c042bbea63918f7fafeb8e8d557c708b11624447 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 12:13:04 +0100 Subject: [PATCH 22/34] source file for utility now --- linux/CMakeLists.txt | 1 + linux/i2c/I2cComIF.cpp | 45 +++++++-------------- linux/spi/SpiComIF.cpp | 10 ++--- linux/utility/CMakeLists.txt | 7 ++++ linux/utility/Utility.cpp | 52 ++++++++++++++++++++++++ linux/utility/Utility.h | 36 +++++++++++++++++ linux/utility/utility.h | 77 ------------------------------------ 7 files changed, 116 insertions(+), 112 deletions(-) create mode 100644 linux/utility/CMakeLists.txt create mode 100644 linux/utility/Utility.cpp create mode 100644 linux/utility/Utility.h delete mode 100644 linux/utility/utility.h diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 9101e15d..77bea0ef 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -2,5 +2,6 @@ add_subdirectory(gpio) add_subdirectory(i2c) add_subdirectory(csp) add_subdirectory(spi) +add_subdirectory(utility) add_subdirectory(boardtest) diff --git a/linux/i2c/I2cComIF.cpp b/linux/i2c/I2cComIF.cpp index 8e372b14..ed50293d 100644 --- a/linux/i2c/I2cComIF.cpp +++ b/linux/i2c/I2cComIF.cpp @@ -1,12 +1,13 @@ #include "I2cComIF.h" #include - #include #include #include #include #include -#include +#include + +#include I2cComIF::I2cComIF(object_id_t objectId): SystemObject(objectId){ @@ -68,8 +69,7 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF *cookie, I2cCookie* i2cCookie = dynamic_cast(cookie); if(i2cCookie == nullptr) { - sif::error << "I2cComIF::sendMessasge: Invalid I2C Cookie!" - << std::endl; + sif::error << "I2cComIF::sendMessage: Invalid I2C Cookie!" << std::endl; return NULLPOINTER; } @@ -82,6 +82,10 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF *cookie, } deviceFile = i2cCookie->getDeviceFile(); + utility::UnixFileHelper fileHelper(deviceFile, &fd, O_RDWR, "I2cComIF::sendMessage"); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return fileHelper.getOpenResult(); + } result = openDevice(deviceFile, i2cAddress, &fd); if (result != HasReturnvaluesIF::RETURN_OK){ return result; @@ -91,10 +95,8 @@ ReturnValue_t I2cComIF::sendMessage(CookieIF *cookie, sif::error << "I2cComIF::sendMessage: Failed to send data to I2C " "device with error code " << errno << ". Error description: " << strerror(errno) << std::endl; - close(fd); return HasReturnvaluesIF::RETURN_FAILED; } - close(fd); return HasReturnvaluesIF::RETURN_OK; } @@ -104,7 +106,6 @@ ReturnValue_t I2cComIF::getSendSuccess(CookieIF *cookie) { ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) { - ReturnValue_t result; int fd; std::string deviceFile; @@ -115,8 +116,7 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF *cookie, I2cCookie* i2cCookie = dynamic_cast(cookie); if(i2cCookie == nullptr) { - sif::error << "I2cComIF::requestReceiveMessage: Invalid I2C Cookie!" - << std::endl; + sif::error << "I2cComIF::requestReceiveMessage: Invalid I2C Cookie!" << std::endl; i2cDeviceMapIter->second.replyLen = 0; return NULLPOINTER; } @@ -131,6 +131,10 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF *cookie, } deviceFile = i2cCookie->getDeviceFile(); + utility::UnixFileHelper fileHelper(deviceFile, &fd, O_RDWR, "I2cComIF::requestReceiveMessage"); + if(fileHelper.getOpenResult() != HasReturnvaluesIF::RETURN_OK) { + return fileHelper.getOpenResult(); + } result = openDevice(deviceFile, i2cAddress, &fd); if (result != HasReturnvaluesIF::RETURN_OK){ i2cDeviceMapIter->second.replyLen = 0; @@ -139,19 +143,15 @@ ReturnValue_t I2cComIF::requestReceiveMessage(CookieIF *cookie, uint8_t* replyBuffer = i2cDeviceMapIter->second.replyBuffer.data(); - if (read(fd, replyBuffer, requestLen) != (int)requestLen) { + if (read(fd, replyBuffer, requestLen) != static_cast(requestLen)) { sif::error << "I2cComIF::requestReceiveMessage: Reading from I2C " << "device failed with error code " << errno <<". Description" << " of error: " << strerror(errno) << std::endl; - close(fd); i2cDeviceMapIter->second.replyLen = 0; return HasReturnvaluesIF::RETURN_FAILED; } i2cDeviceMapIter->second.replyLen = requestLen; - - close(fd); - return HasReturnvaluesIF::RETURN_OK; } @@ -159,8 +159,7 @@ ReturnValue_t I2cComIF::readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t* size) { I2cCookie* i2cCookie = dynamic_cast(cookie); if(i2cCookie == nullptr) { - sif::error << "I2cComIF::readReceivedMessage: Invalid I2C Cookie!" - << std::endl; + sif::error << "I2cComIF::readReceivedMessage: Invalid I2C Cookie!" << std::endl; return NULLPOINTER; } @@ -179,20 +178,6 @@ ReturnValue_t I2cComIF::readReceivedMessage(CookieIF *cookie, ReturnValue_t I2cComIF::openDevice(std::string deviceFile, address_t i2cAddress, int* fileDescriptor) { - *fileDescriptor = open(deviceFile.c_str(), O_RDWR); - if (*fileDescriptor < 0) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "I2cComIF: Opening I2C device failed with error code " << errno << "." << - std::endl; - sif::warning << "Error description: " << strerror(errno) << std::endl; -#else - sif::printWarning("I2cComIF: Opening I2C device failed with error code %d.\n"); - sif::printWarning("Error description: %s\n", strerror(errno)); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - return HasReturnvaluesIF::RETURN_FAILED; - } if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) { #if FSFW_VERBOSE_LEVEL >= 1 diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index 144a6db0..ebcf7991 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -3,14 +3,14 @@ #include #include - #include #include #include #include #include #include -#include +#include + #include SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(objectId), @@ -31,7 +31,7 @@ SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(object ReturnValue_t SpiComIF::initializeInterface(CookieIF *cookie) { SpiCookie* spiCookie = dynamic_cast(cookie); if(spiCookie == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; + return NULLPOINTER; } address_t spiAddress = spiCookie->getSpiAddress(); @@ -140,7 +140,7 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s SpiCookie* spiCookie = dynamic_cast(cookie); ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; if(spiCookie == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; + return NULLPOINTER; } if(sendLen > spiCookie->getMaxBufferSize()) { @@ -208,7 +208,7 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLe ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; SpiCookie* spiCookie = dynamic_cast(cookie); if(spiCookie == nullptr) { - return HasReturnvaluesIF::RETURN_FAILED; + return NULLPOINTER; } bool fullDuplex = spiCookie->isFullDuplex(); diff --git a/linux/utility/CMakeLists.txt b/linux/utility/CMakeLists.txt new file mode 100644 index 00000000..71151b6c --- /dev/null +++ b/linux/utility/CMakeLists.txt @@ -0,0 +1,7 @@ +target_sources(${TARGET_NAME} PUBLIC + Utility.cpp +) + + + + diff --git a/linux/utility/Utility.cpp b/linux/utility/Utility.cpp new file mode 100644 index 00000000..8f1ca912 --- /dev/null +++ b/linux/utility/Utility.cpp @@ -0,0 +1,52 @@ +#include "Utility.h" + +void utility::handleIoctlError(const char* const customPrintout) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + if(customPrintout != nullptr) { + sif::warning << customPrintout << std::endl; + } + sif::warning << "handleIoctlError: Error code " << errno << ", "<< strerror(errno) << + std::endl; +#else + if(customPrintout != nullptr) { + sif::printWarning("%s\n", customPrintout); + } + sif::printWarning("handleIoctlError: Error code %d, %s\n", errno, strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + +} + +utility::UnixFileHelper::UnixFileHelper(std::string device, int* fileDescriptor, int flags, + std::string diagnosticPrefix): + fileDescriptor(fileDescriptor) { + if(fileDescriptor == nullptr) { + return; + } + *fileDescriptor = open(device.c_str(), flags); + if (*fileDescriptor < 0) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << diagnosticPrefix <<"Opening device failed with error code " << errno << + "." << std::endl; + sif::warning << "Error description: " << strerror(errno) << std::endl; +#else + sif::printError("%sOpening device failed with error code %d.\n", diagnosticPrefix); + sif::printWarning("Error description: %s\n", strerror(errno)); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ + openStatus = OPEN_FILE_FAILED; + } +} + +utility::UnixFileHelper::~UnixFileHelper() { + if(fileDescriptor != nullptr) { + close(*fileDescriptor); + } +} + +ReturnValue_t utility::UnixFileHelper::getOpenResult() const { + return openStatus; +} + diff --git a/linux/utility/Utility.h b/linux/utility/Utility.h new file mode 100644 index 00000000..a93b4936 --- /dev/null +++ b/linux/utility/Utility.h @@ -0,0 +1,36 @@ +#ifndef LINUX_UTILITY_UTILITY_H_ +#define LINUX_UTILITY_UTILITY_H_ + +#include +#include +#include + +#include +#include + +namespace utility { + +void handleIoctlError(const char* const customPrintout); + +class UnixFileHelper { +public: + static constexpr int READ_WRITE_FLAG = O_RDWR; + static constexpr int READ_ONLY_FLAG = O_RDONLY; + static constexpr int NON_BLOCKING_IO_FLAG = O_NONBLOCK; + + static constexpr ReturnValue_t OPEN_FILE_FAILED = 1; + + UnixFileHelper(std::string device, int* fileDescriptor, int flags, + std::string diagnosticPrefix = ""); + + virtual~ UnixFileHelper(); + + ReturnValue_t getOpenResult() const; +private: + int* fileDescriptor = nullptr; + ReturnValue_t openStatus = HasReturnvaluesIF::RETURN_OK; +}; + +} + +#endif /* LINUX_UTILITY_UTILITY_H_ */ diff --git a/linux/utility/utility.h b/linux/utility/utility.h deleted file mode 100644 index 278b081c..00000000 --- a/linux/utility/utility.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef LINUX_UTILITY_UTILITY_H_ -#define LINUX_UTILITY_UTILITY_H_ - -#include -#include -#include - -#include -#include - -namespace utility { - -void handleIoctlError(const char* const customPrintout) { -#if FSFW_VERBOSE_LEVEL >= 1 -#if FSFW_CPP_OSTREAM_ENABLED == 1 - if(customPrintout != nullptr) { - sif::warning << customPrintout << std::endl; - } - sif::warning << "handleIoctlError: Error code " << errno << ", "<< strerror(errno) << - std::endl; -#else - if(customPrintout != nullptr) { - sif::printWarning("%s\n", customPrintout); - } - sif::printWarning("handleIoctlError: Error code %d, %s\n", errno, strerror(errno)); -#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ -#endif /* FSFW_VERBOSE_LEVEL >= 1 */ - -} - -class UnixFileHelper { -public: - static constexpr int READ_WRITE_FLAG = O_RDWR; - static constexpr int READ_ONLY_FLAG = O_RDONLY; - static constexpr int NON_BLOCKING_IO_FLAG = O_NONBLOCK; - - static constexpr ReturnValue_t OPEN_FILE_FAILED = 1; - - UnixFileHelper(std::string device, int* fileDescriptor, int flags, - std::string diagnosticPrefix = ""): - fileDescriptor(fileDescriptor) { - if(fileDescriptor == nullptr) { - return; - } - *fileDescriptor = open(device.c_str(), flags); - if (*fileDescriptor < 0) { - #if FSFW_VERBOSE_LEVEL >= 1 - #if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << diagnosticPrefix <<"Opening device failed with error code " << errno << - "." << std::endl; - sif::warning << "Error description: " << strerror(errno) << std::endl; - #else - sif::printError("%sOpening device failed with error code %d.\n", diagnosticPrefix); - sif::printWarning("Error description: %s\n", strerror(errno)); - #endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ - #endif /* FSFW_VERBOSE_LEVEL >= 1 */ - openStatus = OPEN_FILE_FAILED; - } - } - - virtual~ UnixFileHelper() { - if(fileDescriptor != nullptr) { - close(*fileDescriptor); - } - } - - ReturnValue_t getOpenResult() const { - return openStatus; - } -private: - int* fileDescriptor = nullptr; - ReturnValue_t openStatus = HasReturnvaluesIF::RETURN_OK; -}; - -} - -#endif /* LINUX_UTILITY_UTILITY_H_ */ -- 2.43.0 From 434d0586b3077a323430b52f770bacf634329e69 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:24:05 +0100 Subject: [PATCH 23/34] refactored GPIO to support callbacks --- bsp_rpi/gpio/GPIORPi.cpp | 2 +- linux/boardtest/LibgpiodTest.cpp | 2 +- linux/gpio/GpioCookie.cpp | 4 +- linux/gpio/GpioCookie.h | 2 +- linux/gpio/GpioIF.h | 2 +- linux/gpio/LinuxLibgpioIF.cpp | 292 ++++++++++++------ linux/gpio/LinuxLibgpioIF.h | 19 +- linux/gpio/gpioDefinitions.h | 68 +++- .../devices/SolarArrayDeploymentHandler.cpp | 2 +- 9 files changed, 268 insertions(+), 125 deletions(-) diff --git a/bsp_rpi/gpio/GPIORPi.cpp b/bsp_rpi/gpio/GPIORPi.cpp index 84a3365f..74b67a42 100644 --- a/bsp_rpi/gpio/GPIORPi.cpp +++ b/bsp_rpi/gpio/GPIORPi.cpp @@ -10,7 +10,7 @@ ReturnValue_t gpio::createRpiGpioConfig(GpioCookie* cookie, gpioId_t gpioId, int return HasReturnvaluesIF::RETURN_FAILED; } - GpioConfig_t config; + GpiodRegular config; /* Default chipname for Raspberry Pi. There is still gpiochip1 for expansion, but most users will not need this */ config.chipname = "gpiochip0"; diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index d88e5676..99602107 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -13,7 +13,7 @@ LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, if (gpioInterface == nullptr) { sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl; } - gpioInterface->initialize(gpioCookie); + gpioInterface->addGpios(gpioCookie); testCase = TestCases::LOOPBACK; } diff --git a/linux/gpio/GpioCookie.cpp b/linux/gpio/GpioCookie.cpp index cd73574c..f957d070 100644 --- a/linux/gpio/GpioCookie.cpp +++ b/linux/gpio/GpioCookie.cpp @@ -4,10 +4,10 @@ GpioCookie::GpioCookie() { } -ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpioConfig_t& gpioConfig){ +ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpiodRegular& gpioConfig){ auto gpioMapIter = gpioMap.find(gpioId); if(gpioMapIter == gpioMap.end()) { - auto statusPair = gpioMap.emplace(gpioId, gpioConfig); + auto statusPair = gpioMap.emplace(gpioId, new GpiodRegular(gpioConfig)); if (statusPair.second == false) { #if FSFW_VERBOSE_LEVEL >= 1 sif::error << "GpioCookie::addGpio: Failed to add GPIO " << gpioId << diff --git a/linux/gpio/GpioCookie.h b/linux/gpio/GpioCookie.h index e1436813..c7721a98 100644 --- a/linux/gpio/GpioCookie.h +++ b/linux/gpio/GpioCookie.h @@ -23,7 +23,7 @@ public: virtual ~GpioCookie(); - ReturnValue_t addGpio(gpioId_t gpioId, GpioConfig_t& gpioConfig); + ReturnValue_t addGpio(gpioId_t gpioId, GpiodRegular& gpioConfig); /** * @brief Get map with registered GPIOs. */ diff --git a/linux/gpio/GpioIF.h b/linux/gpio/GpioIF.h index 80d3a727..75feb3ce 100644 --- a/linux/gpio/GpioIF.h +++ b/linux/gpio/GpioIF.h @@ -22,7 +22,7 @@ public: * @param cookie Cookie specifying informations of the GPIOs required * by a object. */ - virtual ReturnValue_t initialize(GpioCookie* cookie) = 0; + virtual ReturnValue_t addGpios(GpioCookie* cookie) = 0; /** * @brief By implementing this function a child must provide the diff --git a/linux/gpio/LinuxLibgpioIF.cpp b/linux/gpio/LinuxLibgpioIF.cpp index 1b152a0f..0cf3858f 100644 --- a/linux/gpio/LinuxLibgpioIF.cpp +++ b/linux/gpio/LinuxLibgpioIF.cpp @@ -2,18 +2,20 @@ #include "GpioCookie.h" #include +#include #include #include #include + LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) { } LinuxLibgpioIF::~LinuxLibgpioIF() { } -ReturnValue_t LinuxLibgpioIF::initialize(GpioCookie* gpioCookie){ +ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) { ReturnValue_t result; if(gpioCookie == nullptr) { sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl; @@ -32,101 +34,153 @@ ReturnValue_t LinuxLibgpioIF::initialize(GpioCookie* gpioCookie){ return RETURN_FAILED; } - /* Register new GPIOs in gpioMap*/ + /* Register new GPIOs in gpioMap */ gpioMap.insert(mapToAdd.begin(), mapToAdd.end()); return RETURN_OK; } ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { + for(auto& gpioConfig: mapToAdd) { + switch(gpioConfig.second->gpioType) { + case(gpio::GpioTypes::NONE): { + return GPIO_INVALID_INSTANCE; + } + case(gpio::GpioTypes::GPIOD_REGULAR): { + GpiodRegular* regularGpio = dynamic_cast(gpioConfig.second); + configureRegularGpio(gpioConfig.first, regularGpio); + break; + } + case(gpio::GpioTypes::CALLBACK): { + auto gpioCallback = dynamic_cast(gpioMapIter->second); + if(gpioCallback->callback == nullptr) { + return GPIO_INVALID_INSTANCE; + } + gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::READ, + 0, gpioCallback->callbackArgs); + } + } + } + return RETURN_OK; +} + +ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular *regularGpio) { std::string chipname; unsigned int lineNum; struct gpiod_chip *chip; gpio::Direction direction; std::string consumer; struct gpiod_line *lineHandle; - int result; + int result = 0; - for(auto& gpioConfig: mapToAdd) { - chipname = gpioConfig.second.chipname; - chip = gpiod_chip_open_by_name(chipname.c_str()); - if (!chip) { - sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip " - << chipname << ". Gpio ID: " << gpioConfig.first << std::endl; - return RETURN_FAILED; - } - - lineNum = gpioConfig.second.lineNum; - lineHandle = gpiod_chip_get_line(chip, lineNum); - if (!lineHandle) { - sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line" << std::endl; - gpiod_chip_close(chip); - return RETURN_FAILED; - } - - direction = gpioConfig.second.direction; - consumer = gpioConfig.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(), - gpioConfig.second.initValue); - if (result < 0) { - sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " - << lineNum << " from GPIO instance with ID: " << gpioConfig.first - << std::endl; - gpiod_line_release(lineHandle); - return RETURN_FAILED; - } - break; - case gpio::IN: - 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: " << gpioConfig.first - << std::endl; - gpiod_line_release(lineHandle); - return RETURN_FAILED; - } - break; - default: - sif::error << "LinuxLibgpioIF::configureGpios: Invalid direction specified" - << std::endl; - return RETURN_FAILED; - } - /** - * Write line handle to GPIO configuration instance so it can later be used to set or - * read states of GPIOs. - */ - gpioConfig.second.lineHandle = lineHandle; - } - return RETURN_OK; -} - -ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId){ - return driveGpio(gpioId, 1); -} - -ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId){ - return driveGpio(gpioId, 0); -} - -ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, - unsigned int logiclevel) { - int result; - struct gpiod_line *lineHandle; - - gpioMapIter = gpioMap.find(gpioId); - if (gpioMapIter == gpioMap.end()){ - sif::debug << "LinuxLibgpioIF::driveGpio: Unknown gpio id " << gpioId << std::endl; + chipname = regularGpio->chipname; + chip = gpiod_chip_open_by_name(chipname.c_str()); + if (!chip) { + sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip " + << chipname << ". Gpio ID: " << gpioId << std::endl; return RETURN_FAILED; } - lineHandle = gpioMapIter->second.lineHandle; - result = gpiod_line_set_value(lineHandle, logiclevel); + lineNum = regularGpio->lineNum; + lineHandle = gpiod_chip_get_line(chip, lineNum); + if (!lineHandle) { + sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line" << std::endl; + gpiod_chip_close(chip); + return RETURN_FAILED; + } + + direction = regularGpio->direction; + consumer = regularGpio->consumer; + /* Configure direction and add a description to the GPIO */ + switch (direction) { + case(gpio::OUT): { + result = gpiod_line_request_output(lineHandle, consumer.c_str(), + regularGpio->initValue); + if (result < 0) { + sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " << lineNum << + " from GPIO instance with ID: " << gpioId << std::endl; + gpiod_line_release(lineHandle); + return RETURN_FAILED; + } + break; + } + case(gpio::IN): { + 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: " << gpioId << std::endl; + gpiod_line_release(lineHandle); + return RETURN_FAILED; + } + break; + } + default: { + sif::error << "LinuxLibgpioIF::configureGpios: Invalid direction specified" + << std::endl; + return GPIO_INVALID_INSTANCE; + } + + } + /** + * Write line handle to GPIO configuration instance so it can later be used to set or + * read states of GPIOs. + */ + regularGpio->lineHandle = lineHandle; + return RETURN_OK; +} + +ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) { + gpioMapIter = gpioMap.find(gpioId); + if (gpioMapIter == gpioMap.end()) { + sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl; + return UNKNOWN_GPIO_ID; + } + + if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { + return driveGpio(gpioId, dynamic_cast(gpioMapIter->second), 1); + } + else { + auto gpioCallback = dynamic_cast(gpioMapIter->second); + if(gpioCallback->callback == nullptr) { + return GPIO_INVALID_INSTANCE; + } + gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE, + 1, gpioCallback->callbackArgs); + } + return GPIO_TYPE_FAILURE; +} + +ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) { + gpioMapIter = gpioMap.find(gpioId); + if (gpioMapIter == gpioMap.end()) { + sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl; + return UNKNOWN_GPIO_ID; + } + + if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { + return driveGpio(gpioId, dynamic_cast(gpioMapIter->second), 0); + } + else { + auto gpioCallback = dynamic_cast(gpioMapIter->second); + if(gpioCallback->callback == nullptr) { + return GPIO_INVALID_INSTANCE; + } + gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE, + 0, gpioCallback->callbackArgs); + } + return GPIO_TYPE_FAILURE; +} + +ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, + GpiodRegular* regularGpio, unsigned int logicLevel) { + if(regularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + + int result = gpiod_line_set_value(regularGpio->lineHandle, logicLevel); if (result < 0) { - sif::error << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " - << gpioId << " to logic level " << logiclevel << std::endl; + sif::warning << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId << + " to logic level " << logicLevel << std::endl; return DRIVE_GPIO_FAILURE; } @@ -134,38 +188,76 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, } ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { - struct gpiod_line *lineHandle; - gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()){ - sif::debug << "LinuxLibgpioIF::readGpio: Unknown gpio id " << gpioId << std::endl; - return RETURN_FAILED; + sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl; + return UNKNOWN_GPIO_ID; + } + + if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { + GpiodRegular* regularGpio = dynamic_cast(gpioMapIter->second); + if(regularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + *gpioState = gpiod_line_get_value(regularGpio->lineHandle); + } + else { + } - lineHandle = gpioMapIter->second.lineHandle; - *gpioState = gpiod_line_get_value(lineHandle); return RETURN_OK; } ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ - gpioId_t gpioId; + ReturnValue_t status = HasReturnvaluesIF::RETURN_OK; + ReturnValue_t result = HasReturnvaluesIF::RETURN_OK; for(auto& gpioConfig: mapToAdd) { - gpioId = gpioConfig.first; - /* Cross check with private map */ - gpioMapIter = gpioMap.find(gpioId); - if(gpioMapIter != mapToAdd.end()) { - /* An entry for this GPIO already exists. Check if configuration - * of direction is equivalent */ - if (gpioConfig.second.direction != gpioMapIter->second.direction){ - sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict for GPIO " << - gpioConfig.first << std::endl; - return RETURN_FAILED; + switch(gpioConfig.second->gpioType) { + case(gpio::GpioTypes::GPIOD_REGULAR): { + auto regularGpio = dynamic_cast(gpioConfig.second); + if(regularGpio == nullptr) { + return GPIO_TYPE_FAILURE; } - /* Remove element from map to add because a entry for this GPIO - * already exists */ - mapToAdd.erase(gpioConfig.first); + result = checkForConflictsRegularGpio(gpioConfig.first, regularGpio); + if(result != HasReturnvaluesIF::RETURN_OK) { + status = result; + } + break; + } + default: { + + } } } - return RETURN_OK; + return status; +} + + +ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck, + GpiodRegular* gpioToCheck) { + /* Cross check with private map */ + gpioMapIter = gpioMap.find(gpioIdToCheck); + if(gpioMapIter != gpioMap.end()) { + if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) { + auto ownRegularGpio = dynamic_cast(gpioMapIter->second); + if(ownRegularGpio == nullptr) { + return GPIO_TYPE_FAILURE; + } + /* An entry for this GPIO already exists. Check if configuration + * of direction is equivalent */ + if (gpioToCheck->direction != ownRegularGpio->direction){ + sif::error << "LinuxLibgpioIF::checkForConflicts: Detected conflict for GPIO " << + gpioIdToCheck << std::endl; + return RETURN_FAILED; + + } + } + + /* Remove element from map to add because a entry for this GPIO + * already exists */ + gpioMap.erase(gpioIdToCheck); + + } + return HasReturnvaluesIF::RETURN_OK; } diff --git a/linux/gpio/LinuxLibgpioIF.h b/linux/gpio/LinuxLibgpioIF.h index 03c78fdb..287e157d 100644 --- a/linux/gpio/LinuxLibgpioIF.h +++ b/linux/gpio/LinuxLibgpioIF.h @@ -17,14 +17,21 @@ class GpioCookie; class LinuxLibgpioIF : public GpioIF, public SystemObject { public: - static const uint8_t INTERFACE_ID = CLASS_ID::LINUX_LIBGPIO_IF; + static const uint8_t gpioRetvalId = CLASS_ID::LINUX_LIBGPIO_IF; - static const ReturnValue_t DRIVE_GPIO_FAILURE = MAKE_RETURN_CODE(0x2); + static constexpr ReturnValue_t UNKNOWN_GPIO_ID = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 1); + static constexpr ReturnValue_t DRIVE_GPIO_FAILURE = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 2); + static constexpr ReturnValue_t GPIO_TYPE_FAILURE = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 3); + static constexpr ReturnValue_t GPIO_INVALID_INSTANCE = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4); LinuxLibgpioIF(object_id_t objectId); virtual ~LinuxLibgpioIF(); - ReturnValue_t initialize(GpioCookie* gpioCookie) override; + ReturnValue_t addGpios(GpioCookie* gpioCookie) override; ReturnValue_t pullHigh(gpioId_t gpioId) override; ReturnValue_t pullLow(gpioId_t gpioId) override; ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override; @@ -40,7 +47,9 @@ private: * @param gpioId The GPIO ID of the GPIO to drive. * @param logiclevel The logic level to set. O or 1. */ - ReturnValue_t driveGpio(gpioId_t gpioId, unsigned int logiclevel); + ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegular* regularGpio, unsigned int logiclevel); + + ReturnValue_t configureRegularGpio(gpioId_t gpioId, GpiodRegular* regularGpio); /** * @brief This function checks if GPIOs are already registered and whether @@ -53,6 +62,8 @@ private: */ ReturnValue_t checkForConflicts(GpioMap& mapToAdd); + ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegular* regularGpio); + /** * @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd. */ diff --git a/linux/gpio/gpioDefinitions.h b/linux/gpio/gpioDefinitions.h index 28ad1239..e4fb89bc 100644 --- a/linux/gpio/gpioDefinitions.h +++ b/linux/gpio/gpioDefinitions.h @@ -12,6 +12,17 @@ enum Direction { OUT = 1 }; +enum GpioOperation { + READ, + WRITE +}; + +enum GpioTypes { + NONE, + GPIOD_REGULAR, + CALLBACK +}; + static constexpr gpioId_t NO_GPIO = -1; } @@ -29,23 +40,52 @@ static constexpr gpioId_t NO_GPIO = -1; * @param lineHandle The handle returned by gpiod_chip_get_line will be later written to this * pointer. */ -typedef struct GpioConfig { - GpioConfig(): chipname(), lineNum(0), consumer(), direction(gpio::Direction::OUT), - initValue(0) {}; +class GpioBase { +public: - GpioConfig(std::string chipname_, int lineNum_, std::string consumer_, - gpio::Direction direction_, int initValue_): - chipname(chipname_), lineNum(lineNum_), consumer(consumer_), - direction(direction_), initValue(initValue_) {} - std::string chipname; - int lineNum; + GpioBase() = default; + + GpioBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction, + int initValue): + gpioType(gpioType), consumer(consumer),direction(direction), initValue(initValue) {} + + virtual~ GpioBase() {}; + + /* Can be used to cast GpioBase to a concrete child implementation */ + gpio::GpioTypes gpioType = gpio::GpioTypes::NONE; std::string consumer; - gpio::Direction direction; - int initValue; - struct gpiod_line* lineHandle = nullptr; -} GpioConfig_t; + gpio::Direction direction = gpio::Direction::IN; + int initValue = 0; +}; -using GpioMap = std::unordered_map; +class GpiodRegular: public GpioBase { +public: + GpiodRegular(): GpioBase() {}; + + GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_, + gpio::Direction direction_, int initValue_): + GpioBase(gpio::GpioTypes::GPIOD_REGULAR, consumer_, direction_, initValue_), + chipname(chipname_), lineNum(lineNum_) {} + std::string chipname; + int lineNum = 0; + struct gpiod_line* lineHandle = nullptr; +}; + +class GpioCallback: public GpioBase { +public: + GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_, + void (* callback) (gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args), + void* callbackArgs): + GpioBase(gpio::GpioTypes::CALLBACK, consumer, direction_, initValue_), + callback(callback), callbackArgs(callbackArgs) {} + + void (* callback) (gpioId_t gpioId, gpio::GpioOperation gpioOp, + int value, void* args) = nullptr; + void* callbackArgs = nullptr; +}; + + +using GpioMap = std::unordered_map; using GpioMapIter = GpioMap::iterator; #endif /* LINUX_GPIO_GPIODEFINITIONS_H_ */ diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index a78478e5..5ce1558a 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -39,7 +39,7 @@ ReturnValue_t SolarArrayDeploymentHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - result = gpioInterface->initialize(dynamic_cast(gpioCookie)); + result = gpioInterface->addGpios(dynamic_cast(gpioCookie)); if (result != RETURN_OK) { sif::error << "SolarArrayDeploymentHandler::initialize: Failed to initialize Gpio interface" << std::endl; -- 2.43.0 From ed40ed70ccbff4b2cafb581004b16d8b3a0240c2 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:27:02 +0100 Subject: [PATCH 24/34] bugfix --- linux/gpio/gpioDefinitions.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux/gpio/gpioDefinitions.h b/linux/gpio/gpioDefinitions.h index e4fb89bc..3b0f70fd 100644 --- a/linux/gpio/gpioDefinitions.h +++ b/linux/gpio/gpioDefinitions.h @@ -60,7 +60,8 @@ public: class GpiodRegular: public GpioBase { public: - GpiodRegular(): GpioBase() {}; + GpiodRegular(): GpioBase(gpio::GpioTypes::GPIOD_REGULAR, std::string(), + gpio::Direction::IN, 0) {}; GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_, gpio::Direction direction_, int initValue_): -- 2.43.0 From c406133ae687b1ec4534283c599b0adf3c05747d Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:33:12 +0100 Subject: [PATCH 25/34] printf supportt --- linux/spi/SpiComIF.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index ebcf7991..25dd5ad5 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -188,8 +188,14 @@ ReturnValue_t SpiComIF::sendMessage(CookieIF *cookie, const uint8_t *sendData, s else { /* We write with a blocking transfer here */ if (write(fileDescriptor, sendData, sendLen) != static_cast(sendLen)) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "SpiComIF::sendMessage: Half-Duplex write operation failed!" << std::endl; +#else + sif::printWarning("SpiComIF::sendMessage: Half-Duplex write operation failed!\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ result = HALF_DUPLEX_TRANSFER_FAILED; } } @@ -238,7 +244,13 @@ ReturnValue_t SpiComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLe } if(read(fileDescriptor, rxBuf, readSize) != static_cast(readSize)) { +#if FSFW_VERBOSE_LEVEL >= 1 +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "SpiComIF::sendMessage: Half-Duplex read operation failed!" << std::endl; +#else + sif::printWarning("SpiComIF::sendMessage: Half-Duplex read operation failed!\n"); +#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */ +#endif /* FSFW_VERBOSE_LEVEL >= 1 */ result = HALF_DUPLEX_TRANSFER_FAILED; } -- 2.43.0 From dfe2c81ecd4f3e29fb0412d1e33a7fa76c45ea9b Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:34:02 +0100 Subject: [PATCH 26/34] cleaned up includes --- linux/spi/SpiComIF.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/linux/spi/SpiComIF.cpp b/linux/spi/SpiComIF.cpp index 25dd5ad5..cc2d9288 100644 --- a/linux/spi/SpiComIF.cpp +++ b/linux/spi/SpiComIF.cpp @@ -1,16 +1,18 @@ #include "SpiComIF.h" #include "spiDefinitions.h" +#include #include + #include +#include + +#include #include #include #include -#include -#include -#include -#include +#include #include SpiComIF::SpiComIF(object_id_t objectId, GpioIF* gpioComIF): SystemObject(objectId), -- 2.43.0 From 46495dd123eb6ce544319e5af3a54241667f6106 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:34:34 +0100 Subject: [PATCH 27/34] deleted unused code --- linux/spi/SpiComIF.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/linux/spi/SpiComIF.h b/linux/spi/SpiComIF.h index b91dd479..e454db21 100644 --- a/linux/spi/SpiComIF.h +++ b/linux/spi/SpiComIF.h @@ -54,19 +54,7 @@ private: SpiDeviceMap spiDeviceMap; -// /** -// * @brief This function opens an SPI device and binds the opened file -// * to a specific SPI address. -// * @param deviceFile The name of the device file. E.g. spi-0 -// * @param i2cAddress The address of the SPI slave device. -// * @param fileDescriptor Pointer to device descriptor. -// * @return RETURN_OK if successful, otherwise RETURN_FAILED. -// */ -// ReturnValue_t openDevice(std::string deviceFile, int* fileDescriptor, bool nonBlocking = false); - ReturnValue_t getReadBuffer(address_t spiAddress, uint8_t** buffer); }; - - #endif /* LINUX_SPI_SPICOMIF_H_ */ -- 2.43.0 From 06173eeb0303c7baa03bfaf25dec564b6f15d307 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:38:43 +0100 Subject: [PATCH 28/34] small fixes for Q7S --- bsp_q7s/ObjectFactory.cpp | 20 +++++++++---------- bsp_q7s/devices/HeaterHandler.cpp | 2 +- .../devices/SolarArrayDeploymentHandler.cpp | 14 +++++++------ mission/devices/SolarArrayDeploymentHandler.h | 2 +- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/bsp_q7s/ObjectFactory.cpp b/bsp_q7s/ObjectFactory.cpp index 1a54ca34..d69683ef 100644 --- a/bsp_q7s/ObjectFactory.cpp +++ b/bsp_q7s/ObjectFactory.cpp @@ -119,37 +119,37 @@ void ObjectFactory::produce(){ new LinuxLibgpioIF(objects::GPIO_IF); #if TE0720 == 0 /* Pin H2-11 on stack connector */ - GpioConfig_t gpioConfigHeater0(std::string("gpiochip7"), 18, + GpiodRegular gpioConfigHeater0(std::string("gpiochip7"), 18, std::string("Heater0"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_0, gpioConfigHeater0); /* Pin H2-12 on stack connector */ - GpioConfig_t gpioConfigHeater1(std::string("gpiochip7"), 14, + GpiodRegular gpioConfigHeater1(std::string("gpiochip7"), 14, std::string("Heater1"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_1, gpioConfigHeater1); /* Pin H2-13 on stack connector */ - GpioConfig_t gpioConfigHeater2(std::string("gpiochip7"), 20, + GpiodRegular gpioConfigHeater2(std::string("gpiochip7"), 20, std::string("Heater2"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_2, gpioConfigHeater2); - GpioConfig_t gpioConfigHeater3(std::string("gpiochip7"), 16, + GpiodRegular gpioConfigHeater3(std::string("gpiochip7"), 16, std::string("Heater3"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_3, gpioConfigHeater3); - GpioConfig_t gpioConfigHeater4(std::string("gpiochip7"), 24, + GpiodRegular gpioConfigHeater4(std::string("gpiochip7"), 24, std::string("Heater4"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_4, gpioConfigHeater4); - GpioConfig_t gpioConfigHeater5(std::string("gpiochip7"), 26, + GpiodRegular gpioConfigHeater5(std::string("gpiochip7"), 26, std::string("Heater5"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_5, gpioConfigHeater5); - GpioConfig_t gpioConfigHeater6(std::string("gpiochip7"), 22, + GpiodRegular gpioConfigHeater6(std::string("gpiochip7"), 22, std::string("Heater6"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_6, gpioConfigHeater6); - GpioConfig_t gpioConfigHeater7(std::string("gpiochip7"), 28, + GpiodRegular gpioConfigHeater7(std::string("gpiochip7"), 28, std::string("Heater7"), gpio::OUT, 0); heaterGpiosCookie->addGpio(gpioIds::HEATER_7, gpioConfigHeater7); @@ -157,10 +157,10 @@ void ObjectFactory::produce(){ pcduSwitches::TCS_BOARD_8V_HEATER_IN); GpioCookie* solarArrayDeplCookie = new GpioCookie; - GpioConfig_t gpioConfigDeplSA1(std::string("gpiochip7"), 25, + GpiodRegular gpioConfigDeplSA1(std::string("gpiochip7"), 25, std::string("DeplSA1"), gpio::OUT, 0); solarArrayDeplCookie->addGpio(gpioIds::DEPLSA1, gpioConfigDeplSA1); - GpioConfig_t gpioConfigDeplSA2(std::string("gpiochip7"), 23, + GpiodRegular gpioConfigDeplSA2(std::string("gpiochip7"), 23, std::string("DeplSA2"), gpio::OUT, 0); solarArrayDeplCookie->addGpio(gpioIds::DEPLSA2, gpioConfigDeplSA2); diff --git a/bsp_q7s/devices/HeaterHandler.cpp b/bsp_q7s/devices/HeaterHandler.cpp index 2387ab2a..ccf5b65c 100644 --- a/bsp_q7s/devices/HeaterHandler.cpp +++ b/bsp_q7s/devices/HeaterHandler.cpp @@ -43,7 +43,7 @@ ReturnValue_t HeaterHandler::initialize() { return ObjectManagerIF::CHILD_INIT_FAILED; } - result = gpioInterface->initialize(dynamic_cast(gpioCookie)); + result = gpioInterface->addGpios(dynamic_cast(gpioCookie)); if (result != RETURN_OK) { sif::error << "HeaterHandler::initialize: Failed to initialize Gpio interface" << std::endl; return ObjectManagerIF::CHILD_INIT_FAILED; diff --git a/mission/devices/SolarArrayDeploymentHandler.cpp b/mission/devices/SolarArrayDeploymentHandler.cpp index 5ce1558a..c114209b 100644 --- a/mission/devices/SolarArrayDeploymentHandler.cpp +++ b/mission/devices/SolarArrayDeploymentHandler.cpp @@ -1,15 +1,17 @@ -#include -#include -#include +#include #include + +#include #include +#include + SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_, object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_, uint8_t mainLineSwitch_, gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs) : - SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), mainLineSwitcherObjectId( - mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), deplSA1(deplSA1), deplSA2( - deplSA2), burnTimeMs(burnTimeMs), actionHelper(this, nullptr) { + SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_), + mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_), + deplSA1(deplSA1), deplSA2(deplSA2), burnTimeMs(burnTimeMs), actionHelper(this, nullptr) { commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE); } diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index 279ae5da..f885928b 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -115,7 +115,7 @@ private: gpioId_t deplSA1; gpioId_t deplSA2; - GpioIF* gpioInterface; + GpioIF* gpioInterface = nullptr; /** Time duration switches are active to cut the burn wire */ uint32_t burnTimeMs; -- 2.43.0 From bbd6a3633223eb7a1dfe68464f6b4b5db00b2a1e Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 13:39:01 +0100 Subject: [PATCH 29/34] redordered includes --- mission/devices/SolarArrayDeploymentHandler.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mission/devices/SolarArrayDeploymentHandler.h b/mission/devices/SolarArrayDeploymentHandler.h index f885928b..b7e94f23 100644 --- a/mission/devices/SolarArrayDeploymentHandler.h +++ b/mission/devices/SolarArrayDeploymentHandler.h @@ -1,6 +1,8 @@ #ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ #define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ +#include + #include #include #include @@ -9,7 +11,7 @@ #include #include #include -#include + #include /** -- 2.43.0 From e25e473c323f988ebc1c11a6445969c455f70abe Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 14:41:40 +0100 Subject: [PATCH 30/34] fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index a3d245f5..8eb25c02 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit a3d245f5a030c9450c516552283d26da2c799301 +Subproject commit 8eb25c02aa278bda46d0c3769500bddbddc989f5 -- 2.43.0 From f65e28d33bf22a0ea0c8598431b3f4bcaa5545dd Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 14:41:57 +0100 Subject: [PATCH 31/34] fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 8eb25c02..c55cf8f2 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 8eb25c02aa278bda46d0c3769500bddbddc989f5 +Subproject commit c55cf8f2796026818841266b78f3b6ad37aba3c8 -- 2.43.0 From 09ff131133e50ac4b3d014412ad35edb1a31ed1c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 14:44:16 +0100 Subject: [PATCH 32/34] libgpiod test --- linux/boardtest/LibgpiodTest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/linux/boardtest/LibgpiodTest.cpp b/linux/boardtest/LibgpiodTest.cpp index 99602107..d085671a 100644 --- a/linux/boardtest/LibgpiodTest.cpp +++ b/linux/boardtest/LibgpiodTest.cpp @@ -58,7 +58,7 @@ ReturnValue_t LibgpiodTest::performOneShotAction() { case(TestCases::LOOPBACK): { result = gpioInterface->pullHigh(gpioIds::TEST_ID_0); if(result == HasReturnvaluesIF::RETURN_OK) { - sif::info << "LibgpiodTest::performOneShotAction:" + sif::info << "LibgpiodTest::performOneShotAction: " "GPIO pulled high successfully for loopback test" << std::endl; } else { @@ -68,7 +68,7 @@ ReturnValue_t LibgpiodTest::performOneShotAction() { } result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState); if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 1) { - sif::info << "LibgpiodTest::performOneShotAction:" + sif::info << "LibgpiodTest::performOneShotAction: " "GPIO state read successfully and is high" << std::endl; } else { @@ -79,12 +79,12 @@ ReturnValue_t LibgpiodTest::performOneShotAction() { result = gpioInterface->pullLow(gpioIds::TEST_ID_0); if(result == HasReturnvaluesIF::RETURN_OK) { - sif::info << "LibgpiodTest::performOneShotAction:" + sif::info << "LibgpiodTest::performOneShotAction: " "GPIO pulled low successfully for loopback test" << std::endl; } result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState); if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 0) { - sif::info << "LibgpiodTest::performOneShotAction:" + sif::info << "LibgpiodTest::performOneShotAction: " "GPIO state read successfully and is low" << std::endl; } else { -- 2.43.0 From 42486576804985658fb6d56e8afa9320d34ea523 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 14:47:38 +0100 Subject: [PATCH 33/34] fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index c55cf8f2..91f69aa3 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit c55cf8f2796026818841266b78f3b6ad37aba3c8 +Subproject commit 91f69aa34fcdde9d3f6ae1a71e72a084bf3bc49d -- 2.43.0 From 2fe3e7a74ae6dd4038d0d156f65a96273246e734 Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Tue, 23 Feb 2021 14:50:08 +0100 Subject: [PATCH 34/34] fsfw update --- fsfw | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fsfw b/fsfw index 91f69aa3..8b561d07 160000 --- a/fsfw +++ b/fsfw @@ -1 +1 @@ -Subproject commit 91f69aa34fcdde9d3f6ae1a71e72a084bf3bc49d +Subproject commit 8b561d073c5a664bae2a901c142fcb2e10faf539 -- 2.43.0