Приступаем к работе с драйвером I2C для Linux, рекомендуется собрать! ! !
Приступаем к работе с драйвером I2C для Linux, рекомендуется собрать! ! !

Читайте полезные статьи впервые

1

Ядро Linux делит драйвер I2C на две части:

  1. I2C водитель автобуса, шина драйвер I2C — это SOCиз Драйвер контроллера I2C, также называемый Драйвер I2C-адаптера.
  2. I2C драйвер устройства, Драйвер I2C-устройства предназначен для конкретных I2C-устройство и написанное из драйвера.

Несколько важных членов в рамках I2C

1. Шина I2C

Структура шины I2C определена в файле driver\i2c\i2c-core.c следующим образом:

Язык кода:javascript
копировать
struct bus_type i2c_bus_type = {
    .name  = "i2c",
    .match  = i2c_device_match,
    .probe  = i2c_device_probe,
    .remove  = i2c_device_remove,
    .shutdown = i2c_device_shutdown,
};

Шина I2C соответствует шине в каталоге /bus. Эта структура шины i2c управляет сопоставлением, удалением и другими операциями устройства i2c и драйвера I2C. Шина I2C вызывает функцию i2c_device_match, чтобы проверить, совпадают ли устройство I2C и драйвер I2C. Если они совпадают, он вызывает функцию i2c_device_probe, а затем вызывает функцию проверки драйвера I2C.

Форма как:

i2c_device_match будет управлять правилами сопоставления устройств I2C и шины I2C, которые будут тесно связаны с написанием драйверов I2C.

2. Драйвер I2C

i2c_driver аналогичен Platform_driver и используется для написания драйверов устройств I2C. Структура i2c_driver определена в файле include/linux/i2c.h и имеет следующее содержимое:

Язык кода:javascript
копировать
struct i2c_driver {
    unsigned int class;

    /* Notifies the driver that a new bus has appeared. You should avoid
     * using this, it will be removed in a near future.
     */
    int (*attach_adapter)(struct i2c_adapter *) __deprecated;

    /* Standard driver model interfaces */
    int (*probe)(struct i2c_client *, const struct i2c_device_id *);
    int (*remove)(struct i2c_client *);


    /* driver model interfaces that don't relate to enumeration  */
    void (*shutdown)(struct i2c_client *);

    /* Alert callback, for example for the SMBus alert protocol.
     * The format and meaning of the data value depends on the protocol.
     * For the SMBus alert protocol, there is a single bit of data passed
     * as the alert response's low bit ("event flag").
     */
    void (*alert)(struct i2c_client *, unsigned int data);

    /* a ioctl like command that can be used to perform specific functions
     * with the device.
     */
    int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);

    struct device_driver driver;
    const struct i2c_device_id *id_table;

    /* Device detection callback for automatic device creation */
    int (*detect)(struct i2c_client *, struct i2c_board_info *);
    const unsigned short *address_list;
    struct list_head clients;
};

Ключевые члены:

Язык кода:javascript
копировать
int (*probe)(struct i2c_client *, const struct i2c_device_id *) 

Когда устройство I2C и драйвер успешно сопоставлены, функция зонда будет выполнена.

Язык кода:javascript
копировать
struct device_driver driver device_driver 

Для структуры драйвера, если вы используете дерево устройств, вам необходимо установить переменную-член of_match_table для устройства_драйвер, которая является совместимым атрибутом драйвера.

Язык кода:javascript
копировать
const struct i2c_device_id *id_table

id_table — традиционная таблица идентификаторов соответствия устройств, которая не использует дерево устройств.

3. I2C-устройства

Структура устройства I2C Структура i2c_client определена в файле include/linux/i2c.h и имеет следующее содержимое:

Язык кода:javascript
копировать
struct i2c_client {
    unsigned short flags; /* div., see below */
    unsigned short addr;  /* chip address - NOTE: 7bit */
    /* addresses are stored in the _LOWER_ 7 bits */
    char name[I2C_NAME_SIZE];
    struct i2c_adapter *adapter; /* the adapter we sit on */
    struct device dev;  /* the device structure  */
    int irq;   /* irq issued by device  */
    struct list_head detected;
    #if IS_ENABLED(CONFIG_I2C_SLAVE)
    i2c_slave_cb_t slave_cb; /* callback for slave mode */
    #endif
};

Ключевые члены:

  • flags:логотип
  • addr:Адрес чипа,7 немного, там низкий уровень 7 Кусочек
  • flagsname[I2C_NAME_SIZE]:имя
  • adapter:переписыватьсяиз I2C адаптер
  • dev:Структура устройства
  • irq:прерывать

Устройство соответствует i2c_client Каждый раз, когда обнаруживается устройство I2C, этому устройству I2C назначается i2c_client.

4. Адаптер I2C

После приведенного выше введения мы знаем, что существуют драйверы I2C и устройства I2C. Нам необходимо взаимодействовать с устройствами I2C через драйвер I2C, для которого требуется адаптер I2C. Адаптер I2C соответствует контроллеру I2C на SOC.

Ядро Linux абстрагирует адаптер I2C (контроллер) SOC в i2c_adapter. Структура i2c_adapter определяется в файле include/linux/i2c.h. Содержимое структуры следующее:

Язык кода:javascript
копировать
/*
 * i2c_adapter is the structure used to identify a physical i2c bus along
 * with the access algorithms necessary to access it.
 */
struct i2c_adapter {
    struct module *owner;
    unsigned int class;    /* classes to allow probing for */
    const struct i2c_algorithm *algo; /* the algorithm to access the bus *//* Алгоритм доступа к шине */
    void *algo_data;

    /* data fields that are valid for all devices */
    struct rt_mutex bus_lock;

    int timeout;   /* in jiffies */
    int retries;
    struct device dev;  /* the adapter device */

    int nr;
    char name[48];
    struct completion dev_released;

    struct mutex userspace_clients_lock;
    struct list_head userspace_clients;

    struct i2c_bus_recovery_info *bus_recovery_info;
    const struct i2c_adapter_quirks *quirks;
};

Ключевые члены:

Язык кода:javascript
копировать
const struct i2c_algorithm *algo

Метод, с помощью которого адаптер I2C взаимодействует с устройством IIC.

Структура i2c_algorithm определена в файле include/linux/i2c.h и имеет следующее содержимое:

Язык кода:javascript
копировать
struct i2c_algorithm {
    /* If an adapter algorithm can't do I2C-level access, set master_xfer
       to NULL. If an adapter algorithm can do SMBus access, set
       smbus_xfer. If set to NULL, the SMBus protocol is simulated
       using common I2C messages */
    /* master_xfer should return the number of messages successfully
       processed, or a negative value on error */
    int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,
               int num);
    int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,
               unsigned short flags, char read_write,
               u8 command, int size, union i2c_smbus_data *data);

    /* To determine what the adapter supports */
    u32 (*functionality) (struct i2c_adapter *);

    #if IS_ENABLED(CONFIG_I2C_SLAVE)
    int (*reg_slave)(struct i2c_client *client);
    int (*unreg_slave)(struct i2c_client *client);
    #endif
};

Ключевые члены:

  • master_xfer:I2C Функция передачи адаптера, вы можете использовать эту функцию для завершения IIC Связь между устройствами.
  • smbus_xfer:SMBUS функция передачи шины

Основная задача драйвера адаптера I2C — инициализировать структурную переменную i2c_adapter, а затем установить функцию master_xfer в i2c_algorithm. После завершения зарегистрируйте набор i2c_adapter в системе с помощью двух функций i2c_add_numbered_adapter или i2c_add_adapter.

Разница между этими двумя функциями заключается в том, что i2c_add_adapter использует динамический номер шины, а i2c_add_numbered_adapter использует статический номер шины.

5. Резюме

Драйвер I2C имеет четыре важные вещи: шина I2C, драйвер I2C, устройство I2C и устройство I2C.

  • шина I2C:Поддерживает два связанных списка(драйвер I2C、I2C-устройство),управлятьI2C-устройствоидрайвер I2Cиз сопоставления и удаления и т. д.
  • драйвер I2C:переписыватьсяизто естьI2C-устройствоизводитель。
  • I2C-устройство:Это конкретное аппаратное устройствоизабстракция。
  • I2C-адаптер:используется длядрайвер I2C и I2C-устройство являются общими и представляют собой абстракцию контроллера I2C на SOC.

Механизм работы шины Linux I2C:

  1. зарегистрироватьсядрайвер I2C
  2. Волядрайвер I2C добавлен в шину Список драйверов I2Cиз
  3. Траверс шина Список устройств I2C,Сопоставление согласно i2c_device_matchfunction,если совпадение, вызовi2c_device_probeфункция
  4. i2c_device_probeфункцияпозвонюдрайвер I2Cизprobeфункция

Простой процесс написания драйвера I2C

Как правило, драйверы шины I2C SOC написаны производителями полупроводников, и пользователям не нужно это писать. Таким образом, драйвер шины I2C защищен для пользователей SOC, и нам нужно сосредоточиться только на драйвере устройства I2C. Если вы не работаете в полупроводниковой компании, ваша работа — писать драйверы адаптера I2C.

i2c_driver аналогичен Platform_driver. Он предназначен для написания драйверов устройств I2C. Конкретное содержимое структуры i2c_driver было представлено выше.

Для нас, разработчиков драйверов устройств I2C, ключевой задачей является сборка i2c_driver. После завершения построения нам необходимо зарегистрировать этот i2c_driver в ядре Linux.

Итак, как зарегистрироваться?

Используйте эту функцию ниже:

Язык кода:javascript
копировать
int i2c_register_driver(struct module *owner,struct i2c_driver *driver)

Значения параметров функции и возвращаемых значений следующие:

  • owner:в целомдля THIS_MODULE。
  • driver:хотетьзарегистрироватьсяиз i2c_driver。
  • возвращаемое значение:0,Успех; отрицательное значение;,неудача.

Кроме того, i2c_add_driver часто используется для регистрации i2c_driver — это макроса, определяемого следующим образом:

Язык кода:javascript
копировать
#define i2c_add_driver(driver) \
        i2c_register_driver(THIS_MODULE, driver)

i2c_add_driver — это простая инкапсуляция i2c_register_driver только с одним параметром — регистрируемым i2c_driver.

При управлении устройством необходимо отменить регистрацию ранее зарегистрированного i2c_driver в ядре Linux. Необходимо использовать функцию i2c_del_driver. Прототип этой функции следующий:

Язык кода:javascript
копировать
void i2c_del_driver(struct i2c_driver *driver);

Значения параметров функции и возвращаемых значений следующие:

  • driver:Чтобы выйти из системыиз i2c_driver。
  • возвращаемое значение:никто。

Регулярные рамки:

Язык кода:javascript
копировать
/* i2c водитель probe функция */
static int xxx_probe(struct i2c_client *client,
{
    /* Функция Специальные процедуры */
    return 0;
}

/* i2c водитель remove функция */
static int xxx_remove(struct i2c_client *client)
{
    /* Функция Специальные процедуры */
    return 0;
}

/* Традиционный метод сопоставления ID список */
static const struct i2c_device_id xxx_id[] = {
    {"xxx", 0},
    {}
};

/* Соответствие дерева устройств списку */
static const struct of_device_id xxx_of_match[] = {
    { .compatible = "xxx" },
    { /* Sentinel */ }
};

/* i2c структура драйвера */
static struct i2c_driver xxx_driver = {
    .probe = xxx_probe,
    .remove = xxx_remove,
    .driver = {
        .owner = THIS_MODULE,
        .name = "xxx",
        .of_match_table = xxx_of_match,
    },
    .id_table = xxx_id,
};

/* Функция входа в привод */
static int __init xxx_init(void)
{
    int ret = 0;
    ret = i2c_add_driver(&xxx_driver);
    return ret;
}

/* Функция экспорта драйвера */
static void __exit xxx_exit(void)
{
    i2c_del_driver(&xxx_driver);
}

module_init(xxx_init);
module_exit(xxx_exit);

Когда устройство I2C и драйвер I2C успешно сопоставлены, будет выполнена функция проверки. Это то же самое, что и драйвер платформы. Функция проверки в основном содержит стандартный драйвер символьного устройства.

Рекомендовано в прошлом

Linux — это система реального времени или операционная система с разделением времени?

Правила расширения вложенных макросов языка C

Поделитесь осциллографом с последовательным портом QT с открытым исходным кодом

Функция обратного вызова языка C, необходимая для улучшения навыков C.

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose