I2C-dev:更改写入和读取参数
I2C-dev: Change write and read parameters
我目前正在研究 Raspberry Pi 3 和 PsoC 4 之间的 I2C。我正在使用 I2C-dev 库来处理 I2C 通信。至此I2C总线up运行,读写功能已经正确实现。但是,我想让函数指向读写函数,因此 to 函数使用相同类型的参数(至少看起来像)我有以下主要代码,称为 I
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;
}
如代码所示,我正在使用一个名为 myI2C 的结构对象,该对象在两个函数 i2c_init、i2c_exe 中传递。 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;
}
所以这里要注意的重要一点是,在函数 i2c_init 中,我打开了 varialbe cmd,这决定了函数指针是指向写入函数还是读取函数。现在失败部分来了。函数指针在其自己的名为 i2c.h 的 .h 文件中声明,如下所示:
struct I2C {
ssize_t (*WR)(int, const void *, size_t);
};
如您所见,函数指针必须指向带有参数 (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;
我研究了错误并得出结论,这是因为读写函数不知何故没有采用相同的参数,这很奇怪,因为我在其中传递了相同的参数(int i2s_file,int buffer, int length) 所以如果我将函数指针更改为
ssize_t (*WR)(int, void *, size_t);
该函数适用于读取,但不适用于写入。所以我的问题是:我能否通过更改 i2c-dev 库以某种方式更改写入或读取函数以采用相同的参数,或者还有什么我可以做的解决这个问题?
这是 i2c-dev 库的 link,我已经完全放弃去理解它 http://textuploader.com/5yioi
提前致谢
您可以将函数显式转换为正确的类型:
typedef ssize_t (*I2CCMD)(int, void *, size_t);
cthis->WR = (I2CCMD)write;
cthis->WR = (I2CCMD)read;
这应该可以消除错误。
显然 read
函数不能接受指向 const
的指针,因为与 write
函数不同,它必须修改该参数。
所以不能用函数指针切换功能,因为函数指针的类型不同。
最好的解决方法似乎是将 "cmd" 参数移动到 i2c_exe
函数,或者创建一个包含 cmd
的私有变量(在 struct I2C
将是理想的)。然后在 i2c_exe
中调用读取或写入。
一个更糟糕的解决方案是将结构更改为联合,例如:
union I2C {
ssize_t (*WR)(int, const void *, size_t);
ssize_t (*read)(int, void*, size_t);
};
然后在读取的情况下,使用读取成员分配给结构。但请注意,这是一种 "dirty hack",理论上是一种不明确的行为。实际上,它很可能适用于任何给定系统。 (const 正确性不太可能影响调用约定。)
我目前正在研究 Raspberry Pi 3 和 PsoC 4 之间的 I2C。我正在使用 I2C-dev 库来处理 I2C 通信。至此I2C总线up运行,读写功能已经正确实现。但是,我想让函数指向读写函数,因此 to 函数使用相同类型的参数(至少看起来像)我有以下主要代码,称为 I
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;
}
如代码所示,我正在使用一个名为 myI2C 的结构对象,该对象在两个函数 i2c_init、i2c_exe 中传递。 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;
}
所以这里要注意的重要一点是,在函数 i2c_init 中,我打开了 varialbe cmd,这决定了函数指针是指向写入函数还是读取函数。现在失败部分来了。函数指针在其自己的名为 i2c.h 的 .h 文件中声明,如下所示:
struct I2C {
ssize_t (*WR)(int, const void *, size_t);
};
如您所见,函数指针必须指向带有参数 (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;
我研究了错误并得出结论,这是因为读写函数不知何故没有采用相同的参数,这很奇怪,因为我在其中传递了相同的参数(int i2s_file,int buffer, int length) 所以如果我将函数指针更改为
ssize_t (*WR)(int, void *, size_t);
该函数适用于读取,但不适用于写入。所以我的问题是:我能否通过更改 i2c-dev 库以某种方式更改写入或读取函数以采用相同的参数,或者还有什么我可以做的解决这个问题?
这是 i2c-dev 库的 link,我已经完全放弃去理解它 http://textuploader.com/5yioi
提前致谢
您可以将函数显式转换为正确的类型:
typedef ssize_t (*I2CCMD)(int, void *, size_t);
cthis->WR = (I2CCMD)write;
cthis->WR = (I2CCMD)read;
这应该可以消除错误。
显然 read
函数不能接受指向 const
的指针,因为与 write
函数不同,它必须修改该参数。
所以不能用函数指针切换功能,因为函数指针的类型不同。
最好的解决方法似乎是将 "cmd" 参数移动到 i2c_exe
函数,或者创建一个包含 cmd
的私有变量(在 struct I2C
将是理想的)。然后在 i2c_exe
中调用读取或写入。
一个更糟糕的解决方案是将结构更改为联合,例如:
union I2C {
ssize_t (*WR)(int, const void *, size_t);
ssize_t (*read)(int, void*, size_t);
};
然后在读取的情况下,使用读取成员分配给结构。但请注意,这是一种 "dirty hack",理论上是一种不明确的行为。实际上,它很可能适用于任何给定系统。 (const 正确性不太可能影响调用约定。)