简体   繁体   English

I2C-dev:更改写入和读取参数

[英]I2C-dev: Change write and read parameters

I'm currently working on I2C between a Raspberry Pi 3 and a PsoC 4. I'm using the I2C-dev library to handle the I2C communication.我目前正在 Raspberry Pi 3 和 PsoC 4 之间处理 I2C。我正在使用 I2C-dev 库来处理 I2C 通信。 So the I2C bus is up and running, and the read and write function has been implemented correctly.这样I2C总线就正常运行了,读写功能已经正确实现了。 I want however to make functions pointer the read and write functions hence the to functions uses the same types of arguments (atleast it looks like) I have the following main code called I然而,我想让函数指针指向读取和写入函数,因此 to 函数使用相同类型的参数(至少看起来像)我有以下主要代码称为 I

2Ctest-tools.cpp : 2Ctest-tools.cpp

#include <unistd.h>             //Needed for I2C port
#include <fcntl.h>              //Needed for I2C port
#include <sys/ioctl.h>          //Needed for I2C port
#include <linux/i2c-dev.h>      //Needed for I2C port
#include <stdio.h>
#include "i2c.h"
#include "functions.h"


int main() {


        int addr = 0x49;
        int cmd = 2; //Write
        int length = 5;
        int file_i2c = 0;
        I2C myI2C;



        unsigned char buffer[5];

        buffer[0] = 0x01;
        buffer[1] = 0x02;
        buffer[2] = 0x20;
        buffer[3] = 0x00;
        buffer[4] = 0x17;

        i2c_init(&myI2C, cmd, addr, &file_i2c);
        i2c_exe(&myI2C, file_i2c, buffer, length);

    return 0;
}

As shown in the code, im using a object of the struct called myI2C which is passed in the two functions i2c_init, i2c_exe.如代码所示,im 使用了名为 myI2C 的结构对象,该对象在 i2c_init、i2c_exe 两个函数中传递。 The source code for functions.cpp is in the following: functions.cpp 的源代码如下:

#include <unistd.h>             //Needed for I2C port
#include <fcntl.h>              //Needed for I2C port
#include <sys/ioctl.h>          //Needed for I2C port
#include <linux/i2c-dev.h>      //Needed for I2C port
#include <stdio.h>
#include "i2c.h"
#include "functions.h"

int i2c_init(I2C *cthis, int cmd, int addr, int *ptrFile_i2c ) {
    char *filename = (char*)"/dev/i2c-1";
    if ((*ptrFile_i2c = open(filename, O_RDWR)) < 0)
    {
        //ERROR HANDLING: you can check errno to see what went wrong
        printf("Failed to open the i2c bus");
        return 0;
    }

    if (ioctl(*ptrFile_i2c, I2C_SLAVE, addr) < 0)
    {
        printf("Failed to acquire bus access and/or talk to slave.\n");
        //ERROR HANDLING; you can check errno to see what went wrong
        return 0;
    }

    switch(cmd) {
        case 1: 
            //cthis->WR = write;
            break;
        case 2:
            cthis->WR = read;
            break;
    }
    return 0;
}

int i2c_exe(I2C *cthis, int file_i2c, unsigned char *buffer, size_t length) {

    cthis->WR(file_i2c, buffer, length);
    return 0;
}

So the important thing to note here is that in the function i2c_init im switching on the varialbe cmd, which dictates whether the function pointer will point on the write or read function.所以这里要注意的重要一点是,在函数 i2c_init im 中打开了 varialbe cmd,它决定了函数指针是指向写函数还是读函数。 Now the failure part comes in. The functions pointer is declared in its own .h file called i2c.h and looks like this:现在失败部分来了。函数指针在它自己的名为 i2c.h 的 .h 文件中声明,如下所示:

struct I2C {
    ssize_t (*WR)(int, const void   *, size_t);
};

As you can see the function pointer has to point on a function with the parameters (int, const void*, size_t) this works like a charm when the function points on the write function BUT when it points on the read function im getting and error, the error says:正如你所看到的,函数指针必须指向一个带有参数(int、const void*、size_t)的函数,当函数指向写函数时,这就像一个魅力,但当它指向读函数时,我得到了错误,错误说:

functions.cpp: In function 'int i2c_init(I2C*, int, int, int*)': functions.cpp:30:14: error: invalid conversion from 'ssize_t ( )(int, void , size_t) {aka int ( )(int, void , unsigned int)}' to 'ssize_t ( )(int, const void , size_t) {aka int ( )(int, const void , unsigned int)}' [-fpermissive] cthis->WR = read; functions.cpp:在函数'诠释i2c_init(I2C *,INT,INT,INT *)':functions.cpp:30:14:错误:从“ssize_t供无效的转换()(INT,空隙为size_t){又名INT( )(int, void , unsigned int)}' 到 'ssize_t ( )(int, const void , size_t) {aka int ( )(int, const void , unsigned int)}' [-fpermissive] cthis->WR = read ;

I have studied the error and concluded that it's because the read and write function somehow does not take the same arguments, which is weird because im passing the same arguments in them (int i2s_file, int buffer, int length) so if i change the function pointer to我研究了错误并得出结论,这是因为读写函数以某种方式不采用相同的参数,这很奇怪,因为我在其中传递了相同的参数(int i2s_file,int buffer,int length)所以如果我更改函数指向

ssize_t (*WR)(int, void *, size_t);

the function works with read but not with write.. So my question is: can i somehow change the write or read function to take the same argument by changing the i2c-dev library or is there anything else i could do to solve this problem?该函数适用于读取但不适用于写入..所以我的问题是:我可以通过更改 i2c-dev 库以某种方式更改 write 或 read 函数以采用相同的参数,或者我还能做些什么来解决这个问题?

here's a link to the i2c-dev library, which i have completely giving up to understand http://textuploader.com/5yioi这是 i2c-dev 库的链接,我已经完全放弃理解http://textuploader.com/5yioi

thanks in advanced提前致谢

You can cast the functions explicitly to the correct type:您可以将函数显式转换为正确的类型:

typedef ssize_t (*I2CCMD)(int, void *, size_t);

cthis->WR = (I2CCMD)write;

cthis->WR = (I2CCMD)read;

This should eliminate the error.这应该消除错误。

Obviously the read function cannot take a pointer to const since, unlike the write function, it has to modify that parameter.显然read函数不能使用指向const的指针,因为与write函数不同,它必须修改该参数。

So you cannot switch functionality with a function pointer, because the function pointers are of different types.所以你不能用函数指针来切换功能,因为函数指针是不同的类型。

The best work-arounds seem to be either moving the "cmd" parameter to the i2c_exe function, or alternatively create a private variable containing cmd (inside struct I2C would be ideal).最好的解决方法似乎是将“cmd”参数移动到i2c_exe函数,或者创建一个包含cmd的私有变量(在struct I2C内是理想的)。 And then in i2c_exe either call read or write.然后在i2c_exe中调用 read 或 write。

A worse solution is to change the struct to a union, like:更糟糕的解决方案是将结构更改为联合,例如:

union I2C {
    ssize_t (*WR)(int, const void   *, size_t);
    ssize_t (*read)(int, void*, size_t);
};

Then in case of reads, use the read member to assign to the struct.然后在读取的情况下,使用读取成员分配给结构。 But please note that this is kind of a "dirty hack", it is poorly-specified behavior in theory.但请注意,这是一种“肮脏的黑客”,理论上它是指定不明确的行为。 In practice, it will most likely work on any given system.在实践中,它很可能适用于任何给定的系统。 (It is very unlikely that const correctness would ever affect calling convention.) (const 的正确性不太可能影响调用约定。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM