Руководство по разработке Linux TWI
Руководство по разработке Linux TWI

Каталог статей

Руководство по разработке Linux TWI

1 Предисловие

1.1 Введение в документ

В этой статье описывается интерфейс драйвера TWI и метод отладки на платформе Sunxi, а также предоставляется справочная информация по разработке модулей TWI.

1.2 Целевые читатели

Разработчики и сопровождающие уровня ядра и уровня приложений модуля TWI.

1.3 Область применения

Таблица 1-1: Список применимых продуктов

Версия ядра

файл драйвера

Linux-4.9

i2c-sunxi.c

Linux-5.4

i2c-sunxi.c

2 Введение в модуль

2.1 Знакомство с функциями модуля

Шина Allwinner Twi совместима с протоколом шины i2c и представляет собой простую двунаправленную двухпроводную синхронную последовательную шину. Для передачи информации между устройствами, подключенными к шине, требуется всего два провода. Стандартная скорость связи, поддерживаемая контроллером TWI, составляет 100 кбит/с, а максимальная скорость связи может достигать 400 кбит/с. Контроллер Twi Allwinner поддерживает следующие функции:

Поддерживает режим хоста и режим подчиненного устройства;

Поддерживается в режиме хоста dma передача инфекции;

В режиме хоста поддерживается арбитраж шины в режиме нескольких хостов;

Поддерживается в режиме синхронизация часов хоста, ожидание кусочек байтов;

Поддержка прерывания обнаружения адреса в подчиненном режиме;

поддерживать 7bit подчиненный адрес и 10bit подчиненный адрес;

поддерживатьобщепринятыйиз i2c Режим протокола и пользовательский режим передачи;

sunxi плоскийбашняподдерживатьмногодорога ТВИ, ​​в том числе TWI и S_TWI。

2.2 Введение в связанные термины

2.2.1 Аппаратная терминология

Таблица 2-1: Аппаратная терминология

Связанные термины

Объяснение

TWI

Двухпроводной интерфейс, контроллер шины, совместимый со стандартным протоколом I2C на платформе Allwinner.

2.2.2 Терминология программного обеспечения

Таблица 2-2: Терминология программного обеспечения

Связанные термины

Связанные термины

Sunxi

Платформа разработки Linux, используемая Quanzhi Technology.

I2C_dapter

Абстрактное определение адаптера шины I2C в ядре Linux. Контроллер шины IIC физически соединяет несколько устройств I2C.

I2C_algorithm

linux В ядре I2C Абстрактное определение автобусного сообщения. описывать I2C Автобус подходитсоответствоватьустройствои I2C Способы связи между устройствами

I2C Client

linux В ядре I2C абстрактное определение устройства

I2C Driver

linux В ядре I2C Абстрактное определение драйвера устройства

2.3 Введение в настройку модуля

В разных аппаратных платформах Sunxi количество контроллеров TWI различно, но для каждого контроллера TWI на одной плате конфигурация модулей аналогична. В этом разделе показана конфигурация контроллера TWI0 на платформе Sunxi (конфигурация других контроллеров TWI аналогична).

2.3.1 Конфигурация дерева устройств по умолчанию

В дереве устройств существует конфигурация модулей всех платформ этого типа чипа. Путь к файлу дерева устройств: {linux-ver}/arch/arm64 (32-разрядная платформа — Arm)/boot/dts/sunxi. (32-битная система не имеет этого каталога)/xxxx.dtsi (CHIP — это код R&D, например sun50iw10p1 и т. д.), конфигурация дерева устройств шины TWI следующая:

Язык кода:javascript
копировать
twi0: twi@0x05002000{
	#address-cells = <1>;
	#size-cells = <0>;
	compatible = "allwinner,sun50i-twi"; //Конкретное изоборудование, используемое для обеспечения обязательного оснащения 
	device_type = "twi0";                //имя узла оборудования,используется дляsys_config.fexживотноесоответствовать 
	reg = <0x0 0x05002000 0x0 0x400>;    //Регистр шины TWI0 Конфигурация 
	interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; //номер разрыва середины шины TWI0, тип разрыва середины 
	clocks = <&clk_twi0>;       //оборудованиеиспользоватьизчасы 
	clock-frequency = <400000>; //контроллер TWI0 с тактовой частотой
	pinctrl-names = "default", "sleep"; //Контроллер TWI0 используетизимя контакта, его серединаdefaultдля является нормальным время письма изpin Конфигурация, сондля сна время изpin Конфигурация
	pinctrl-0 = <&twi0_pins_a>; //Использовать контроллер TWI0 по умолчанию при настройке контактов
	pinctrl-1 = <&twi0_pins_b>; //Использовать вывод, когда контроллер TWI0 спит. Конфигурация
	twi_drv_used = <1>;  //использоватьDMAпередавать данные
	status = "disabled"; //Включен ли контроллер TWI0
};

существовать linux-5.4 Средний, ТВИ из Конфигурацияи linux-4.9 Внутриядерный Конфигурация несколько иная, разница в основном отражается на существовании. clock и dma По конфигурации:

Язык кода:javascript
копировать
twi0: twi@0x05002000{
	#address-cells = <1>;
	#size-cells = <0>;
	compatible = "allwinner,sun20i-twi"; //Конкретное изоборудование, используемое для обеспечения обязательного оснащения 
	device_type = "twi0";                //имя узла оборудования,используется дляsys_config.fexживотноесоответствовать
	reg = <0x0 0x02502000 0x0 0x400>;    //Регистр шины TWI0 Конфигурация 
	interrupts-extended= <&plic0 25 IRQ_TYPE_LEVEL_HIGH>; //Шина TWI0 разрывает номер середины, середина разрывает класс
часы = <&ccu CLK_BUS_I2C0>;//twiконтрольустройствоиспользоватьизчасы
	resets = <&ccu RST_BUS_I2C0>;//twiконтрольустройствоиспользоватьизresetчасы
	clock-names = "bus";
	clock-frequency = <400000>; //контроллер TWI0 с тактовой частотой
	dmas = <&dma 43>, <&dma 43>;//TWI0КонтроллерзdmaНомер канала
	dma-names = "tx", "rx";
	status = "disabled";//Включен ли контроллер TWI0
};

для Понятносуществовать TWI Дифференцировать каждый по коду водителя автобуса TWI Контроллер, необходимый для существования Device Tree в aliases для каждого узла TWI Указанный псевдоним узла:

Язык кода:javascript
копировать
aliases {
	soc_twi0 = &twi0;
	soc_twi1 = &twi1;
	soc_twi2 = &twi2;
	soc_twi3 = &twi3;
	...
};

Форма псевдонима представляет собой строку “twi” Сложите последовательные числа из цифр, существуют TWI Водителя автобуса можно пропустить Функция of_alias_get_id() получает соответствующий TWI Контроллер имеет цифровой номер, что позволяет различать каждый TWI контроллер.

Среди них twi0_pins_a, twi0_pins_b — это узлы конфигурации контактов TWI. Путь этой конфигурации в linux4.9 — Arch/arm64 (32-разрядная платформа — Arm)/boot/dts/sunxi/xxxxpinctrl.dtsi (CHIP — это код исследований и разработок, например sun50iw10p1 и т. д.). конкретная конфигурация следующая:

Язык кода:javascript
копировать
twi0_pins_a: twi0@0 {
	allwinner,pins = "PD14", "PD15";          //Контроллер TWIиспользовать контакт 
	allwinner,pname = "twi0_scl", "twi0_sda"; //Контроллер TWI из описания функции вывода
	allwinner,function = "twi0"; //Описание функции вывода
	allwinner,muxsel = <4>;      //Функция мультиплексирования выводов Конфигурация
	allwinner,drive = <0>;       //возможности драйвера io
	allwinner,pull = <0>;        //Внутри статус частичного сопротивления 
};

twi0_pins_b: twi0@1 {
	allwinner,pins = "PD14", "PD15";
	allwinner,function = "io_disabled";
	allwinner,muxsel = <7>;
	allwinner,drive = <1>;
	allwinner,pull = <0>;
};

Путь этой конфигурации в linux-5.4 — Arch/arm64 (arm для 32-битной платформы)/boot/dts/sunxi/xxxx.dtsi (CHIP — это код исследований и разработок, например sun50iw10p1 и т. д.), как показано ниже:

Язык кода:javascript
копировать
twi0_pins_a: twi0@0 {
	pins = "PH0", "PH1";
	function = "twi0";
	drive-strength = <10>;
};
twi0_pins_b: twi0@1 {
	pins = "PH0", "PH1";
	function = "gpio_in";
}

Кроме того, clk_twi0 — это конфигурация часов.

существовать linux-4.9 середина, дорога диаметр для arch/arm64(32 Кусочек плоский башня для arm)/boot/dts/sunxi/XXXXclk.dtsi(CHIP дляR&D кодовое название, например sun50iw10p1 и т. д.), конкретная конфигурация выглядит следующим образом:

Язык кода:javascript
копировать
clk_twi0: twi0 {
	#clock-cells = <0>;
	compatible = "allwinner,периферийные часы";
clock-output-names = "twi0"; //Укажите имена часов, используемые для соответствия конфигурации часов.
};

существовать linux-5.4 середина,Незачем Конфигурация。

2.3.2 Конфигурация уровня платы board.dts

board.dts Используется для сохранения информации о каждом уровне плиты плоскобашняизоборудование (например, demo доска,перф1 Доска, версия 1 плата и т. д.), информация о конфигурации внутри перезапишет вышеуказанную информацию. device tree Информация о конфигурации по умолчанию. доска.dts издорогадиаметрдля longan/device/config/chips/IC/configs/BOARD/board.dts,

существовать linux-4.9 середина,переписываться board.dts в TWI0 Конкретная конфигурация следующая:

Язык кода:javascript
копировать
twi0_pins_a: twi0@0 {
	allwinner,pins = "PA0", "PA1";
	allwinner,pname = "twi0_scl", "twi0_sda";
	allwinner,function = "twi0";
	allwinner,muxsel = <4>;
	allwinner,drive = <1>;
	allwinner,pull = <0>;
};

twi0_pins_b: twi0@1 {
	allwinner,pins = "PA0", "PA1";
	allwinner,function = "io_disabled";
	allwinner,muxsel = <7>;
	allwinner,drive = <1>;
	allwinner,pull = <0>;
};

twi0: twi@0x05002000{
	clock-frequency = <400000>; //тактовая частота i2c для 400К
	pinctrl-0 = <&twi0_pins_a>;
	pinctrl-1 = <&twi0_pins_b>;
	status = "okay"; //Включаем TWI0
};

существовать linux-5.4 середина,переписываться board.dts в TWI0 Конкретная конфигурация следующая:

Язык кода:javascript
копировать
&twi0 {
	clock-frequency = <400000>;
	pinctrl-0 = <&twi0_pins_a>;
	pinctrl-1 = <&twi0_pins_b>;
	pinctrl-names = "default", "sleep";
	status = "disabled";
	eeprom@50 {
		compatible = "atmel,24c16";
		reg = <0x50>;
		status = "disabled";
	};
};

Что Средний, ТВИ Ставка определяется “clock-frequency” свойство Конфигурация,максимумподдерживать 400K。

для TWI оборудование, вы можете заполнить узел оборудования как для Device Tree Соответствующий TWI Дочерний узел контроллера. ТВИ управляемый контроллером probe функционировать через of_i2c_register_devices() , автоматически расширять свои подузлы для и из TWI оборудование.

для twi0 цитируется в pin порт, конкретная конфигурация следующая:

Язык кода:javascript
копировать
twi0_pins_a: twi0@0 {
	pins = "PB10", "PB11"; /*sck sda*/
	function = "twi0";
	drive-strength = <10>;
};

twi0_pins_b: twi0@1 {
	pins = "PB10", "PB11";
	function = "gpio_in";
};
2.3.3 Конфигурация меню конфигурации ядра

существовать longan середина,linux-4.9 существовать жизнь делать ХОРОШО Входить входить Внутри ядерный корень глаз записывать (/kernel/linux-4.9), Выполнять ХОРОШО make ARCH=arm64 menuconfig (32 Кусочекплоскийбашня Выполнять ХОРОШО:make ARCH=arm menuconfig) Входитьвходить Конфигурация Основной интерфейс,И выполните следующие операции (linux-5.4 существоватькореньглаззаписыватьсередина Выполнять ХОРОШО./build.sh menuconfig)существовать tina середина,может быть напрямуюсуществоватькореньглаззаписыватьв Выполнять ХОРОШО make kernel_menuconfig Входитьвходить menuconfig Интерфейс конфигурации.

1. выбирать Device Drivers Параметр «Входвход» представляет собой следующий уровень конфигурации, как показано на рисунке ниже.

Рисунок 2-1: Драйвер устройства

2. выбирать I2C support Параметры,Входитьвходитьследующий уровень Конфигурация,Как показано ниже.

Рисунок 2-2: Поддержка I2C

3. Настройка пользователей I2C интерфейс,выбирать I2C device интерфейс, как показано на рисунке ниже.

Рисунок 2-3: Интерфейс устройства I2C.

4. выбирать I2C HardWare Bus support Параметры,Входитьвходитьследующий уровень Конфигурация,Как показано ниже.

Рисунок 2-4: Поддержка аппаратной шины I2C.

5. выбирать SUNXI I2C controller Параметры,Можетвыбирать Компилировать напрямую Входить Внутриядерный,также Может Скомпилировать в модуль。Как показано ниже.

Рисунок 2-5: Контроллер SUNXI I2C

2.4 Структура модуля исходного кода

Драйвер шины I2C

Язык кода:javascript
копировать
kernel/linux-4.9/drivers/i2c/
├── busses
│   ├── i2c-sunxi.c // Код драйвера контроллера Sunxi плоскобашняиз I2C
│   ├── i2c-sunxi.h // дляSunxi плоскобашняиз Драйвер контроллера I2C определяет некоторые макросы и структуры данных
│   ├── i2c-sunxi-test.c // Код испытания оборудования Sunxi плоскобашняизи2c,5.4Пока не подходитсоответствовать
├── i2c-core.c // Ядерный файл подсистемы I2C, обеспечивающий соответствующие функции интерфейса.
├── i2c-dev.c  // I2CПодсистемаизоборудование Связанные документы,Используется для регистрации соответствующих файлов оборудования.,Легко отлаживать

2.5 Введение в структуру драйверов

Рисунок 2-6: Структурная схема модуля TWI.

Linux середина I2C Как показано в архитектуре картины, картинасередина разделена на три уровня разделительными линиями: 1. Пользовательское пространство, включая все виды использования I2C Приложения для устройств 2. Внутриядерный, являющийся движущей частью 3. Под аппаратным обеспечением понимается фактическое физическое устройство, включая I2C Контроллер I2C периферийные устройства.

Чтосередина,Linux В ядреиз I2C Драйверы можно логически разделить на 6 части:

  1. I2C framework предоставить "доступ I2C slave devices” из метода. из-за этого slave devices по I2C controller контроль, и поэтому главным образом за счет I2C controller Стремитесь к достижению этой цели.
  2. пройти I2C framework изабстрактный, пользователям плевать I2C Из технических подробностей вам нужно только позвонить в систему из интерфейса, можно и внешнее оборудование Входить ХОРОШО. Обычно внешнее оборудование представляет собой Кусочек Внутрия дерного Государства из других драйвер (например, сенсорный экран, камера и т. д.). I2C framework Аналогичный интерфейс также предоставляется пользовательскому пространству через символьное оборудование, а программы пользовательского пространства могут получать доступ к информации из оборудования через Долженинтерфейс.
  3. существовать I2C framework Внутриотделение,иметь I2C core、I2C busses、I2C algos и I2C muxes Четыре модуля.
  4. I2C core использовать I2C adapter и I2C algorithm Две абстракции подмодуля I2C controller из Функция,использовать I2C client и I2C driver абстрактный I2C slave device по назначению (соответствует модели оборудования device и device водитель). Кроме того, на основе I2C соглашение, прошло smbus Реализация модуля SMBus(System Management Шина, шина управления системой) из функции.
  5. I2C busses Это каждый I2C controller drivers изсобирать,Кусочек В driver/i2c/busses/eye-registerВниз,i2c-sunxi-test.c、i2c-sunxi.c、i2c-sunxi.h。
  6. I2C algos Содержит некоторые общие из I2C алгоритм, так называемый из алгоритм относится к I2C Протокол метода связи, используемый для реализации I2C из read/write Относится к операции, которая обычно реализуется аппаратно и не требует особого внимания. на Долженглаззаписывать。

3 Описание интерфейса модуля

3.1 интерфейс ядра i2c

3.1.1 i2c_transfer()
  • Прототип функции: int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
  • Функция: Полная I2C Автобус и I2C оборудованиемеждуизопределенное числоглазиз I2C message Взаимодействие.
  • параметр:
    • adap: указывает на принадлежность из I2C контроллер шины;
    • msgs:i2c_msg тип из указателя;
    • число: указывает, сколько необходимо обработать за раз. I2C msg
  • возвращаться:
    • >0:Уже обработаноиз msg число;
    • <0:неудача;
3.1.2 i2c_master_recv()
  • Формат: int i2c_master_recv(const struct i2c_client *client, char *buf, int count)
  • Функция: Завершите операцию получения I2c, инкапсулировав i2c_transfer().
  • параметр:
    • клиент: указывает на текущий I2C оборудованиеиз Пример;
    • buf: используется для сохранения кэша полученных данных;
    • count: кэш данных buf длина
  • возвращаться:
    • >0:Успешно полученоиз Количество байтов;
    • <0:неудача;
3.1.3 i2c_master_send()
  • Тип: int i2c_master_send(const struct i2c_client *client, const char *buf, int count)
  • Функция: Завершите операцию отправки I2c, инкапсулировав i2c_transfer().
  • параметр:
    • клиент: указывает на текущий I2C Из экземпляра оборудованияиз;
    • buf: для отправки данных;
    • count: длина данных, которые будут отправлены
  • возвращаться:
    • >0:Отправлено успешноиз Количество байтов;
    • <0:неудача;
3.1.4 i2c_smbus_read_byte()
  • Прототип функции: s32 i2c_smbus_read_byte(const struct i2c_client *client)
  • Функция: от I2C Считайте байт из шины. (Внутри министерство завершено i2c_transfer() Для достижения этой цели следующие интерфейсы одинаковы. )
  • параметр:
    • клиент: указывает на текущийиз I2C отоборудование
  • возвращаться:
    • >0:читатьизданные;
    • <0:неудача;
3.1.5 i2c_smbus_write_byte()
  • Прототип функции: s32 i2c_smbus_write_byte(const struct i2c_client *client, значение u8)
  • Функция: от I2C Шина пишет входить один байт.
  • параметр:
    • клиент: указывает на текущийиз I2C отоборудование;
    • значение: Чтобы записать числовое значение вхожденияиз.
  • возвращаться:
    • 0: успех;
    • <0:неудача;
3.1.6 i2c_smbus_read_byte_data()
  • Прототип функции: s32 i2c_smbus_read_byte_data(const struct i2c_client *client, команда u8)
  • Функция: от I2C оборудование Читает один байт по указанному смещению.
  • параметр:
    • клиент: указывает на текущийиз I2C отоборудование;
    • command:I2C Данные протокола из 0 Байт кода жизниделать (т.е. значение смещения);
  • возвращаться:
    • >0:читатьизданные;
    • <0:неудача;
3.1.7 i2c_smbus_write_byte_data()
  • Прототип функции: s32 i2c_smbus_write_byte_data(const struct i2c_client *client, команда u8, значение u8)
  • Функция: от I2C оборудование записывает входить один байт по указанному смещению.
  • параметр:
    • клиент: указывает на текущийиз I2C отоборудование;
    • command:I2C Данные протокола из 0 Байт кода жизниделать (т.е. значение смещения);
    • значение: Чтобы написать значение вхожденияиз;
  • возвращаться:
    • 0: успех;
    • <0:неудача;
3.1.8 i2c_smbus_read_word_data()
  • Прототип функции: s32 i2c_smbus_read_word_data(const struct i2c_client *client, команда u8)
  • Функция: от I2C оборудование Читать один по указанному смещению word данные (два байта, подходят для I2C реестр оборудования 16 Кусок Состояние).
  • параметр:
    • клиент: указывает на текущийиз I2C отоборудование;
    • command:I2C Данные протокола из 0 Байт кода жизниделать (т.е. значение смещения);
  • возвращаться:
    • >0:читатьизданные;
    • <0:неудача;
3.1.9 i2c_smbus_write_word_data()
  • Прототип функции: s32 i2c_smbus_write_word_data(const struct i2c_client *client, команда u8, значение u16)
  • Функция: от I2C оборудования укажите смещение и напишите входить word данные (два байта).
  • параметр:
    • клиент: указывает на текущийиз I2C отоборудование;
    • command:I2C Данные протокола из 0 Байт кода жизниделать (т.е. значение смещения);
    • значение: Чтобы записать числовое значение вхожденияиз.
  • возвращаться:
    • 0: успех;
    • <0:неудача;
3.1.10 i2c_smbus_read_block_data()
  • Прототип функции: s32 i2c_smbus_read_block_data(const struct i2c_client *client, команда u8,u8 *values)
  • Функция: от I2C оборудование Чтение фрагмента данных по указанному смещению.
  • параметр:
    • клиент: указывает на текущийиз I2C отоборудование;
    • command:I2C Данные протокола из 0 Байт кода жизниделать (т.е. значение смещения);
    • значения: используются для сохранения прочитанных данных;
  • возвращаться:
    • >0:читатьизданныедлина;
    • <0:неудача;
3.1.11 i2c_smbus_write_block_data()
  • Тип файла: s32 i2c_smbus_write_block_data(const struct i2c_client *client, команда u8, длина u8, const u8 *values)
  • Функция: от I2C оборудование записывает входить фрагмент данных по указанному смещению (максимальная длина 32 байт).
  • параметр:
    • клиент: указывает на текущийиз I2C отоборудование;
    • command:I2C Данные протокола из 0 Байт кода жизниделать (т.е. значение смещения);
    • длина: Чтобы записать длину данных вхождения;
    • значения: Записать данные вхожденияиз;
  • возвращаться:
    • 0: успех;
    • <0:неудача;

3.2 Интерфейс вызова пользовательского режима i2c

i2c издействоватьсуществовать В ядре используется как символ оборудования для работы, который можно передать через файл использования Читай и пишиинтерфейс(open,write,read,ioctrl)ждатьдействовать Внутриядерныйглаззаписыватьв/dev/i2c-* Файлы поставляются с соответствующими интерфейсами i2c. Связано с операционными определениями существующегоi2c-dev.c в, этот раздел будет более важным из нескольких интерфейсов:

3.2.1 i2cdev_open()
  • Прототип функции: static int i2cdev_open(struct inode *inode, struct file *file)
  • Функция: Программа (C язык и т. д.)использовать open(file) При вызове функции из. открыть i2c оборудование, может быть как файл Читай и пишииз способ i2c оборудованиесередина Читай и данные пиши
  • параметр:
    • inode:inode узел;
    • file:file структура;
    • начало: файловый дескриптор
3.2.2 i2cdev_read()
  • Тип файла: static ssize_t i2cdev_read(struct file *file, char __user *buf, size_t count,loff_t *offset)
  • Функция: Программа (C язык и т. д.) позвоните read() При вызове функции из. Как чтение данных из файла. i2c оборудованиесерединапрочитать данные. Нижний вызов i2c_xfer передавать данные
  • параметр:
    • file:file структура;
    • буф, записать данные buf;
    • offset, Смещение файла.
  • возвращаться:
    • Непусто: возвращает количество прочитанных байтов;
    • <0:неудача;
3.2.3 i2cdev_write()
  • Тип файла: static ssize_t i2cdev_write(struct file *file, const char __user *buf,size_t count, loff_t *offset)
  • Функция: Программа (C язык и т. д.) позвоните write() При вызове функции из. Так же, как запись данных в файл i2c оборудованиясередина записать данные. Нижний вызов i2c_xfer передавать данные
  • параметр:
    • file:file структура;
    • buf: прочитать данные buf;
    • offset, Смещение файла.
  • возвращаться:
    • 0: успех;
    • <0:неудача;
3.2.4 i2cdev_ioctl()
  • Тип файла: static long i2cdev_ioctl(файл структуры *file, unsigned int cmd, unsigned long arg)
  • Функция: Программа (C язык и т. д.) позвоните ioctl() При вызове функции из. как управление файлами i/o То же верно i2c Управление оборудованием. Должен относительно мощный и его можно модифицировать. i2c оборудованиеиз адрес, перейти i2 оборудованиев Читай и данные пиши,использовать smbus Подождите, подробности вы можете проверить в функции «Должен».
  • параметр:
    • file:file структура;
    • cmd:обратитесь кделать;
    • arg: другие параметры.
  • возвращаться:
    • 0: успех;
    • <0:неудача;

4 примера использования модуля

4.1 Использование интерфейса i2c-core для чтения и записи устройств TWI

существовать Внутриядерный Исходный кодсерединаиметь Готовыйиз i2c Пример драйвера устройства: tina/lichee/kernel/linux-5.4/drivers/misc/eeprom/at24.c, это EEPROM из I2C драйвер оборудования, проверено I2C водитель автобуса, так что это серединапасс sysfs Реализация узла Читай и пиши визит. Ниже приведены некоторые ключевые положения этого документа:

Язык кода:javascript
копировать
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <linux/mod_devicetable.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
#include <linux/property.h>
#include <linux/acpi.h>
#include <linux/i2c.h>
#include <linux/nvmem-provider.h>
#include <linux/regmap.h>
#include <linux/pm_runtime.h>
#include <linux/gpio/consumer.h>

