我目前正在研究Raspberry Pi 3和PsoC 4之间的I2C。我正在使用I2C-dev库来处理I2C通信。因此I2C总线启动并运行,读写功能已正确实现。但是我想让函数指针成为读写函数,因此to函数使用相同类型的参数(至少它看起来像)我有以下主要代码叫做
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,它指示函数指针是否指向写或读函数。现在失败部分进来了。函数指针在它自己的.h文件中声明,名为i2c.h,如下所示:
struct I2C {
ssize_t (*WR)(int, const void *, size_t);
};
正如你所看到的那样,函数指针必须指向一个带参数的函数(int,const void *,size_t),当函数指向写入函数时它就像魅力一样当它指向读取函数时得到和错误,错误说:
functions.cpp:在函数'int i2c_init(I2C *,int,int,int *)'中: functions.cpp:30:14:错误:来自'ssize_t()的无效转换(int,void ,size_t){aka int()(int,void ,unsigned int }'to'sssize_t()(int,const void ,size_t){aka int()(int,const void ,unsigned int)}'[-fpermissive] cthis-&gt; WR = read;
我已经研究了错误并得出结论,这是因为读取和写入函数以某种方式不采用相同的参数,这很奇怪因为我在它们中传递相同的参数(int i2s_file,int buffer,int length)所以如果我将函数指针更改为
ssize_t (*WR)(int, void *, size_t);
该函数适用于读取而不是写入。所以我的问题是:我可以通过更改i2c-dev库以某种方式更改写入或读取函数以获取相同的参数,或者我还能做些什么来解决这个问题?
这是i2c-dev库的链接,我完全放弃了解http://textuploader.com/5yioi
先谢谢
答案 0 :(得分:1)
您可以将函数显式转换为正确的类型:
typedef ssize_t (*I2CCMD)(int, void *, size_t);
cthis->WR = (I2CCMD)write;
cthis->WR = (I2CCMD)read;
这应该可以消除错误。
答案 1 :(得分:0)
显然read
函数无法指向const
,因为与write
函数不同,它必须修改该参数。
因此,您无法使用函数指针切换功能,因为函数指针的类型不同。
最好的解决方案似乎是移动&#34; cmd&#34; i2c_exe
函数的参数,或者创建包含cmd
的私有变量(内部struct I2C
将是理想的)。然后在i2c_exe
中调用read或write。
更糟糕的解决方案是将结构更改为联合,例如:
union I2C {
ssize_t (*WR)(int, const void *, size_t);
ssize_t (*read)(int, void*, size_t);
};
然后在读取的情况下,使用读取成员分配给结构。但是请注意,这是一种肮脏的黑客行为,理论上这是一种指定不当的行为。实际上,它很可能适用于任何给定的系统。 (const正确性不太可能影响调用约定。)