Raspberry Pi:Типовые проблемы/I2C, SPI, I2S, LIRC, PPS перестали работать? Читайте тут

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


// в процессе обработки

I2C, SPI, I2S, LIRC, PPS перестали работать? Читайте тут[1]

В релизе Raspbian от января 2015 года, включающем поддержку Pi 2, произошел переход на новое ядро (3.18) – в частности, была добавлена дефолтная поддержка дерева устройств. В связи с этим многие вещи, которые раньше работали нормально, вдруг работать перестали, однако если внести ряд изменений, то Pi снова начнет работать нормально. Мы расскажем об этом чуть ниже, но для начала немного справочной информации. Если спешите, то можно сразу перейти к разделу «Решение проблемы».

Первое время Linux распространялся в виде исходного кода либо в виде самого базового ядра плюс исходный код, чтобы с помощью всего этого можно было собрать что-нибудь получше. Одним из шагов в процессе установки была настройка ядра под соответствие вашим требованиям – этот этап следовал за этапом компиляции. Кроме того, он требовал много времени, а новичкам порою казался очень сложным.

Но потом пришел черед Святого Грааля Linux-дистрибутивов – платформно-зависимых (в идеале – универсальных) загрузчиков (U-boot, GRUB и т.д.), базового ядра (по одному на каждую процессорную архитектуру) и набора загружаемых модулей. Поскольку не всякое устройство обладало обнаруживаемыми шинами вроде PCI и USB, в этой почти идеалистической картине не хватало механизма, который описывал бы все остальные устройства. И этим механизмом стало дерево устройств.

Дерево устройств (Device Tree или просто DT) – это способ описания устройств на Linux-платформах (впрочем, это универсальный механизм, и им можно пользоваться и на других ОС). Это иерархическая структура, состоящая из нодов, суб-нодов и свойств. Она в некоторых отношениях отличается от XML, но, к счастью, более читабельна, более лаконична и представлена в стандартном бинарном виде (Flattened Device Tree или FDT), благодаря чему программам проще ее анализировать и манипулировать. Платформы для ПК-процессоров уже многие годы работают с DT, но теперь в эти стройные ряды вступила и SoC-платформа ARM.

Хорошо, но почему Raspberry Pi тоже необходимо использовать дерево устройств? До теперешних пор в код поддержки периферийных карт нужно было добавлять объекты

struct platform_device

. Компиляция этих объектов была условной и выполнялась на базе конфигурационных опций ядра. Однако, чтобы обычные пользователи не смогли компилировать собственные ядра, эти опции включались и в стандартных билдах. Таким образом, при загрузке в систему подгружалось много модулей (как правило, нежелательных), не считая тех, что были добавлены в черный список – это предотвращало их автоматическую загрузку, но по-прежнему позволяло загрузить вручную. В итоге, если черный список был составлен некорректно, это могло привести к неприятному конфликту между GPIO-контактами, что происходило, как правило, после апдейта ядра, т.к. файл черного списка (

/etc/modprobe.d/raspi-blacklist.conf

) не является частью ядра и, следовательно, автоматически не обновляется. Дерево устройств переворачивает эту систему с ног на голову – вместо объектов

struct platform_device

теперь всеми делами заправляют ноды, позволяя пользователям решать, какие девайсы активировать и, следовательно, какие модули подгрузить. Кроме того, добавление в ядро драйвера-модуля для нового девайса еще не будет означать, что модуль будет загружен. Сначала в дерево устройств нужно добавить соответствующие ноды.

Решение проблемы

Если у вас не хватает терпения, или для вашего устройства нет подходящего оверлея, попробуйте просто добавить в config.txt строчку

device_tree=

, а затем перезагрузиться. Впрочем, имейте в виду, что в таким виде эта опция выглядит очень «сыро», и система может ее попросту не «подхватить».

Поэтому лучше проделать все это следующим образом. Сначала вводим эту команду:

sudo raspi-config