#define EEPROM_ATTR(_name) \ 
{ 							\
	.attr = { .name = #_name,.mode = 0444 }, \
	.show = _name_00_show, \ 
}

struct i2c_client *this_client;

static const struct i2c_device_id at24_ids[] = {
	{ "24c16", 0 },
	{ /* END OF LIST */ }
};
MODULE_DEVICE_TABLE(i2c, at24_ids);

static int eeprom_i2c_rxdata(char *rxdata, int length)
{
    int ret;
    struct i2c_msg msgs[] = {
        {
            .addr = this_client->addr,
            .flags = 0,
            .len = 1,
            .buf = &rxdata[0],
        },
        {
            .addr = this_client->addr,
            .flags = I2C_M_RD,
            .len = length,
            .buf = &rxdata[1],
        },
	};
    ret = i2c_transfer(this_client->adapter, msgs, 2);
    if (ret < 0)
    	pr_info("%s i2c read eeprom error: %d\n", __func__, ret);
    	
    return ret;
}    

static int eeprom_i2c_txdata(char *txdata, int length)
{
    int ret;
    struct i2c_msg msg[] = {
        {
            .addr = this_client->addr,
            .flags = 0,
            .len = length,
            .buf = txdata,
        },
    };
    ret = i2c_transfer(this_client->adapter, msg, 1);
    if (ret < 0)
	    pr_err("%s i2c write eeprom error: %d\n", __func__, ret);
	    
    return 0;
}

static ssize_t read_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
    int i;
    u8 rxdata[4];
    rxdata[0] = 0x1;
    eeprom_i2c_rxdata(rxdata, 3);
    
    for(i=0;i<4;i++)
	    printk("rxdata[%d]: 0x%x\n", i, rxdata[i]);
    
    return sprintf(buf, "%s\n", "read end!");
}

static ssize_t write_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
    int i;
    static u8 txdata[4] = {0x1, 0xAA, 0xBB, 0xCC};
    for(i=0;i<4;i++)
    	printk("txdata[%d]: 0x%x\n", i, txdata[i]);
    	
    eeprom_i2c_txdata(txdata,4);
    
    txdata[1]++;
    txdata[2]++;
    txdata[3]++;
    
    return sprintf(buf, "%s\n", "write end!");
}

static struct kobj_attribute read = EEPROM_ATTR(read);
static struct kobj_attribute write = EEPROM_ATTR(write);

static const struct attribute *test_attrs[] = {
    &read.attr,
    &write.attr,
    NULL,
};

static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    int err;
    this_client = client;
    printk("1..at24_probe \n");
    err = sysfs_create_files(&client->dev.kobj,test_attrs);
    printk("2..at24_probe \n");
    
    if(err){
    	printk("sysfs_create_files failed\n");
	}
	printk("3..at24_probe \n");

	return 0;
}
static int at24_remove(struct i2c_client *client)
{
	return 0;
}

static struct i2c_driver at24_driver = {
    .driver = {
        .name = "at24",
        .owner = THIS_MODULE,
    },
    .probe = at24_probe,
    .remove = at24_remove,
    .id_table = at24_ids,
};

static int __init at24_init(void)
{
    printk("%s %d\n", __func__, __LINE__);
    return i2c_add_driver(&at24_driver);
}
module_init(at24_init);
	
static void __exit at24_exit(void)
{
	printk("%s()%d - \n", __func__, __LINE__);
	i2c_del_driver(&at24_driver);
}
module_exit(at24_exit);

4.2 Использование интерфейса пользовательского режима для чтения и записи устройств TWI

Если настроено i2c devices интерфейс, вы можете напрямую использовать функции чтения и записи файлов для работы I2C Следующая программа читает напрямую. /dev/i2c-* Приходите читать и писать i2c оборудование:

Язык кода:javascript
копировать
#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#define CHIP "/dev/i2c-1"
#define CHIP_ADDR 0x50
int main()
{
    unsigned char rddata;
    unsigned char rdaddr[2] = {0, 0}; /* Прочитает данные чипа, существующего в смещении */
    unsigned char wrbuf[3] = {0, 0, 0x3c}; /* Для записи данных первые два байта для смещения */
    printf("hello, this is i2c tester\n");
    int fd = open(CHIP, O_RDWR);
    if (fd < 0)
    {
        printf("open "CHIP"failed\n");
        goto exit;
    }
    if (ioctl(fd, I2C_SLAVE_FORCE, CHIP_ADDR) < 0)
    { /* Установить адрес чипа */
        printf("oictl:set slave address failed\n");
        goto close;
    }
    printf("input a char you want to write to E2PROM\n");
    wrbuf[2] = getchar();
    printf("write return:%d, write data:%x\n", write(fd, wrbuf, 3), wrbuf[2]);
    sleep(1);
    printf("write address return: %d\n",write(fd, rdaddr, 2)); /* Перед чтением сначала установите смещение для чтения из */
    printf("read data return:%d\n", read(fd, &rddata, 1));
    printf("rddata: %c\n", rddata);
    close(fd);
    
exit:
    return 0;
}

5 FAQ

5.1 Метод отладки

5.1.1 Инструменты отладки
5.1.1.1 Инструменты отладки i2c-tools

