Почему i2c_smbus_write_byte_data может возвращать "Операция запрещена" в uClinux 2.4?
Я пишу программу на языке C с целью настройки периферийного устройства (АЦП CS5368) через интерфейс I2C Dante Brooklyn II, платы на базе процессора Soft-Core Microblaze под управлением uClinux 2.4.
Я реализовал конфигурацию в соответствии с документами Dante OEM в качестве руководства, однако при запуске моей программы я получаю сообщение "Операция запрещена" (EPERM
) ошибка при попытке записи данных в I2C с помощью i2c_smbus_write_byte_data
.
Вот фрагмент кода, содержащий вызов виновника i2c_smbus_write_byte_data
:
// Set ADC I2S to "Slave mode all speeds".
printf("Set the CS5368 I2S mode to slave\n");
unsigned char adc_dif = 0x01; // I2S mode
unsigned char adc_mode = 0x03; // Slave mode all speeds
unsigned char data = 0x90 | (adc_dif << 2) | adc_mode;
result = i2c_smbus_write_byte_data(i2c_fd, CS5368_GCTL_MDE, data);
if (result < 0) {
perror("Failed to write to the 'Global Mode Control' register");
return -1;
}
Вот код в контексте полного исходного кода небольшой программы. Программа начинается со сброса CS5368 через вывод GPIO перед выполнением настройки через I2C.
EPERM
возвращается независимо от того, подключен ли CS5368. Мне удалось успешно настроить CS5368, используя интерфейс I2C Arduino Uno, поэтому проблема, похоже, не связана с CS5368.
Для запуска программы я захожу на доску через telnet
в качестве root
, поэтому я сомневаюсь, что ошибка имеет какое-либо отношение к разрешениям пользователя.
В документации OEM говорится:
Модуль Brooklyn II может работать как контроллер I2C, работающий на частоте 100 кГц и использующий 7-битный режим адресации. Он поддерживает работу с несколькими мастерами. Доступ к устройствам I2C можно получить из пользовательского приложения, запущенного в модуле Brooklyn II. Интерфейс поддерживает протокол SMBus (шина управления системой), который является подмножеством протокола I2C.
Далее приводится список поддерживаемых i2c_smbus_*
функции, включая i2c_smbus_write_byte_data
, поэтому проблема, похоже, не связана с отсутствием поддержки SMBus или I2C.
Я столкнулся с связанной проблемой, когда пользователь получалEPERM
код ошибки при попытке использовать I2C write
API, однако решение, похоже, заключалось в использовании i2c_smbus_*
API вместо того, что я уже делаю.
Мы будем очень благодарны за любые советы о том, что может быть причиной возврата этого кода ошибки или как отладить проблему в дальнейшем!
Изменить: в случае, если это помогает, вот полный вывод, начиная с входа на плату через telnet после перемещения exe в /tmp
через ftp:
$ telnet 169.254.72.245
Trying 169.254.72.245...
Connected to 169.254.72.245.
Escape character is '^]'.
login: root
Password:
BusyBox v1.23.2 (2018-05-31 11:33:18 AEST) hush - the humble shell
/ # cd /tmp
/var/tmp # ./cs5368-i2c-config
Open GPIO device
Set GPIO tristate outputs
Set GPIO pins low
Sleep for 10 secs
Set GPIO pins high
Close GPIO file descriptor
Searching for I2C device
Opening /dev/i2c-0
Setting I2C_SLAVE 4c...
I2C Interface found: /dev/i2c-0
Set the CS5368 as the slave
Set the CS5368 I2S mode to slave
Failed to write to the 'Global Mode Control' register: Operation not permitted