Рассматриваются общие сведения и принципы работы с библиотекой I²C
I²C (Inter-Integrated Circuit) - это последовательный протокол, который соединяет несколько устройств по схеме "Ведущий-ведомый". Несколько ведущих устройств могут совместно использовать одну шину. Одно и то же устройство может выступать так и в роли ведущего, так и в роли ведомого. В спецификации I²C определены следующие диапазоны скоростей передачи данных:
Фреймворк I²C предназначен для облегчения последовательной реализации интерфейсов I²C. Он состоит из следующих частей:
hardware/i2c/*
- Аппаратный интерфейс.
lib/i2c
- Уровень менеджера ресурсов.
<hw/i2c.h>
- Публичный заголовочный файл, определяющий аппаратные и программные интерфейсы.
Наиболее распространенное применение шины I²C это доступ к регистрам ведомого устройства с низкой пропускной способностью, например:
Вы можете реализовать ведущего I²C как однопоточный менеджер ресурсов или как специализированное приложение. Основные преимущества менеджера ресурсов:
Для специализированных приложений, использующих шину I²C, более эффективна библиотека аппаратного доступа. Аппаратный интерфейс, определяющий интерфейс к этой библиотеке, полезен в качестве отправной точки для разработчиков и облегчает сопровождение и переносимость кода.
Это интерфейс к коду, реализующий аппаратно-ориентированную функциональность ведущего I²C. Он определен в <hw/i2c.h>
. Таблица функций описана в разделе i2c_master_funcs_t.
Пример последовательности вызовов аппаратной библиотеки:
#include <hw/i2c.h>i2c_master_funcs_t masterf;i2c_libversion_t version;i2c_status_t status;void *hdl;i2c_master_getfuncs(&masterf, sizeof(masterf));masterf.version_info(&version);if ((version.major != I2CLIB_VERSION_MAJOR) ||(version.minor > I2CLIB_VERSION_MINOR)){/* error */...}hdl = masterf.init(...);masterf.set_bus_speed(hdl, ...);masterf.set_slave_addr(hdl, ...);status = masterf.send(hdl, ...);if (status != I2C_STATUS_DONE) {/* error */if (!(status & I2C_STATUS_DONE))masterf.abort(hdl);}status = masterf.recv(hdl, ...);if (status != I2C_STATUS_DONE) {/* error */...}masterf.fini(hdl);
Если ведущее устройство I²C предназначено для использования одним приложением, вы можете скомпилировать код аппаратного интерфейса в виде библиотеки и связать его с приложением.
Для повышения переносимости кода приложению следует вызывать i2c_master_getfuncs() для доступа к функциям, специфичным для аппаратного обеспечения. Доступ к аппаратной библиотеке через таблицу функций также упрощает загрузку и управление несколькими аппаратными библиотеками.
Интерфейс менеджера ресурсов использует аппаратную библиотеку аналогичным образом.
Уровень менеджера ресурсов регистрирует имя устройства (обычно /dev/i2c0
). Приложения получают доступ к ведущему устройству I²C, выдавая команды devctl() на имя устройства.
Поддерживаемые команды devctl() и их форматы определены в <hw/i2c.h>
. Включает в себя следующие команды:
Многие команды devctl() используют структуру i2c_addr_t.
Уровень менеджера ресурсов реализован в виде библиотеки, статически связанной с аппаратной библиотекой. В настоящее время предоставляется однопоточный менеджер, libi2c-master
.
При запуске resmgr
выполняет следующие действия:
i2c_master_getfuncs(&masterf)masterf.init()masterf.set_bus_speed()
После этого менеджер ресурсов начинает работать в фоновом режиме.
Вот как менеджер ресурсов обрабатывает эти команды devctl():
if (bus_speed has changed)masterf.set_bus_speed()masterf.set_slave_address()masterf.send() or masterf.recv()
Поток менеджера ресурсов остается занятым до завершения транзакции и отвечает клиенту.
Вы можете завершить работу менеджера ресурсов, отправив ему сообщение SIGTERM
.
i2c_master_funcs_t, devctl(), DCMD_I2C_DRIVER_INFO, DCMD_I2C_SEND, DCMD_I2C_RECV, DCMD_I2C_SENDRECV, DCMD_I2C_SET_BUS_SPEED, DCMD_I2C_MASTER_SEND, DCMD_I2C_MASTER_RECV, DCMD_I2C_LOCK, DCMD_I2C_UNLOCK, i2c_master_getfuncs()
Предыдущий раздел: Библиотека разработки I²C драйверов