i2c-tools Это инструмент с открытым исходным кодом, специально используемый для отладки. I2C оборудование.Можетиспользовать i2c-tools получить i2c информация, связанная с оборудованием (существовать Внутриядерныйв интегрирована по умолчанию), и Читай и пиши связанные из i2c оборудованиеизданные。i2c-tools В основном путем чтения и записи /dev/i2c-* Получение файла I2C оборудование,так нужносуществовать kernel/linux-4.9 из menuconfig в ручке I2Cиз device interface Узел открыт, специфический из i2c-tools Как его использовать, заключается в следующем.

Язык кода:javascript
копировать
i2cdetect -l //Получаем информацию об оборудовании i2c
i2cdump -y i2c-number i2c-reg //Дамп соответствующих данных оборудования i2c, например i2cdump -y 1 0x50
i2cget -y i2c-number i2c-reg data_rege //Читаем i2cоборудование определенного адреса из данных, например i2cget -y 1 0x50 1
i2cset -y i2c-number i2c-reg data_rege data //Записываем данные на адрес i2cоборудование, например i2cset -y 1 0x50 1 1
5.1.2 Отладка узлов
5.1.2.1 /sys/module/i2c_sunxi/parameters/transfer_debug

Функция этого файла узла — открыть отладочную информацию определенного процесса связи канала TWI. Значение по умолчанию — -1, при этом информация об отладке связи не будет выводиться ни на один канал.

открытый канал x Информация об отладке процесса связи из метода:

Язык кода:javascript
копировать
echo x > /sys/module/i2c_sunxi/parameters/transfer_debug

Способ отключения отладочной информации процесса связи:

Язык кода:javascript
копировать
echo -1 > /sys/module/i2c_sunxi/parameters/transfer_debug
5.1.2.2 /sys/devices/soc.2/1c2ac00.twi.0/info

Этот файл узла может распечатать текущий TWI рядиз Некоторая информация об аппаратных ресурсах。

Язык кода:javascript
копировать
cat /sys/devices/soc.2/1c2ac00.twi.0/info

5.1.2.3 /sys/devices/soc.2/1c2ac00.twi/status

Этот файл узла может распечатать текущий TWI рядизнемного удачи ХОРОШОинформация о статусе,включать Контроллерз Каждый депозитустройствоценить。

Язык кода:javascript
копировать
cat /sys/devices/soc.2/1c2ac00.twi/status

5.2 Часто задаваемые вопросы

5.2.1 Данные TWI отправляются не полностью

Проблемное явление:incomplete xfer. Бетон из log Как показано ниже:

Язык кода:javascript
копировать
[ 1658.926643] sunxi_i2c_do_xfer()1936 - [i2c0] incomplete xfer (status: 0x20, dev addr: 0x50)
[ 1658.926643] sunxi_i2c_do_xfer()1936 - [i2c0] incomplete xfer (status: 0x48, dev addr: 0x50)

Анализ проблемы:эта ошибкаповерхность Показывать主контроль已经发送Понятноданные(status ценитьдля 0x20 Когда это означает,что SLAVE ADDR + WRITE;status ценитьдля 0x48 Когда это означает, что SLAVE ADDR + READ),Но оборудование не ответило ACK,Это оборудование для поверхности не отвечает.,отвечать Должен Проверьте, не пропустили лиоборудование、Плохой контакт、повреждение оборудования и неправильная последовательность включения, приводящая к неготовности оборудования и другим проблемам.

Поиск неисправностей

шаг 1: По дереву оборудования, а именно информация о конфигурации, ядерная конфигурация на выводе правильная. каждая группа TWI Существует несколько наборов конфигураций контактов.

шаг 2: Замена TWI Автобус выключен изоборудованиедля at24c16, используйте i2ctools Читай и пиши at24c16 Посмотрите, удалось ли это сделать. Это означает, что шина работает правильно.

шаг 3: Проверьте, может ли оборудование работать нормально и I2C В хорошем ли состоянии оборудование.

шаг 4:подробный Понятно Решить текущие потребностидействоватьизоборудованиеиз Метод инициализации,Последовательность работы,использоватьметод,Устраните сбой связи из-за неправильной инициализации.

шаг 5. Проверьте с помощью осциллографа. TWI Вывод выводит сигнал, чтобы проверить, совпадает ли он.

5.2.2 Сигнал запуска TWI не может быть отправлен.

Проблемное явление:START can’t рассылка!. Бетон из log Как показано ниже:

Язык кода:javascript
копировать
sunxi_i2c_do_xfer()1865 - [i2c1] START can't sendout!

Анализ проблемы:эта ошибкаповерхность Показывать TWI Невозможно отправить сигнал запуска, обычно за которым следует TWI Автобус изприколоть Конфигурацияа такжечасы Конфигурацияиметьзакрывать。отвечать Долженисследоватьприколоть Конфигурация Это правильно?,Конфигурация часов правильная?,Имеет ли вывод подтягивающий резистор и т. д.

Поиск неисправностей

шаг 1: Перезапустить Внутриядерный просмотром журнал, анализ TWI Инициализация прошла успешно?,Если есть проблема, то это вопрос времени. контакт,Проверьте правильность информации о контакте.

шаг 2: корень По принципу картина, просмотр TWI-SCK и TWI-SDA Целесообразно ли подключать подтягивающий резистор к 3.3v Напряжение.

шаг 3. Используйте мультиметр для измерения SDA и SCL Начальное напряжение, проверьте, существует ли напряжение 3.3V рядом (отключите это TWI Все периферийные аппаратные соединения и программные процессы связи контроллера).