Выберите в меню Advanced Options, а затем SPI или I2C – чтобы включить соответствующий интерфейс. Если вы хотите, чтобы модули драйверов подгружались автоматически, то на последующий вопрос ответьте «Yes». Кроме того, для включения и выключения дерева устройств можно пользоваться raspi-config.

Написать дерево устройств сложно, особенно если раньше вы с этим никогда не сталкивались. Впрочем, если вы используете покупное оборудование, писать (или даже редактировать) его необязательно, поскольку загрузчик Raspberry Pi (start.elf и его «собратья») может сочетать в себе базовый файл дерева устройств (DTB или DT Blob) и множество оверлеев, каждый из которых, к тому же, можно видоизменить по целому ряду параметров. И все это управляется из

/boot/config.txt

. Этот механизм описан в новом README-файле (

/boot/overlays/README

– только сначала обновите прошивку до последней версии), а полную документацию можно найти здесь.

ЧАВО

Интерфейс I2C исчез. Что делать?

Добавьте в config.txt строчку

dtparam=i2c_arm=on

и перезагрузитесь. Если хотите полаконичнее,

=on

можно опустить, т.к. это опция по умолчанию. Или воспользуйтесь raspi-config, как было описано выше.

Интерфейс SPI исчез. Что делать?

Добавьте в config.txt строчку

dtparam=spi=on

и перезагрузитесь. Или воспользуйтесь raspi-config, как было описано выше.

Интерфейс I2S исчез. Что делать?

Если заметили этот признак, добавьте в config.txt строчку

dtparam=i2s=on

и перезагрузитесь. В raspi-config этого нет.

Модуль lirc-rpi больше не загружается. Что делать?

Добавьте

dtoverlay=lirc-rpi

.

Но что насчет параметров к модулю lirc-rpi?

Они добавляются в конец строчки, примерно так:

dtoverlay=lirc-rpi,gpio_in_pin=16,gpio_in_pull=high

.

Что насчет w1-gpio?

Тут чуточку сложнее. Если вам нужно указать контакт для активации внешнего подтягивающего резистора, понадобится такая строчка –

dtoverlay=w1-gpio-pullup,gpiopin=<x>,extpullup=<y>

. В противном случае –

dtoverlay=w1-gpio,gpiopin=<x>

. (В первом и втором случаях «x» и «y» – это, разумеется, GPIO-контакты.) Если нужно активировать так называемый «режим паразитического питания» (т.е. режим, при котором питание подается по проводам, передающим данные; в данном случае – по двум проводам), добавьте к строчке

pullup=1

(или

pullup=on

).

Как насчет Еще один хитрый оверлей.

Название и параметр, полагаю, очевидны –

dtoverlay=pps-gpio,gpiopin=<x>

.

А что насчет звуковой карты?

Вам понадобится один из нижеследующих оверлеев:

  • dtoverlay=hifiberry-dac
    
  • dtoverlay=hifiberry-dacplus
    
  • dtoverlay=hifiberry-digi
    
  • dtoverlay=hifiberry-amp
    
  • dtoverlay=iqaudio-dac
    
  • dtoverlay=iqaudio-dacplus
    

Если вашей карты в этом списке нет, вам имеет смысл пока выключить дерево устройств (

device_tree=

) и обратиться к производителю. Также стоит попробовать написать об этом пост на форуме.

Как активировать часы реального времени (RTC, т.е. Real Time Clock) на I2C?

Понадобится следующая строчка –

dtoverlay=i2c-rtc,<model>

, где

<model>

– это один из следующих вариантов:

ds1307, ds3231, pcf2127, pcf8523 или pcf8563

. Обратите внимание, что старые RTC-оверлеи к использованию не рекомендуются и в будущих релизах будут удалены.

Как настроить светодиод, чтобы он сигнализировал о том, что загрузка проходит нормально?

Воспользуйтесь строчкой

dtparam=act_led_trigger=heartbeat

.

См.также

Внешние ссылки