diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index 43cd63ce..3f8e1f3c 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -122,7 +122,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpioByLineName(gpioId_t gpioId, int result = gpiod_ctxless_find_line(lineName.c_str(), chipname, MAX_CHIPNAME_LENGTH, &lineOffset); - if (result != LINE_FOUND) { + if (result != LINE_FOUND) { parseFindeLineResult(result, lineName); return RETURN_FAILED; } @@ -140,7 +140,7 @@ ReturnValue_t LinuxLibgpioIF::configureGpioByLineName(gpioId_t gpioId, } ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, struct gpiod_chip* chip, - GpiodRegularBase& regularGpio, std::string failOutput) { + GpiodRegularBase& regularGpio, std::string failOutput) { unsigned int lineNum; gpio::Direction direction; std::string consumer; @@ -165,22 +165,10 @@ ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, struct gpiod case(gpio::OUT): { result = gpiod_line_request_output(lineHandle, consumer.c_str(), regularGpio.initValue); - if (result < 0) { - sif::error << "LinuxLibgpioIF::configureRegularGpio: 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: { @@ -189,6 +177,18 @@ ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, struct gpiod return GPIO_INVALID_INSTANCE; } + if (result < 0) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::error << "LinuxLibgpioIF::configureRegularGpio: Failed to request line " << + lineNum << " from GPIO instance with ID: " << gpioId << std::endl; +#else + sif::printError("LinuxLibgpioIF::configureRegularGpio: " + "Failed to request line %d from GPIO instance with ID: %d\n", lineNum, gpioId); +#endif + gpiod_line_release(lineHandle); + return RETURN_FAILED; + } + } /** * Write line handle to GPIO configuration instance so it can later be used to set or @@ -230,7 +230,11 @@ ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) { ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) { gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "LinuxLibgpioIF::pullLow: Unknown GPIO ID " << gpioId << std::endl; +#else + sif::printWarning("LinuxLibgpioIF::pullLow: Unknown GPIO ID %d\n", gpioId); +#endif return UNKNOWN_GPIO_ID; } @@ -260,8 +264,13 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio, gpio::Levels logicLevel) { int result = gpiod_line_set_value(regularGpio.lineHandle, logicLevel); if (result < 0) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId << " to logic level " << logicLevel << std::endl; +#else + sif::printWarning("LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID %d to " + "logic level %d\n", gpioId, logicLevel); +#endif return DRIVE_GPIO_FAILURE; } @@ -271,7 +280,11 @@ ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { gpioMapIter = gpioMap.find(gpioId); if (gpioMapIter == gpioMap.end()){ +#if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl; +#else + sif::printWarning("LinuxLibgpioIF::readGpio: Unknown GPIOD ID %d\n", gpioId); +#endif return UNKNOWN_GPIO_ID; } @@ -299,13 +312,14 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ for(auto& gpioConfig: mapToAdd) { switch(gpioConfig.second->gpioType) { case(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP): - case(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL): { + case(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL): + case(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME): { auto regularGpio = dynamic_cast(gpioConfig.second); if(regularGpio == nullptr) { return GPIO_TYPE_FAILURE; } - /* Check for conflicts and remove duplicates if necessary */ - result = checkForConflictsRegularGpio(gpioConfig.first, *regularGpio, mapToAdd); + // Check for conflicts and remove duplicates if necessary + result = checkForConflictsById(gpioConfig.first, gpioConfig.second->gpioType, mapToAdd); if(result != HasReturnvaluesIF::RETURN_OK) { status = result; } @@ -316,15 +330,22 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ if(callbackGpio == nullptr) { return GPIO_TYPE_FAILURE; } - /* Check for conflicts and remove duplicates if necessary */ - result = checkForConflictsCallbackGpio(gpioConfig.first, callbackGpio, mapToAdd); + // Check for conflicts and remove duplicates if necessary + result = checkForConflictsById(gpioConfig.first, + gpioConfig.second->gpioType, mapToAdd); if(result != HasReturnvaluesIF::RETURN_OK) { status = result; } break; } default: { - +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "Invalid GPIO type detected for GPIO ID " << gpioConfig.first + << std::endl; +#else + sif::printWarning("Invalid GPIO type detected for GPIO ID %d\n", gpioConfig.first); +#endif + status = GPIO_TYPE_FAILURE; } } } @@ -332,68 +353,86 @@ ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){ } -ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck, - GpiodRegularBase& gpioToCheck, GpioMap& mapToAdd) { - /* Cross check with private map */ +ReturnValue_t LinuxLibgpioIF::checkForConflictsById(gpioId_t gpioIdToCheck, + gpio::GpioTypes expectedType, GpioMap& mapToAdd) { + // Cross check with private map gpioMapIter = gpioMap.find(gpioIdToCheck); if(gpioMapIter != gpioMap.end()) { auto& gpioType = gpioMapIter->second->gpioType; - if(gpioType != gpio::GpioTypes::GPIO_REGULAR_BY_CHIP and - gpioType != gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { - sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different " - "GPIO type" << gpioIdToCheck << ". Removing duplicate." << std::endl; + bool eraseDuplicateDifferentType = false; + switch(expectedType) { + case(gpio::GpioTypes::NONE): { + break; + } + case(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP): + case(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL): + case(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME): { + if(gpioType == gpio::GpioTypes::NONE or gpioType == gpio::GpioTypes::CALLBACK) { + eraseDuplicateDifferentType = true; + } + break; + } + case(gpio::GpioTypes::CALLBACK): { + if(gpioType != gpio::GpioTypes::CALLBACK) { + eraseDuplicateDifferentType = true; + } + } + } + if(eraseDuplicateDifferentType) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for " + "different GPIO type " << gpioIdToCheck << + ". Removing duplicate from map to add" << std::endl; +#else + sif::printWarning("LinuxLibgpioIF::checkForConflicts: ID already exists for " + "different GPIO type %d. Removing duplicate from map to add\n", gpioIdToCheck); +#endif mapToAdd.erase(gpioIdToCheck); - return HasReturnvaluesIF::RETURN_OK; - } - auto ownRegularGpio = dynamic_cast(gpioMapIter->second); - if(ownRegularGpio == nullptr) { - return GPIO_TYPE_FAILURE; + return GPIO_DUPLICATE_DETECTED; } - /* Remove element from map to add because a entry for this GPIO - already exists */ - sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition" - << " detected. Duplicate will be removed from map to add." << std::endl; - mapToAdd.erase(gpioIdToCheck); - } - return HasReturnvaluesIF::RETURN_OK; -} - -ReturnValue_t LinuxLibgpioIF::checkForConflictsCallbackGpio(gpioId_t gpioIdToCheck, - GpioCallback *callbackGpio, GpioMap& mapToAdd) { - /* Cross check with private map */ - gpioMapIter = gpioMap.find(gpioIdToCheck); - if(gpioMapIter != gpioMap.end()) { - if(gpioMapIter->second->gpioType != gpio::GpioTypes::CALLBACK) { - sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different " - "GPIO type" << gpioIdToCheck << ". Removing duplicate." << std::endl; - mapToAdd.erase(gpioIdToCheck); - return HasReturnvaluesIF::RETURN_OK; - } - - /* Remove element from map to add because a entry for this GPIO - already exists */ - sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition" - << " detected. Duplicate will be removed from map to add." << std::endl; + // Remove element from map to add because a entry for this GPIO already exists +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO " + "definition with ID " << gpioIdToCheck << " detected. " << + "Duplicate will be removed from map to add" << std::endl; +#else + sif::printWarning("LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition " + "with ID %d detected. Duplicate will be removed from map to add\n", gpioIdToCheck); +#endif mapToAdd.erase(gpioIdToCheck); + return GPIO_DUPLICATE_DETECTED; } return HasReturnvaluesIF::RETURN_OK; } void LinuxLibgpioIF::parseFindeLineResult(int result, std::string& lineName) { switch (result) { +#if FSFW_CPP_OSTREAM_ENABLED == 1 case LINE_NOT_EXISTS: - sif::warning << "LinuxLibgpioIF::parseFindeLineResult: Line with name " << lineName - << " does not exist" << std::endl; + case LINE_ERROR: { + sif::warning << "LinuxLibgpioIF::parseFindeLineResult: Line with name " << lineName << + " does not exist" << std::endl; break; - case LINE_ERROR: - sif::warning << "LinuxLibgpioIF::parseFindeLineResult: " << "Line with name " - << lineName << " does not exist" << std::endl; + } + default: { + sif::warning << "LinuxLibgpioIF::parseFindeLineResult: Unknown return code for line " + "with name " << lineName << std::endl; break; - default: - sif::warning << "LinuxLibgpioIF::parseFindeLineResult: Unknown return code for line with " - << "name " << lineName << std::endl; + } +#else + case LINE_NOT_EXISTS: + case LINE_ERROR: { + sif::printWarning("LinuxLibgpioIF::parseFindeLineResult: Line with name %s " + "does not exist\n", lineName); break; } + default: { + sif::printWarning("LinuxLibgpioIF::parseFindeLineResult: Unknown return code for line " + "with name %s\n", lineName); + break; + } +#endif + } } diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h index d458c362..6489d749 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h @@ -28,6 +28,8 @@ public: HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 3); static constexpr ReturnValue_t GPIO_INVALID_INSTANCE = HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4); + static constexpr ReturnValue_t GPIO_DUPLICATE_DETECTED = + HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 5); LinuxLibgpioIF(object_id_t objectId); virtual ~LinuxLibgpioIF(); @@ -75,10 +77,9 @@ private: */ ReturnValue_t checkForConflicts(GpioMap& mapToAdd); - ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegularBase& regularGpio, + ReturnValue_t checkForConflictsById(gpioId_t gpiodId, gpio::GpioTypes type, GpioMap& mapToAdd); - ReturnValue_t checkForConflictsCallbackGpio(gpioId_t gpiodId, GpioCallback* regularGpio, - GpioMap& mapToAdd); + //ReturnValue_t checkForConflictsCallbackGpio(gpioId_t gpiodId, GpioMap& mapToAdd); /** * @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd.