Набор микросхем Intel - программирование GPIO

Из спецификации я знал следующую информацию:

JGPIO1 PIN# :10

SoC GPIO # : 71 

USE select: IO 0x532[7] ( 0 = native function, 1 = GPIO )

IO select: IO 0x536[7] (0 = output, 1 = input )

Level: IO 0x540[7] ( 0 = low, 1= high )

В этом случае я хочу запрограммировать контакт GPIO № 10. Есть ли какой-нибудь пример или пример кода, на который я могу сослаться?

Я могу сделать это через RW-все [1]. Однако это в Windows.

Я хочу сделать это на C и в среде Linux.

Пожалуйста, порекомендуйте.

===============================================================

Например, если я хочу установить

7-й бит в 1 по адресу 0x532

7-й бит равен 0 в 0x536

7-й бит равен 1 по адресу 0x540.


person user3815726    schedule 03.12.2015    source источник
comment
Я хочу запрограммировать GPIO... -- В ядре или в пространстве пользователя? кажется, они отличаются от того, что я ожидаю -- Что вы ожидаете получить (что бы это ни значило)? Что у вас есть на самом деле?   -  person sawdust    schedule 03.12.2015
comment
@sawdust 1. В пользовательском пространстве 2. Должен ли я иметь функцию, которая требует, чтобы параметры включали адрес и бит? 3. Я думал, что приведенной выше информации достаточно для программирования GPIO, разве этого недостаточно? что еще я должен предоставить?   -  person user3815726    schedule 03.12.2015
comment
Вопросы @sawdust обновлены. Пожалуйста, если вам все еще непонятно. Это мое первое программирование GPIO, так что еще нужно чему-то научиться.   -  person user3815726    schedule 03.12.2015
comment
Программы пользовательского пространства Linux обычно получают доступ к GPIO с помощью sysfs. Вы смотрели на это?   -  person sawdust    schedule 03.12.2015
comment
@sawdust Вы имеете в виду /sys/class/gpio?   -  person user3815726    schedule 03.12.2015
comment
Да, sysfs относится к специальной файловой системе, смонтированной в /sys.   -  person sawdust    schedule 03.12.2015
comment
@sawdust да, я проходил через это раньше. black-swift.com/ wiki/index.php?title=Working_with_GPIOs_%28C/   -  person user3815726    schedule 03.12.2015
comment
В нем упоминается использование эха в первую очередь. эхо 27 › /sys/class/gpio/export . Итак, в моем случае, я должен эхо 10 или 71 в моем эксперименте.   -  person user3815726    schedule 03.12.2015
comment
Изучите Documentation/gpio/sysfs.txt. Вам необходимо сопоставить выводы, которые вы хотите использовать, с выводами в регистрах с именем /sys/class/gpio/gpiochipN.   -  person sawdust    schedule 03.12.2015
comment
@sawdust, вы можете ответить как ответ, чтобы я мог проверить ваш ответ.   -  person user3815726    schedule 03.12.2015
comment
Давайте продолжим обсуждение в чате.   -  person user3815726    schedule 04.12.2015


Ответы (2)


В пользовательском пространстве Linux типичным методом доступа к GPIO является псевдофайловая система /sys (она же sysfs). Это предлагает несколько переносимый интерфейс, который пытается свести к минимуму аппаратные зависимости и избежать конфликтов с драйверами устройств.

Чтобы определить номера GPIO, к которым вы хотите получить доступ на своей плате, вам необходимо обратиться к документации по SoC. Имена каталогов в /sys/class/gpio/ должны быть идентифицированы с их эквивалентами аппаратного регистра. Эти имена каталогов будут иметь вид gpiochipN, где N — базовый номер GPIO в этом регистре. Файл gpiochipN/label должен помочь идентифицировать регистр, например. по его (памяти или порту) адресу.

Обратите внимание, что N не может начинаться с 0. В системе Intel BayTrail первым каталогом может быть gpiochip82, поэтому GPIO с наименьшим номером будет 82. Номер бита регистра должен быть добавлен к базе номер, чтобы получить номер GPIO.

См. Интерфейс Sysfs для пользовательского пространства для официальной документации.

Я могу сделать это через RW-все 1. Однако это в Windows.

Подобная программа, вероятно, может быть написана для выполнения под Linux. Однако программы для Linux (в отличие от Windows, ориентированной на x86) должны быть переносимы на другие архитектуры, поэтому такую ​​программу, которая должна знать низкоуровневые сведения об оборудовании, практически невозможно писать/обслуживать. Одна из целей драйверов устройств состоит в том, чтобы изолировать/модулировать такие детали аппаратного обеспечения, и такая программа пытается обойти эти драйверы!

Кроме того, использование такой программы может сделать систему нестабильной или неисправной. Возиться с памятью и/или регистрами устройства небезопасно в работающей системе. FWIW Я написал утилиту, которая сообщает о конфигурации контактов для одного конкретного SoC, но она только читает регистры и никогда не изменяет никаких настроек.

Обратите внимание, что большая часть документации SoC (а также Linux) рассматривает управление выводами и конфигурацию как отдельную (но тесно связанную, если не пересекающуюся) подсистему с GPIO. Контроль и настройка булавки обычно включают:

  • мультиплексирование вывода для различных периферийных устройств/функционала,
  • направленность (т.е. вход или выход),
  • подключение подтягивающих или подтягивающих резисторов,
  • входная фильтрация (т. е. устранение сбоев),
  • выходной привод (например, открытый сток) и
  • прерывание управления.

Подсистема GPIO обычно обрабатывает:

  • направленность,
  • состояние контакта и
  • прерывание управления.
person sawdust    schedule 04.12.2015
comment
Подход sysfs довольно устарел (но все еще доступен). - person 0andriy; 11.12.2020

Многие встроенные платы поставляются с поддержкой библиотеки EAPI — «Интерфейса встроенного прикладного программирования». Базовая спецификация была разработана PICMG. Вот документ.

Если вы хотите контролировать и/или обнаруживать контакты GPIO из пользовательской программы, этот API, вероятно, даст вам самое простое и быстрое решение.

Вот фрагмент кода, использующий EAPI для включения/выключения произвольного вывода GPO. (нумерация контактов на самом устройстве обычно не соответствует номерам контактов на разъеме заголовка на вашей плате, поэтому вам необходимо перевести «внешние» и «внутренние» номера контактов.

bool
DvmA44I2CGPI::setOutput(int pinNum, bool pinOn)
{
    if (pinNum > NUMPINS)
        return false;

    bool     pinPhyVal = (mReversePolarity) ? !pinOn : pinOn;
    uint32_t       val = (pinPhyVal) ? EAPI_GPIO_HIGH : EAPI_GPIO_LOW;

    uint32_t inputs, outputs;
    EApiStatus_t rc;

    if ((rc = EApiGPIOGetDirectionCaps(EAPI_ID_GPIO_BANK00, &inputs, &outputs)) != EAPI_STATUS_SUCCESS)
    {
        fprintf(stderr, "EApiGPIOGetDirectionCaps() Get Direction Failed: ");
        printStatus(rc);
        return false;
    }


    if ((rc = EApiGPIOSetLevel(mPinMap[pinNum-1], outputs, val)) != EAPI_STATUS_SUCCESS)
    {
        fprintf(stderr, "EApiGPIOSetLevel() Set Level Failed: ");
        printStatus(rc);
        return false;
    }

    return true;
}
person Danny    schedule 10.07.2019