i2c user space

Модератор: Модераторы разделов

IMB
Сообщения: 2567
ОС: Debian

i2c user space

Сообщение IMB »

Доброго дня!
Необходимо написать программу для управления контролером по I2C. На основе файла Documentation/i2c/dev_interface написал тестовую программу.
При работе наблюдается ряд проблем:
- при попытке использовать ioctl(file, I2C_SLAVE, addr) на выходе -1, что является ошибкой
решил заменой I2C_SLAVE на I2C_SLAVE_FORCE
- при последовательном чтении из одного регистра значения могут изменяться

Код:

# ./tvp5146control Device File: /dev/i2c-0. Device Address: 0x5d. Device File opened successfully. IOCTL good. I2C read INPUT_SELECT registr value = 0x0. I2C read INPUT_SELECT registr value = 0x80. # ./tvp5146control Device File: /dev/i2c-0. Device Address: 0x5d. Device File opened successfully. IOCTL good. I2C read INPUT_SELECT registr value = 0x0. I2C read INPUT_SELECT registr value = 0x0. # ./tvp5146control Device File: /dev/i2c-0. Device Address: 0x5d. Device File opened successfully. IOCTL good. I2C read INPUT_SELECT registr value = 0x0. I2C read INPUT_SELECT registr value = 0x0. # ./tvp5146control Device File: /dev/i2c-0. Device Address: 0x5d. Device File opened successfully. IOCTL good. I2C read INPUT_SELECT registr value = 0x1e. I2C read INPUT_SELECT registr value = 0x0. # ./tvp5146control Device File: /dev/i2c-0. Device Address: 0x5d. Device File opened successfully. IOCTL good. I2C read INPUT_SELECT registr value = 0x0. I2C read INPUT_SELECT registr value = 0x0.

Почему так может происходить?
Собственно вопрос прост - где бы можно было почитать о программирование управления по I2C из пространства пользователя?
Поиск в Googl-у ничего не дал.
Спасибо.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: i2c user space

Сообщение drBatty »

IMB писал(а):
29.10.2008 15:01
Собственно вопрос прост - где бы можно было почитать о программирование управления по I2C из пространства пользователя?
ну это довольно простенькая задачка. ответ - 2 листка фактов из спецификации :)
как именно это всё работает я бы просто посмотрел например в lm_sensors - Utilities for lm_sensors​. Это градусник для CPU.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: i2c user space

Сообщение IMB »

Спасибо!
Я тут пообщался с техподдержкой и, к сожалению, все не так просто. В моем случае все управляется драйвером и задача сводится к модификации драйвера и написанию управляющей программы.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: i2c user space

Сообщение IMB »

Нашел пример использования ioctl для связывания user space с kernel space - http://tldp.org/LDP/lkmpg/2.6/html/x892.html .
Увы, мой опыт, не позволяет только основываясь на данном примере решить мою задачу.
Может ли кто нибудь поделится ссылка и, в идеале, примерами реализации управления драйверами по ioctl?
Спасибо.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: i2c user space

Сообщение IMB »

И снова приветствую!
Первую часть задачи я вроде решил. Команды по ioctl уходят, внутри драйвера команды по i2c выполняются, результат пока вывожу с помощью printk. Но полученный результат надо передавать в user-space для дальнейшей обработки. Нашел что для этого предназначена функция put_user, но как ее теперь прикрутить к драйверу и откуда потом считать результат?
Функция чтения по i2c в драйвере (жирным выделены мои изменения):

Код:

static int i2c_read_reg(struct i2c_client *client, u8 reg, u8 * val) { int err = 0; struct i2c_msg msg[1]; unsigned char data[1]; int __user *buff; //dev_dbg(tvp5146_i2c_dev, "\nStarting tvp5146 i2c read..."); if (!client->adapter) { err = -ENODEV; } else { msg->addr = client->addr; msg->flags = 0; msg->len = 1; msg->buf = data; data[0] = reg; printk (KERN_INFO "i2c_read_reg reg = %#x\n", reg); err = i2c_transfer(client->adapter, msg, 1); if (err >= 0) { msg->flags = I2C_M_RD; err = i2c_transfer(client->adapter, msg, 1); if (err >= 0) { *val = data[0]; put_user(*val, buff); printk (KERN_INFO "i2c_read_reg reg = %#x, value = %#x\n", reg, *val); } } } //dev_dbg(tvp5146_i2c_dev, "\nEnd of tvp5146 i2c read..."); //printk ("TVP5146 i2c_read_reg return %d.\n", err); return err; }

Собственно вопросы:
- правильно ли я применил put_user()
- откуда я могу считать результат
- где бы можно было еще почитать по тематике
В сети нашел несколько пример, но пока это не принесло просветления.
Спасибо сказали: