最近在调试Android系统下的I2C,主要用于读取数据,所以下面代码只有I2C读取。
关于Android系统下如何增加C语言app,可以参考:
Android版本:Android 13
内核版本:5.15
以下是I2C读取代码,在设备上验证通过:
#include <stdio.h>
#include <linux/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <string.h>
#include <errno.h>
/*********定义struct i2c_rdwr_ioctl_data和struct i2c_msg,要和内核一致*******/
/***********主程序***********/
int main(int argc, char* argv[])
{
int fd = 0, ret;
char *s_Dev = NULL;
unsigned char s_Write[4];
unsigned char *p_Read = NULL;
unsigned short read_len = 0;
unsigned char device_addr = 0x55; /* 设备地址 */
unsigned char data_addr = 0x0; /* 数据地址 */
struct i2c_msg i2cmsg[2];
int loop = 1;
char *endptr;
int result = 0;
if(argc != 5)
{
printf("Usage: %s i2c-device slave_addr(Hex) reg_addr(Hex) lenth_to_read(Dec)\n", argv[0]);
printf("Example: %s /dev/i2c-1 0x55 0x9c 3\n", argv[0]);
result = -1;
goto err;
}
s_Dev = argv[1];
device_addr = strtol(argv[2], &endptr, 16);
data_addr = strtol(argv[3], &endptr, 16);
read_len = atoi(argv[4]);
fd = open(s_Dev, O_RDWR);
if (fd < 0)
{
printf("open failed [%s]\n", s_Dev);
perror("open error");
result = -2;
goto err;
}
printf("open [%s] ok !\n", s_Dev);
p_Read = malloc(read_len);
if(NULL == p_Read)
{
printf("malloc [%d] error.\n", read_len);
result = -3;
goto err;
}
struct i2c_rdwr_ioctl_data msg_rdwr; // = {.msgs = i2cmsg, .nmsgs = 2};
msg_rdwr.msgs = i2cmsg;
msg_rdwr.nmsgs = 2;
ioctl(fd, I2C_TIMEOUT, 1); /*超时时间*/
ioctl(fd, I2C_RETRIES, 2); /*重复次数*/
/** read data begin **/
endptr = argv[1];
s_Write[0] = data_addr;
s_Write[1] = 0;
msg_rdwr.msgs[0].addr = device_addr; // 设备地址
msg_rdwr.msgs[0].flags = 0; // write
msg_rdwr.msgs[0].buf = s_Write; // 数据地址
msg_rdwr.msgs[0].len = 1;
msg_rdwr.msgs[1].addr = device_addr; // 设备地址
msg_rdwr.msgs[1].flags = 1; // read
msg_rdwr.msgs[1].buf = p_Read; //读出的数据
msg_rdwr.msgs[1].len = read_len; //读出数据的长度
ret = ioctl(fd, I2C_RDWR, (unsigned long)&msg_rdwr);
if (ret < 0)
{
perror("ioctl error1");
result = -4;
goto err;
}
else
{
printf("ret[%d]\n", ret);
}
printf("write[len:%d]: \t", msg_rdwr.msgs[0].len);
for(loop = 0; loop < msg_rdwr.msgs[0].len; loop++)
{
printf(" %02x", s_Write[0]);
}
printf("\n");
printf("read[len:%d]: \t", msg_rdwr.msgs[1].len);
for(loop = 0; loop < msg_rdwr.msgs[1].len; loop++)
{
printf(" %02x", p_Read[loop]);
}
printf("\n");
/** read data end **/
err:
if(NULL != p_Read)
{
free(p_Read);
}
if(fd > 0)
{
close(fd);
}
return result;
}
设备上验证:
逻辑分析仪抓到的:
1.以下是master给slave发送的,包括slave设备地址、CommandID(有些器件需要发送寄存器地址,更具slave设备的要求确定)
解码结果如下,地址解析出来是0xAA,应该是有点问题的,由于我发送的地址是0x55;有可能是逻辑分析仪把read/write位作为地址的最低bit了。
2. master收到slave的回复之后,发送CommandID:
逻辑分析仪解析结果如下:
3. slave根据master发送的CommandID,给master回复消息:
逻辑分析仪解析如下:
至此,I2C数据的读取就算完成了。