шаг 4: Конфигурация основных выводов clk Конфигурацияли Входить ХОРОШОПравильно установленнабор。

шаг 5: Тест PIN из функции все в порядке, используйте регистр Читай и пишииз способ, будет PIN Функция напрямую установлена ​​для INPUT Функция(эхо [reg] [val] > /sys/class/sunxi_dump/write), а затем PIN Подтягивание и смена пола PIN-статус, прочитать PIN из статуса (echo [reg,reg] > /sys/class/sunxi_dump/dump;cat дамп), чтобы увидеть, совпадают ли они.

шаг 6: Тест CLK из функции все в порядке, используйте регистр Читай и пишииз способ, будет TWI из CLK gating Подождите, пока он откроется (эхо [reg] [val] > /sys/class/sunxi_dump/write), а затем прочитайте соответствующий TWI из регистрационной информации, прочтите TWI Регистрация данных (echo [reg] ,[len]> /sys/class/sunxi_dump/dump), проверьте, в порядке ли данные регистра.

5.2.3 Сигнал завершения TWI не может быть отправлен

Проблемное явление:STOP can’t рассылка. Бетон из log Как показано ниже:

Язык кода:javascript
копировать
twi_stop()511 - [i2c4] STOP can't sendout!
sunxi_i2c_core_process()1726 - [i2c4] STOP failed!

Анализ проблемы:эта ошибкаповерхность Показывать TWI Невозможно отправить сигнал завершения, обычно за которым следует TWI Автобус изприколоть Конфигурация。отвечать Долженисследоватьприколоть Конфигурация Это правильно?,Является ли напряжение на выводе стабильным и т. д.

Поиск неисправностей

шаг 1: корень По принципу картина, просмотр TWI-SCK и TWI-SDA Целесообразно ли подключать подтягивающий резистор к 3.3v Напряжение.

шаг 2. Используйте мультиметр для измерения SDA и SCL Начальное напряжение, проверьте, существует ли напряжение 3.3V рядом (отключите это TWI Все периферийные аппаратные соединения и программные процессы связи контроллера).

шаг 3: Тест PIN из функции все в порядке, используйте регистр Читай и пишииз способ, будет PIN Функция напрямую установлена ​​для INPUT Функция(эхо [reg] [val] > /sys/class/sunxi_dump/write), а затем PIN Подтягивание и смена пола PIN-статус, прочитать PIN из статуса (echo [reg,reg] > /sys/class/sunxi_dump/dump;cat дамп), чтобы увидеть, совпадают ли они.

шаг 4: Просмотрите конфигурацию дерева устройств и используйте другие SCK/SDA Вывод из узла закрыт, повторите проверку I2C коммуникационная функция.

5.2.4 Тайм-аут передачи TWI

Проблемное явление:xfer тайм-аут. Бетон из log Как показано ниже:

Язык кода:javascript
копировать
[123.681219] sunxi_i2c_do_xfer()1914 - [i2c3] xfer timeout (dev addr:0x50)

Анализ проблемы: Эта ошибка поверхности указывает на то, что ведущее устройство завершило отправку сигнала начала, но процесс связи существует и не может нормально завершить отправку и получение данных, в результате чего сигнал завершения не отправляется на завершение. I2C передачи, вызывая проблему тайм-аута передачи. Должен ли Должен проверить, нормальна ли Конфигурация пина, CLK Конфигурация TWI нормальная? Данные регистра в норме?,Есть ли какие-либо другие помехи от оборудования,середина рассудит, нормально ли это и другие вопросы.

Поиск неисправностей

шаг 1:ядерный Реальность TWI Конфигурация контроллера правильная?

шаг 2: корень По принципу картина, просмотр TWI-SCK и TWI-SDA Целесообразно ли подключать подтягивающий резистор к 3.3v Напряжение.

шаг 3. Используйте мультиметр для измерения SDA и SCL Начальное напряжение, проверьте, существует ли напряжение 3.3V рядом (отключите это TWI Все периферийные аппаратные соединения и программные процессы связи контроллера).

шаг 4: Закрыть другое TWI оборудование,снова Входить ХОРОШОгоретьзаписыватьтест TWI Нормальна ли функция.

шаг 4: Тест PIN из функции все в порядке, используйте регистр Читай и пишииз способ, будет PIN Функция напрямую установлена ​​для INPUT Функция(эхо [reg] [val] > /sys/class/sunxi_dump/write), а затем PIN Подтягивание и смена пола PIN-статус, прочитать PIN из статуса (echo [reg,reg] > /sys/class/sunxi_dump/dump;cat дамп), чтобы увидеть, совпадают ли они.

шаг 5: Тест CLK из функции все в порядке, используйте регистр Читай и пишииз способ, будет TWI из CLK gating Подождите, пока он откроется (эхо [reg] [val] > /sys/class/sunxi_dump/write), а затем прочитайте соответствующий TWI из регистрационной информации, прочтите TWI Регистрация данных (echo [reg] ,[len]> /sys/class/sunxi_dump/dump), проверьте, в порядке ли данные регистра.

шаг 7: корень По данным актуальных из LOG отслеживать TWI Код Выполнить ХОРОШО процесс, проанализировать причину ошибки.

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