Chinaunix首页 | 论坛 | 博客
  • 博客访问: 309803
  • 博文数量: 66
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 509
  • 用 户 组: 普通用户
  • 注册时间: 2015-04-29 13:56
文章分类
文章存档

2018年(2)

2017年(6)

2016年(34)

2015年(24)

我的朋友

分类: 嵌入式

2016-12-07 13:12:38

应用程序可以通过dtb配置内核,也可以编译KO访问内核空间,这2种方法内核态开发。
如果想要在用户空间访问I2C驱动,还有一种方法,就是通过IOCTL 来实现,这种方式是纯用户空间开发。

比如现在有需求ARM和MCU之间通过I2C总线通信(控制风扇或者其他设备),ARM 侧则可以通过用户空间访问I2C client.

具体如下。

1. 打开I2c总线设备,比如i2c-0,i2c-1等。
fd=open("/dev/i2c-1",O_RDWR);
if(fd < 0)
{ //error info }
2. 驱动I2C 从机地址
if (ioctl(file, I2C_SLAVE_FORCE, addr) < 0) 
{ 
// error info
}
3. read/write 读写I2c总线,或者通过IOCTL读写
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
	int fd,ret;
	struct i2c_rdwr_ioctl_data codec_data;

	fd=open("/dev/i2c-3",O_RDWR);
	if(fd<0)
		perror("open error");

#if 0  // write/read 方式
    if (ioctl(fd, I2C_SLAVE_FORCE, 0x40>>1) < 0)
        {
                printf("set slave dev addrs failed\n");
                return -1;
        }
       memset(buf, 0, sizeof(buf));

        // read fan speed
        buf[0] = 0xAA;
        buf[1] = 0xAA;
        buf[2] = 0x04;

        iRtn = write(fd, buf, 3);
        if (iRtn != 3)
        {
                printf("Get fan speed: write data error %d\n", iRtn);
                printf("Error: write data failure %s, errno %x\n", strerror(errno), errno);
                return -1;
        }

        memset(Resp, 0, sizeof(Resp));
        iRtn = read(fd, Resp, 5);
        if (iRtn != 5)
        {
                printf("Get fan speed: read data error %d\n", iRtn);
                printf("Error: write data failure %s\n", strerror(errno));
                return -1;
        }
#endif

        //ioclt方式
	codec_data.nmsgs=2;
	codec_data.msgs=(struct i2c_msg*)malloc(codec_data.nmsgs*sizeof(struct i2c_msg));
	if(!codec_data.msgs)
	{
		perror("malloc error");
		exit(1);
	}
	ioctl(fd,I2C_TIMEOUT,1);/*超时时间*/
	ioctl(fd,I2C_RETRIES,2);/*重复次数*/
	sleep(1);

	codec_data.nmsgs=1;
	(codec_data.msgs[0]).len=2; 
	(codec_data.msgs[0]).addr=(0x36 >> 1);//我的音频硬件地址;
	(codec_data.msgs[0]).flags=0; //write
	(codec_data.msgs[0]).buf=(unsigned char*)malloc(2);
	(codec_data.msgs[0]).buf[0]=0x04;
	(codec_data.msgs[0]).buf[1]=0x55;//the data to write
	ret=ioctl(fd,I2C_RDWR,(unsigned long)&codec_data);
	if(ret<0)
		perror("ioctl error1");
	sleep(1);

	/******read data from e2prom*******/
	printf("read start\n");
	codec_data.nmsgs=2;
	(codec_data.msgs[0]).len=1; //e2prom 目标数据的地址
	(codec_data.msgs[0]).addr=(0x36 >> 1);//yinpin;
	(codec_data.msgs[0]).flags=0;//write
	(codec_data.msgs[0]).buf[0]=0x04;
	(codec_data.msgs[1]).len=1;//读出的数据
	(codec_data.msgs[0]).addr=(0x36 >> 1);
	(codec_data.msgs[1]).flags=I2C_M_RD;//read
	(codec_data.msgs[1]).buf=(unsigned char*)malloc(1);//存放返回值的地址。
	(codec_data.msgs[1]).buf[0]=0;//初始化读缓冲
	ret=ioctl(fd,I2C_RDWR,(unsigned long)&codec_data);
	if(ret<0)
		perror("ioctl error2");
	close(fd);
	return 0;
}
阅读(3577) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~