尝试通过JNI在Android(Gingerbread)中使用I2C设备时遇到问题。
问题出在I2C_SLAVE ioctl调用上。以下代码在编译为独立程序时有效:
int main(int argc, char *argv[])
{
int fd = -1;
long rc;
int addr = 0x22;
if ( fd < 0 ) {
fd = open(radio_device, O_RDWR);
}
#define I2C_SLAVE 0x0703
if ( (rc = ioctl(fd, I2C_SLAVE, addr)) < 0 ) {
printf("RadioService: I2C slave addr failed! rc=%d errno= %d [%s]\n", rc, errno, strerror(errno));
}
else {
printf("RadioService: I2C slave addr 0x%x set\n", addr);
}
return 0;
}
运行时输出(通过adb shell
):
~ # testi2c
RadioService: I2C slave addr 0x22 set
但是,相同的代码不能作为JNI库的一部分:
void Java_biz_lectronix_android_radio_RadioService_nativeInit(JNIEnv* env, jclass clazz)
{
long rc;
int addr1 = 0x22;
int addr2 = 0x18;
if ( fd = open(radio_device, O_RDWR) < 0 ) {
__android_log_print(ANDROID_LOG_ERROR, "RadioService", "I2C open failed! %s", strerror(errno));
}
else {
__android_log_write(ANDROID_LOG_WARN, "RadioService", "Opened fd");
}
__android_log_print(ANDROID_LOG_ERROR, "RadioService", "I2C_SLAVE [0x%x], addr = %d (0x%x)", I2C_SLAVE, addr1, addr1 );
if ( (rc = ioctl(fd, I2C_SLAVE, addr1)) < 0 ) {
__android_log_print(ANDROID_LOG_ERROR, "RadioService", "I2C slave addr1 failed! rc=%d errno= %d [%s]", rc, errno, strerror(errno));
}
else {
__android_log_print(ANDROID_LOG_WARN, "RadioService", "I2C slave addr1 %d set", addr1);
}
if ( (rc = ioctl(fd, I2C_SLAVE, addr2)) < 0 ) {
__android_log_print(ANDROID_LOG_ERROR, "RadioService", "I2C slave addr2 failed! rc=%d errno= %d [%s]", rc, errno, strerror(errno));
}
else {
__android_log_print(ANDROID_LOG_WARN, "RadioService", "I2C slave addr2 %d set", addr2);
}
return;
}
Logcat输出:
01-02 03:03:10.904: E/RadioService(1602): I2C_SLAVE [0x703], addr = 34 (0x22)
01-02 03:03:10.904: E/RadioService(1602): I2C slave addr1 failed! rc=-1 errno= 25 [Not a typewriter]
01-02 03:03:10.904: E/RadioService(1602): I2C slave addr2 failed! rc=-1 errno= 25 [Not a typewriter]
有谁知道这里有什么问题?
答案 0 :(得分:1)
根本不是I2C接口的问题。问题是这一行:
if ( fd = open(radio_device, O_RDWR) < 0 ) {
应该是这个(注意括号):
if ( ( fd = open(radio_device, O_RDWR) ) < 0 ) {
因此,I2C设备被打开,但比较的优先级高于C中的赋值。比较失败,将0分配给fd - 即stdin
。
然后ioctl()
调用失败,因为I2C_SLAVE对于设备来说是不合适的ioctl命令。