From e7df520780242f98f9a1189906c0ade1a8a99f29 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Thu, 23 Sep 2021 17:54:41 +0200 Subject: [PATCH] fixed merge conflicts --- .../fsfw_hal/common/gpio/gpioDefinitions.h | 29 +++++++ .../fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp | 79 ++++++++++++++++--- hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h | 13 ++- 3 files changed, 107 insertions(+), 14 deletions(-) diff --git a/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h b/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h index 688d9c9b..b030ebc3 100644 --- a/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h +++ b/hal/src/fsfw_hal/common/gpio/gpioDefinitions.h @@ -26,8 +26,10 @@ enum GpioOperation { enum GpioTypes { NONE, + GPIO_REGULAR, GPIO_REGULAR_BY_CHIP, GPIO_REGULAR_BY_LABEL, + GPIO_REGULAR_BY_LINE_NAME, CALLBACK }; @@ -75,6 +77,12 @@ public: int initValue, int lineNum): GpioBase(gpioType, consumer, direction, initValue), lineNum(lineNum) { } + + // line number will be configured at a later point for the open by line name configuration + GpiodRegularBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction, + int initValue): GpioBase(gpioType, consumer, direction, initValue) { + } + int lineNum = 0; struct gpiod_line* lineHandle = nullptr; }; @@ -120,6 +128,27 @@ public: std::string label; }; +/** + * @brief Passing this GPIO configuration to the GPIO IF object will try to open the GPIO by its + * line name. This line name can be set in the device tree and must be unique. Otherwise + * the driver will open the first line with the given name. + */ +class GpiodRegularByLineName: public GpiodRegularBase { +public: + GpiodRegularByLineName(std::string lineName_, std::string consumer_, gpio::Direction direction_, + int initValue_) : + GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_, direction_, + initValue_), lineName(lineName_) { + } + + GpiodRegularByLineName(std::string lineName_, std::string consumer_) : + GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_, gpio::Direction::IN, + gpio::LOW), lineName(lineName_) { + } + + std::string lineName; +}; + class GpioCallback: public GpioBase { public: GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_, diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp index 15c3d118..43cd63ce 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.cpp @@ -66,6 +66,14 @@ ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) { configureGpioByLabel(gpioConfig.first, *regularGpio); break; } + case(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME):{ + auto regularGpio = dynamic_cast(gpioConfig.second); + if(regularGpio == nullptr) { + return GPIO_INVALID_INSTANCE; + } + configureGpioByLineName(gpioConfig.first, *regularGpio); + break; + } case(gpio::GpioTypes::CALLBACK): { auto gpioCallback = dynamic_cast(gpioConfig.second); if(gpioCallback->callback == nullptr) { @@ -84,13 +92,13 @@ ReturnValue_t LinuxLibgpioIF::configureGpioByLabel(gpioId_t gpioId, std::string& label = gpioByLabel.label; struct gpiod_chip* chip = gpiod_chip_open_by_label(label.c_str()); if (chip == nullptr) { - sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open gpio from gpio " + sif::warning << "LinuxLibgpioIF::configureGpioByLabel: Failed to open gpio from gpio " << "group with label " << label << ". Gpio ID: " << gpioId << std::endl; return RETURN_FAILED; } std::string failOutput = "label: " + label; - return configureRegularGpio(gpioId, gpioByLabel.gpioType, chip, gpioByLabel, failOutput); + return configureRegularGpio(gpioId, chip, gpioByLabel, failOutput); } ReturnValue_t LinuxLibgpioIF::configureGpioByChip(gpioId_t gpioId, @@ -98,16 +106,41 @@ ReturnValue_t LinuxLibgpioIF::configureGpioByChip(gpioId_t gpioId, std::string& chipname = gpioByChip.chipname; struct gpiod_chip* chip = gpiod_chip_open_by_name(chipname.c_str()); if (chip == nullptr) { - sif::warning << "LinuxLibgpioIF::configureRegularGpio: Failed to open chip " + sif::warning << "LinuxLibgpioIF::configureGpioByChip: Failed to open chip " << chipname << ". Gpio ID: " << gpioId << std::endl; return RETURN_FAILED; } std::string failOutput = "chipname: " + chipname; - return configureRegularGpio(gpioId, gpioByChip.gpioType, chip, gpioByChip, failOutput); + return configureRegularGpio(gpioId, chip, gpioByChip, failOutput); } -ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, gpio::GpioTypes gpioType, - struct gpiod_chip* chip, GpiodRegularBase& regularGpio, std::string failOutput) { +ReturnValue_t LinuxLibgpioIF::configureGpioByLineName(gpioId_t gpioId, + GpiodRegularByLineName &gpioByLineName) { + std::string& lineName = gpioByLineName.lineName; + char chipname[MAX_CHIPNAME_LENGTH]; + unsigned int lineOffset; + + int result = gpiod_ctxless_find_line(lineName.c_str(), chipname, MAX_CHIPNAME_LENGTH, + &lineOffset); + if (result != LINE_FOUND) { + parseFindeLineResult(result, lineName); + return RETURN_FAILED; + } + + gpioByLineName.lineNum = static_cast(lineOffset); + + struct gpiod_chip* chip = gpiod_chip_open_by_name(chipname); + if (chip == nullptr) { + sif::warning << "LinuxLibgpioIF::configureGpioByLineName: Failed to open chip " + << chipname << ". second->gpioType; - if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or - gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { + if (gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP + or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL + or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME) { auto regularGpio = dynamic_cast(gpioMapIter->second); if(regularGpio == nullptr) { return GPIO_TYPE_FAILURE; @@ -201,8 +235,9 @@ ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) { } auto& gpioType = gpioMapIter->second->gpioType; - if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or - gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { + if (gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP + or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL + or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME) { auto regularGpio = dynamic_cast(gpioMapIter->second); if(regularGpio == nullptr) { return GPIO_TYPE_FAILURE; @@ -239,9 +274,11 @@ ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) { sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl; return UNKNOWN_GPIO_ID; } + auto gpioType = gpioMapIter->second->gpioType; - if(gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP or - gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL) { + if (gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_CHIP + or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LABEL + or gpioType == gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME) { auto regularGpio = dynamic_cast(gpioMapIter->second); if(regularGpio == nullptr) { return GPIO_TYPE_FAILURE; @@ -342,3 +379,21 @@ ReturnValue_t LinuxLibgpioIF::checkForConflictsCallbackGpio(gpioId_t gpioIdToChe } return HasReturnvaluesIF::RETURN_OK; } + +void LinuxLibgpioIF::parseFindeLineResult(int result, std::string& lineName) { + switch (result) { + case LINE_NOT_EXISTS: + 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; + break; + default: + sif::warning << "LinuxLibgpioIF::parseFindeLineResult: Unknown return code for line with " + << "name " << lineName << std::endl; + break; + } + +} diff --git a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h index 31e4a7e8..d458c362 100644 --- a/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h +++ b/hal/src/fsfw_hal/linux/gpio/LinuxLibgpioIF.h @@ -38,6 +38,12 @@ public: ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override; private: + + static const size_t MAX_CHIPNAME_LENGTH = 11; + static const int LINE_NOT_EXISTS = 0; + static const int LINE_ERROR = -1; + static const int LINE_FOUND = 1; + /* Holds the information and configuration of all used GPIOs */ GpioUnorderedMap gpioMap; GpioUnorderedMapIter gpioMapIter; @@ -53,8 +59,10 @@ private: ReturnValue_t configureGpioByLabel(gpioId_t gpioId, GpiodRegularByLabel& gpioByLabel); ReturnValue_t configureGpioByChip(gpioId_t gpioId, GpiodRegularByChip& gpioByChip); - ReturnValue_t configureRegularGpio(gpioId_t gpioId, gpio::GpioTypes gpioType, - struct gpiod_chip* chip, GpiodRegularBase& regularGpio, std::string failOutput); + ReturnValue_t configureGpioByLineName(gpioId_t gpioId, + GpiodRegularByLineName &gpioByLineName); + ReturnValue_t configureRegularGpio(gpioId_t gpioId, struct gpiod_chip* chip, + GpiodRegularBase& regularGpio, std::string failOutput); /** * @brief This function checks if GPIOs are already registered and whether @@ -77,6 +85,7 @@ private: */ ReturnValue_t configureGpios(GpioMap& mapToAdd); + void parseFindeLineResult(int result, std::string& lineName); }; #endif /* LINUX_GPIO_LINUXLIBGPIOIF_H_ */