下面的代码是读写IIC设备的寄存器,其支持的类型是:
寄存器地址8位
寄存器值16位
程序用法如下:
向i2c-3的总线上的0x12设备的寄存器写0x1234
./i2c_rw /dev/i2c-3 0x12 w 0x14 0x1234
向i2c-3的总线上的0x12设备读寄存器0xfe
./i2c_rw /dev/i2c-3 0x12 r 0xfe
#include <stdio.h>
#include <linux/types.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
static void Usage(char *argv[])
{
printf("Usage:\n");
printf("%s /dev/i2c-x salve_addr r/w reg_addr [value]\n", argv[0]);
printf("%s /dev/i2c-3 0x12 r 0xfe \n", argv[0]);
printf("%s /dev/i2c-3 0x12 w 0x14 0x1234 \n", argv[0]);
}
static int i2c_write_bytes(int fd, uint8_t slave_addr, uint8_t reg_addr, uint8_t *values, uint8_t len)
{
uint8_t *outbuf = NULL;
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[1];
outbuf = malloc(len + 1);
if (!outbuf)
{
printf("Error: No memory for buffer\n");
return -1;
}
outbuf[0] = reg_addr;
memcpy(outbuf + 1, values, len);
messages[0].addr = slave_addr;
messages[0].flags = 0;
messages[0].len = len + 1;
messages[0].buf = outbuf;
/* Transfer the i2c packets to the kernel and verify it worked */
packets.msgs = messages;
packets.nmsgs = 1;
if(ioctl(fd, I2C_RDWR, &packets) < 0)
{
printf("Error: Unable to send data\n");
free(outbuf);
return -1;
}
free(outbuf);
return 0;
}
static int i2c_read_bytes(int fd, uint8_t slave_addr, uint8_t reg_addr, uint8_t *values, uint8_t len)
{
uint8_t outbuf[1];
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
outbuf[0] = reg_addr;
messages[0].addr = slave_addr;
messages[0].flags = 0;
messages[0].len = sizeof(outbuf);
messages[0].buf = outbuf;
/* The data will get returned in this structure */
messages[1].addr = slave_addr;
messages[1].flags = I2C_M_RD/* | I2C_M_NOSTART*/;
messages[1].len = len;
messages[1].buf = values;
/* Send the request to the kernel and get the result back */
packets.msgs = messages;
packets.nmsgs = 2;
if(ioctl(fd, I2C_RDWR, &packets) < 0)
{
printf("Error: Unable to send data");
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
int fd;
uint8_t w_buf[2];
uint8_t r_buf[2];
if(argc != 5 && argc != 6)
{
Usage(argv);
return -1;
}
// 打开I2C对应的设备节点
fd = open(argv[1], O_RDWR);
if(fd < 0)
{
printf("Error: Unable to open %s\n", argv[1]);
return -1;
}
uint8_t slave_addr = strtoul(argv[2], NULL, 16);
uint8_t reg_addr = strtoul(argv[4], NULL, 16);
uint32_t value = 0;
if(argc == 6)
{
value = strtoul(argv[5], NULL, 16);
w_buf[0] = value & 0xff;
w_buf[1] = (value >> 8) & 0xff;
}
if(strcmp(argv[3], "w") == 0 && argc == 6)
{
if(i2c_write_bytes(fd, slave_addr, reg_addr, w_buf, 2) < 0)
{
printf("Error: Writing to slave failed\n");
close(fd);
return -1;
}
}
else if(strcmp(argv[3], "r") == 0)
{
memset(r_buf, 0, sizeof(r_buf));
if(i2c_read_bytes(fd, slave_addr, reg_addr, r_buf, 2) < 0)
{
printf("Error: Reading from slave failed\n");
close(fd);
return -1;
}
printf("read: 0x%02x%02x\n", r_buf[1], r_buf[0]);
}
else
{
printf("Error: Invalid operation\n");
close(fd);
return -1;
}
close(fd);
return 0;
}