Недавно писал о том как работать с i2c устройством из пространства пользователя в linux.
В качестве пациента у мня raspberry pi b+ и часы реального времени ds1307. В предыдущей статье описан метод работы с устройством при помощи i2c-dev, но в Linux уже есть драйвер для этих часов (drivers/rtc/rtc-ds1307.c).
Нам нужно только скормить устройство драйверу и установить время.
Для указания системе о наличии нового устройства можно воспользоваться командой:
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
После этого ядро выполнит функцию ds1307_probe драйвера и в системе появиться новое устройство /dev/rtc0.
Теперь установим дату:
date -s "2016-04-19 15:11:40"
Теперь нужно записать дату в память RTC:
hwclock -w
Теперь вычитаем время:
hwclock -r
Как видите нам не нужно ничего писать! Правильно подключили, настроили и все!
Но нужно сделать еще так, чтобы эту операцию не нужно было проделывать после перезагрузки.
Самый тупой вариант записать это в скрипт и выполнять его по старту системы. Но это тоже изврат еще тот.
В Linux есть механизм для определения подключенных устройств — Device Tree. Это список всех устройств подключенных к компьютеру. Ядро подгружает его при старте и настраивает все устройства согласно настройкам в файле.
Для raspberry pi создана удобная возможность, которая позволяет избежать компилирования дерева устройств при добавлении нового — device tree overlay.
И есть даже уже готовый overlay для часов ds1307.
Его код:
/dts-v1/; /plugin/; / { compatible = "brcm,bcm2708"; fragment@0 { target = <&i2c1>; __overlay__ { #address-cells = <1>; #size-cells = <0>; status = "okay"; ds1307@68 { compatible = "ds1307"; reg = <0x68>; status = "okay"; }; }; }; };
Он уже скомпилирован в Device Tree Blob и лежит в каталоге /boot/overlays.
Для включения необходимо в файле /boot/config.txt
Добавить строки:
dtparam=i2c_arm=on dtparam=i2c=on dtoverlay=i2c-rtc,ds1307
Теперь после перезагрузки часы будут автоматически подключены.
То же самое работает для большинства устройств. Например экран ili9341, который я подключал раньше при помощи модифицированного ядра, теперь можно включить одной записью в config.txt.
Для более ранних версий raspbian или собственных сборок без поддержки device tree нужно «по старому» пересобрать ядро изменив bsp.
Например так:
static struct i2c_board_info i2c_info[] = { { I2C_BOARD_INFO("rtc-ds1307", 0x68), .type = "ds1307", }, };
Не очень удобно, как по мне.