Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Linux上使用I2C进行读写_C_Linux_Ioctl_I2c - Fatal编程技术网

在Linux上使用I2C进行读写

在Linux上使用I2C进行读写,c,linux,ioctl,i2c,C,Linux,Ioctl,I2c,我正在尝试读取/写入通过I2C总线连接到地址0b 1010 011上的FM24CL64-GTR FRAM芯片 当我尝试写入3个字节(数据地址2个字节,+数据1个字节)时,我会收到一条内核消息([12406.360000]i2c适配器i2c-0:sendbytes:NAK-bailout.),并且写入返回!=3.见下面的代码: #include <linux/i2c-dev.h> #include <fcntl.h> #include <unistd.h> #i

我正在尝试读取/写入通过I2C总线连接到地址
0b 1010 011
上的
FM24CL64-GTR FRAM
芯片

当我尝试写入3个字节(数据地址2个字节,+数据1个字节)时,我会收到一条内核消息(
[12406.360000]i2c适配器i2c-0:sendbytes:NAK-bailout.
),并且写入返回!=3.见下面的代码:

#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>

int file;
char filename[20];
int addr = 0x53; // 0b1010011; /* The I2C address */
uint16_t dataAddr = 0x1234;
uint8_t val = 0x5c;
uint8_t buf[3];

sprintf(filename,"/dev/i2c-%d",0);
if ((file = open(filename,O_RDWR)) < 0)
    exit(1);

if (ioctl(file,I2C_SLAVE,addr) < 0)
    exit(2);

buf[0] = dataAddr >> 8;
buf[1] = dataAddr & 0xff;
buf[2] = val;

if (write(file, buf, 3) != 3)
    exit(3);

...
#包括
#包括
#包括
#包括
int文件;
字符文件名[20];
int addr=0x53;//0b1010011;/*I2C地址*/
uint16_t dataAddr=0x1234;
uint8_t val=0x5c;
uint8_t buf[3];
sprintf(文件名“/dev/i2c-%d”,0);
如果((文件=打开(文件名,O_RDWR))<0)
出口(1);
如果(ioctl(文件,I2C_从机,地址)<0)
出口(2);
buf[0]=dataAddr>>8;
buf[1]=dataAddr&0xff;
buf[2]=val;
if(写入(文件,buf,3)!=3)
出口(3);
...
然而,当我写2个字节,然后再写另一个字节时,我没有得到内核错误,但是当尝试从FRAM读取时,我总是得到0。以下是从FRAM读取的代码:

uint8_t val;

if ((file = open(filename,O_RDWR)) < 0)
    exit(1);

if (ioctl(file,I2C_SLAVE,addr) < 0)
    exit(2);

if (write(file, &dataAddr, 2) != 2) {
    exit(3);

if (read(file, &val, 1) != 1) {
    exit(3);
uint8\t val;
如果((文件=打开(文件名,O_RDWR))<0)
出口(1);
如果(ioctl(文件,I2C_从机,地址)<0)
出口(2);
if(写入(文件和数据地址,2)!=2){
出口(3);
if(读取(文件,&val,1)!=1){
出口(3);
所有函数都不会返回错误值,我也尝试过:

#include <linux/i2c.h>

struct i2c_rdwr_ioctl_data work_queue;
struct i2c_msg msg[2];
uint8_t ret;

work_queue.nmsgs = 2;
work_queue.msgs = msg;

work_queue.msgs[0].addr = addr;
work_queue.msgs[0].len = 2;
work_queue.msgs[0].flags = 0;
work_queue.msgs[0].buf = &dataAddr;

work_queue.msgs[1].addr = addr;
work_queue.msgs[1].len = 1;
work_queue.msgs[1].flags = I2C_M_RD;
work_queue.msgs[1].buf = &ret;

if (ioctl(file,I2C_RDWR,&work_queue) < 0)
    exit(3);
#包括
结构i2c_rdwr_ioctl_数据工作队列;
结构i2c_msg msg[2];
uint8_t ret;
work_queue.nmsgs=2;
work_queue.msgs=msg;
工作队列.msgs[0].addr=addr;
工作队列.msgs[0].len=2;
工作队列.msgs[0]。标志=0;
工作队列.msgs[0].buf=&dataAddr;
工作队列.msgs[1].addr=addr;
work_queue.msgs[1].len=1;
work_queue.msgs[1]。flags=I2C_M_RD;
工作队列.msgs[1].buf=&ret;
if(ioctl(文件、I2C\U RDWR和工作队列)<0)
出口(3);
它也会成功,但总是返回0。这是表示硬件问题,还是我做错了什么


Linux上是否有I2C上FM24CL64-GTR的FRAM驱动程序,API是什么?任何链接都会很有帮助。

我没有使用该特定设备的经验,但根据我们的经验,许多I2C设备都有需要解决的“怪癖”,通常高于驱动程序级别

我们在linux中使用linux(CELinux)和I2C设备驱动程序,但我们的应用程序代码中也有一个非常重要的I2C模块,其中包含了处理我们使用过的各种设备的所有变通智能

此外,在处理I2C问题时,我经常发现我需要重新熟悉源代码规范:

以及使用像样的示波器

祝你好运

上面的链接已失效,下面是一些其他链接:

当然,维基百科:

NAK是一个很大的提示:WriteProtect引脚被外部拔出,必须被驱动到地上,然后单次写入地址并后跟数据字节成功(第一个代码段)


对于读取,可以先写入地址(使用write()),然后从该地址开始读取顺序数据。

请注意,使用
struct i2c_rdwr_ioctl_data
struct i2c_msg
的方法(即您给出的最后一个代码部分)比其他方法更有效,因为使用该方法可以执行I2c的重复启动功能

这意味着您避免了
STA-WRITE-STO->STA-READ-…-STO
转换,因为您的通信将变成
STA-WRITE-RS-READ-…STO
RS
=重复启动)。因此,为您节省了冗余的
STO-STA
瞬态

并不是说它在时间上有很大的不同,但如果它不需要,为什么要失去它

就我的2 ct

最好的RGD,

你犯了一些错误


ic
的地址是以十六进制表示的
Ax
x
可以是任何东西,但4个高位应该是
A=1010
!!!

您应该使用exit()(不带前导下划线),而不是_exit()。_exit()没有正确关闭libc。谢谢,这只是硬件启动测试代码,但仍然感谢您的反馈。今天早上我将从示波器开始,并在它工作后发布我的发现,除非其他人有适用于Linux的FRAM I2C驱动程序,但我找不到。如果“I2C I2C-1:sendbytes:NAK紧急援助”怎么办是否出现在Linux日志中?