使用函数指针移植通用 C 驱动程序
Porting generic C driver with function pointer
我正在尝试将可用于 IMU 的通用 C 驱动程序移植到基于北欧模块的嵌入式平台。最佳方法是正确修改接口功能以使其适应我的系统。因此 github here 上可用的驱动程序具有用于 write/read 寄存器的此接口:
typedef int32_t (*lsm6dso_write_ptr)(void *, uint8_t, uint8_t*, uint16_t);
typedef int32_t (*lsm6dso_read_ptr) (void *, uint8_t, uint8_t*, uint16_t);
typedef struct {
/** Component mandatory fields **/
lsm6dso_write_ptr write_reg;
lsm6dso_read_ptr read_reg;
/** Customizable optional pointer **/
void *handle;
} lsm6dso_ctx_t;
我的read/write寄存器函数是:
void write_i2c_data(nrf_drv_twi_t const *m_twi, uint8_t reg, uint8_t val)
{
uint8_t cmd[2] = {0, 0};
cmd[0] = reg;
cmd[1] = val;
nrf_drv_twi_tx(m_twi, ADDR, cmd, 2, true);
nrf_delay_ms(1);
}
void read_i2c_data(nrf_drv_twi_t const *m_twi, uint8_t reg, uint8_t *val)
{
nrf_drv_twi_tx(m_twi, ADDR, ®, 1, true);
nrf_delay_ms(1);
nrf_drv_twi_rx(m_twi, ADDR, val, 1);
nrf_delay_ms(1);
}
问题 -
1 - 我不确定如何将 m_twi
驱动程序实例函数传递给 lsm6dso_ctx_t
结构。它说该结构是可定制的,但我不确定如何扩充它。
2 - 函数指针有点让我迷惑 - 我怎样才能将我的函数指向 lsm6dso_write_ptr
指针。我知道需要修改我的函数以提供多字节 read/write,我认为这是可行的。
你应该实现两个功能:
static int32_t your_callback_lsm6dso_read_reg(void *ctx, uint8_t reg, uint8_t* data,
uint16_t len) {
// read from register ret
// len length of data to data pointer
// return 0 on success
// something like: (I have no idea about nrf_* interface)
nrf_drv_twi_t const *m_twi = ctx;
nrf_drv_twi_rx(m_twi, reg, data, len);
return 0;
}
static int32_t your_callback_lsm6dso_write_reg(void *ctx, uint8_t reg, uint8_t* data,
uint16_t len)
// write to register ret len length od data from data pointer
// return 0 on success
// something like: (I have no idea about nrf* interface)
nrf_drv_twi_t const *m_twi = ctx;
nrf_drv_twi_tx(m_twi, reg, data, len);
return 0;
}
然后实例化结构体:
lsm6dso_ctx_t lsm6dso_ctx = { your_callback_lsm6dso_write_reg, your_callback_lsm6dso_read_reg, m_twi };
并像这样使用它:
lsm6dso_some_function_from_the_library(&lsm6dso_ctx, ...)
库中的函数将调用 lsm6dso_ctx
中的函数指针,第一个参数作为结构中的 void*
指针。结构中的 void*
指针用于传递您的自定义数据。然后,您可以将句柄从 void*
指针转换为自定义指针并调用适当的函数。
how can I point my function to the lsm6dso_write_ptr pointer.
我觉得你的困惑就来自于此,反过来说就是了。 lsm6dso_ctx_t
中的函数指针应该指向您的函数。
那么您只有一个 lsm6dso_ctx_t
结构的实例,您可以使用驱动程序的所有函数。驱动程序有一些逻辑,它调用你的函数作为结构传递来执行 input/output 操作。
我正在尝试将可用于 IMU 的通用 C 驱动程序移植到基于北欧模块的嵌入式平台。最佳方法是正确修改接口功能以使其适应我的系统。因此 github here 上可用的驱动程序具有用于 write/read 寄存器的此接口:
typedef int32_t (*lsm6dso_write_ptr)(void *, uint8_t, uint8_t*, uint16_t);
typedef int32_t (*lsm6dso_read_ptr) (void *, uint8_t, uint8_t*, uint16_t);
typedef struct {
/** Component mandatory fields **/
lsm6dso_write_ptr write_reg;
lsm6dso_read_ptr read_reg;
/** Customizable optional pointer **/
void *handle;
} lsm6dso_ctx_t;
我的read/write寄存器函数是:
void write_i2c_data(nrf_drv_twi_t const *m_twi, uint8_t reg, uint8_t val)
{
uint8_t cmd[2] = {0, 0};
cmd[0] = reg;
cmd[1] = val;
nrf_drv_twi_tx(m_twi, ADDR, cmd, 2, true);
nrf_delay_ms(1);
}
void read_i2c_data(nrf_drv_twi_t const *m_twi, uint8_t reg, uint8_t *val)
{
nrf_drv_twi_tx(m_twi, ADDR, ®, 1, true);
nrf_delay_ms(1);
nrf_drv_twi_rx(m_twi, ADDR, val, 1);
nrf_delay_ms(1);
}
问题 -
1 - 我不确定如何将 m_twi
驱动程序实例函数传递给 lsm6dso_ctx_t
结构。它说该结构是可定制的,但我不确定如何扩充它。
2 - 函数指针有点让我迷惑 - 我怎样才能将我的函数指向 lsm6dso_write_ptr
指针。我知道需要修改我的函数以提供多字节 read/write,我认为这是可行的。
你应该实现两个功能:
static int32_t your_callback_lsm6dso_read_reg(void *ctx, uint8_t reg, uint8_t* data,
uint16_t len) {
// read from register ret
// len length of data to data pointer
// return 0 on success
// something like: (I have no idea about nrf_* interface)
nrf_drv_twi_t const *m_twi = ctx;
nrf_drv_twi_rx(m_twi, reg, data, len);
return 0;
}
static int32_t your_callback_lsm6dso_write_reg(void *ctx, uint8_t reg, uint8_t* data,
uint16_t len)
// write to register ret len length od data from data pointer
// return 0 on success
// something like: (I have no idea about nrf* interface)
nrf_drv_twi_t const *m_twi = ctx;
nrf_drv_twi_tx(m_twi, reg, data, len);
return 0;
}
然后实例化结构体:
lsm6dso_ctx_t lsm6dso_ctx = { your_callback_lsm6dso_write_reg, your_callback_lsm6dso_read_reg, m_twi };
并像这样使用它:
lsm6dso_some_function_from_the_library(&lsm6dso_ctx, ...)
库中的函数将调用 lsm6dso_ctx
中的函数指针,第一个参数作为结构中的 void*
指针。结构中的 void*
指针用于传递您的自定义数据。然后,您可以将句柄从 void*
指针转换为自定义指针并调用适当的函数。
how can I point my function to the lsm6dso_write_ptr pointer.
我觉得你的困惑就来自于此,反过来说就是了。 lsm6dso_ctx_t
中的函数指针应该指向您的函数。
那么您只有一个 lsm6dso_ctx_t
结构的实例,您可以使用驱动程序的所有函数。驱动程序有一些逻辑,它调用你的函数作为结构传递来执行 input/output 操作。