GPOS прерывания sysfs

У меня возникли некоторые проблемы с функцией C++, которую я использую для отслеживания прерываний GPIO на обычном устройстве Linux. Я передаю прямоугольный сигнал известной частоты на вывод GPIO, но результат вывода следующего кода ошибочен. Если я установлю метод определения края на "падение", рассчитанная частота будет правильной. Однако, если я использую обнаружение "повышения", выходная частота является спорадической и неправильной. Я хотел бы иметь возможность использовать "оба" для расчета коэффициента заполнения.

int gpio::interrupts(string gpioNumber)
{
    int fd;
    int retval;
    struct timeval holder;
    struct timeval tvCurrent;
    double usPrevious;
    double usCurrent;
    double diff;
    struct pollfd pfd;
    char buf[64];
    int error = -1;

    string openD = "/sys/class/gpio/gpio" + gpioNumber + "/value";
    error = fd = open(openD.c_str(), O_RDONLY);

    while (error < 0) {
        error = fd = open(openD.c_str(), O_RDONLY);
    }

    pfd.fd = fd;
    pfd.events = POLLPRI;

    lseek(fd, 0, SEEK_SET);

    while(1) {
        retval = poll(&pfd, 1, -1);
        if (pfd.revents & POLLPRI) {

            lseek(fd, 0, SEEK_SET);

            retval = read(fd, buf, sizeof buf);

            //The following std::cout will be discussed in the following section
            //std::cout << "Thread: " << std::this_thread::get_id() << " GPIO: " << gpioNumber << " Value : " << retval << std::endl;

            gettimeofday(&tvCurrent, NULL);

            //tvPrevious is a list of lists declared in the header
            if (tvPrevious[std::stoi(gpioNumber)][0] != 0 && tvPrevious[std::stoi(gpioNumber)][1] != 0) {
                usPrevious = (tvPrevious[std::stoi(gpioNumber)][0]*1e6) + tvPrevious[std::stoi(gpioNumber)][1];
                usCurrent = (tvCurrent.tv_sec*1e6) + tvCurrent.tv_usec;

                diff = (usCurrent - usPrevious)/1e6;

                //Replace the previous frequency record for this gpio
                //in the existing list. The list is declared in the header
                //and initialised in another function
                gpioFrequencies.replace(std::stoi(gpioNumber), 1/diff);

                emit gpioFrequenciesChanged();

                tvPrevious[std::stoi(gpioNumber)][0] = tvCurrent.tv_sec;
                tvPrevious[std::stoi(gpioNumber)][1] = tvCurrent.tv_usec;

                tvCurrent.tv_sec = 0;
                tvCurrent.tv_usec = 0;

            } else {
                gettimeofday(&holder, NULL);
                tvPrevious[std::stoi(gpioNumber)][0] = holder.tv_sec;
                tvPrevious[std::stoi(gpioNumber)][1] = holder.tv_usec;
                holder.tv_sec = 0;
                holder.tv_usec = 0;
            }
        }
    }

    return 0;
}

Вторая проблема, с которой я столкнулся в приведенном выше коде, заключается в чтении значения gpio из файла /sys/class/gpio/gpioX/value. Комментируемый std::cout в приведенном выше коде используется для проверки того, что каждый gpio работает в отдельном отдельном потоке, и для чтения значения файла / значения gpio. Использую ли я "повышение", "падение" или "оба" для обнаружения края, значение retval всегда 2. Я ожидаю, что значение будет 1 (ВЫСОКОЕ) или 0 (НИЗКОЕ).

Итак, два моих вопроса следующие:

  1. Как я могу изменить вышеприведенный код, чтобы обеспечить не только обнаружение "падения", но и "повышение" и "оба"?
  2. Как я могу изменить приведенный выше код, чтобы обеспечить успешное, правильное чтение файла / значения после запуска прерывания?

РЕДАКТИРОВАТЬ: я ответил на вопрос 2 (чтение значения GPIO), добавив следующие строки после retval = read(fd, buf, sizeof buf);:

buf[1]='\0';
string output = string(buf);

output теперь содержит правильное значение 1 (HIGH) или 0 (LOW) указанного GPIO.

РЕДАКТИРОВАТЬ 2: Я только что определил, что причина колебания частоты была из-за моих периодов измерения вычисления частоты и для нарастающего и для падающего фронта. Я добавил if (std::stoi(string(buf) > 0) Заявление до расчета периода, и теперь частота измеряется правильно.

0 ответов

Другие вопросы по тегам