I inherited I2C API to PX4 for reading data from magnetometer, but when I compile the project, an error occurs. Here is my code and error message:
class BNO055 : public device::I2C, public I2CSPIDriver<BNO055>
{
public:
BNO055(I2CSPIBusOption bus_option, int bus, int bus_frequency);
virtual ~BNO055();
static I2CSPIDriverBase *instantiate(const BusCLIArguments &cli, const
BusInstanceIterator &iterator,
int runtime_instance);
int init() override;
/**
* Starts polling the sensor
*
* @todo why is this a separate function?
*/
void start();
/**
* The function that polls the sensors and updates their values
*/
void RunImpl();
static void print_usage();
private:
PX4Accelerometer _px4_accel;
PX4Gyroscope _px4_gyro;
PX4Magnetometer _px4_mag;
// most recent data
struct bno055_accel_double_t accel_xyz;
struct bno055_gyro_double_t gyro_xyz;
struct bno055_mag_double_t mag_xyz;
// TODO check (and tweak) those values
// cutoff freqs for the internal low pass filters
const uint8_t ACCEL_BW_REGVAL = BNO055_ACCEL_BW_125HZ;
const uint8_t GYRO_BW_REGVAL = BNO055_GYRO_BW_116HZ;
// update freq for the magnetometer
const uint8_t MAG_RATE_REGVAL = BNO055_MAG_DATA_OUTRATE_30HZ;
// poll at 250 Hz to match other sensors, this should probably be
about 2x the low pass bandwidth
const uint32_t POLLING_INTERVAL_US = uint32_t(1000000 / 250);
// the magnetometer is slower than the other sensors, so don't fetch
it every time
const uint32_t MAG_INTERVAL_US = uint32_t(1000000 / 30);
// save the last time the magnetometer was read
uint32_t mag_last_read = 0;
/**
* Completely resets chip
*
* @note init() must have been called before, and since the chip is
now reset, init() should be called again
*/
int reset();
/**
* Read a register from the BNO055, this is used by the Bosch lib
*
* @param dev_addr this is <b>not used</b>, it is only there because
the library needs it in its signature
* @param reg_addr the (starting) register to read from
* @param reg_data returned data
* @param count amount of bytes to read
* @return 0 on success
*/
static int8_t read_reg(uint8_t dev_addr, uint8_t reg_addr, uint8_t
*reg_data, uint8_t cnt);
/**
* Write a register from the BNO055, this is used by the Bosch lib
*
* @param dev_addr this is <b>not used</b>, it is only there because
the library needs it in its signature
* @param reg_addr the (starting) register to write to
* @param reg_data the data to send
* @param count amount of bytes to send
* @return 0 on success
*/
static int8_t write_reg(uint8_t dev_addr, uint8_t reg_addr, uint8_t
*reg_data, uint8_t cnt);
/** Bosch lib main data struct */
struct bno055_t bno055_struct;
/**
* This exists because the lib needs a pointer to a sleep(ms) function
*
* @param ms sleep time in millis
*
* @todo does this work with Nuttx?
* @todo replace with workqueue sleep
*/
inline static void bno_msleep(uint32_t ms) { usleep(ms * 1000); }
};
in .cpp file:
BNO055::BNO055(I2CSPIBusOption bus_option, int bus, int bus_frequency) :
I2C(DRV_IMU_DEVTYPE_BNO055, MODULE_NAME, bus, BNO055_I2C_ADDR1, bus_frequency),
I2CSPIDriver(MODULE_NAME, px4::device_bus_to_wq(get_device_id()), bus_option, bus),
_px4_accel(get_device_id()),
_px4_gyro(get_device_id()),
_px4_mag(get_device_id())
{
}
and I'm using transfer
function in I2C.
int8_t BNO055::read_reg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t cnt)
{
return transfer(®_addr, 1, reg_data, cnt);
}
the transfer function:
int I2C::transfer(const uint8_t *send, const unsigned send_len, uint8_t *recv, const
unsigned recv_len)
{
int ret = PX4_ERROR;
unsigned retry_count = 0;
.
.
.
Finally, here is the error message:
../../src/drivers/imu/bosch/bno055/bno055.cpp:147:45: error: cannot call member function
'int device::I2C::transfer(const uint8_t*, unsigned int, uint8_t*, unsigned int)' without
object
147 | return transfer(®_addr, 1, reg_data, cnt);
Edit: I'm using these functions as static functions because of this:
bno055_struct.bus_write = &BNO055::write_reg;
bno055_struct.bus_read = &BNO055::read_reg;
struct bno055_t
{
u8 chip_id; /**< chip_id of bno055 */
u16 sw_rev_id; /**< software revision id of bno055 */
u8 page_id; /**< page_id of bno055 */
u8 accel_rev_id; /**< accel revision id of bno055 */
u8 mag_rev_id; /**< mag revision id of bno055 */
u8 gyro_rev_id; /**< gyro revision id of bno055 */
u8 bl_rev_id; /**< boot loader revision id of bno055 */
u8 dev_addr; /**< i2c device address of bno055 */
s8 (*bus_write)(u8, u8, u8 *, u8); /**< bus write function pointer */
s8 (*bus_read)(u8, u8, u8 *, u8); /**<bus read function pointer */
void (*delay_msec)(BNO055_MDELAY_DATA_TYPE); /**< delay function pointer */
};
When I don't use static
, I'm getting this error:
error: cannot convert 'int8_t (BNO055::*)(uint8_t, uint8_t, uint8_t*, uint8_t)' {aka 'signed char (BNO055::*)(unsigned char, unsigned char, unsigned char*, unsigned char)'} to 's8 (*)(u8, u8, u8*, u8)' {aka 'signed char (*)(unsigned char, unsigned char, unsigned char*, unsigned char)'} in assignment
63 | bno055_struct.bus_write = &BNO055::write_reg;
| ^~~~~~~~~